CINXE.COM

Chapter 5. Developing Operators | Red Hat Product Documentation

<!DOCTYPE html><html data-capo=""><head><script type="importmap"> { "imports": { "@patternfly/elements/": "/scripts/v1/@patternfly/elements/", "@patternfly/pfe-clipboard/": "/scripts/v1/@patternfly/pfe-clipboard/", "@rhds/elements/": "/scripts/v1/@rhds/elements/elements/", "@cpelements/elements/": "/scripts/v1/@cpelements/elements/elements/" }, "scopes": { "/": { "@floating-ui/core": "/scripts/v1/@floating-ui/core/dist/floating-ui.core.mjs", "@floating-ui/dom": "/scripts/v1/@floating-ui/dom/dist/floating-ui.dom.mjs", "@floating-ui/utils": "/scripts/v1/@floating-ui/utils/dist/floating-ui.utils.mjs", "@floating-ui/utils/dom": "/scripts/v1/@floating-ui/utils/dom/dist/floating-ui.utils.dom.mjs", "@lit/reactive-element": "/scripts/v1/@lit/reactive-element/reactive-element.js", "@lit/reactive-element/decorators/": "/scripts/v1/@lit/reactive-element/decorators/", "@patternfly/pfe-core": "/scripts/v1/@patternfly/pfe-core/core.js", "@patternfly/pfe-core/": "/scripts/v1/@patternfly/pfe-core/", "@rhds/tokens/media.js": "/scripts/v1/@rhds/tokens/js/media.js", "lit": "/scripts/v1/lit/index.js", "lit-element/lit-element.js": "/scripts/v1/lit-element/lit-element.js", "lit-html": "/scripts/v1/lit-html/lit-html.js", "lit-html/": "/scripts/v1/lit-html/", "lit/": "/scripts/v1/lit/", "tslib": "/scripts/v1/tslib/tslib.es6.mjs", "@cpelements/rh-table/dist/rh-table.js": "/scripts/v1/@cpelements/rh-table/dist/rh-table.js" } } } </script><meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Chapter 5. Developing Operators | Red Hat Product Documentation</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <script type="text/javascript" id="trustarc" src="//static.redhat.com/libs/redhat/marketing/latest/trustarc/trustarc.js"></script> <script src="//www.redhat.com/dtm.js"></script> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Red+Hat+Display:wght@400;500;700&family=Red+Hat+Text:wght@400;500;700&display=swap"> <link rel="stylesheet" href="/styles/rh-table--lightdom.min.css"> <style>.section .titlepage{gap:.75rem}.section .titlepage,div.edit{align-items:center;display:flex}div.edit{font-size:.9rem;margin-bottom:8px}div.edit>a{align-items:center;display:flex}.edit pf-icon{margin-right:4px}</style> <style>#error[data-v-df31ff14]{align-items:center;display:flex;flex-direction:column;justify-content:center;min-height:80vh}h1[data-v-df31ff14]{font-size:calc(var(--rh-font-size-body-text-md, 1rem)*4);font-weight:700;margin-bottom:0}h1[data-v-df31ff14],h1 span[data-v-df31ff14]{line-height:var(--rh-line-height-heading,1.3)}h1 span[data-v-df31ff14]{color:var(--rh-color-text-brand-on-light,#e00);display:block;text-transform:uppercase}h1 span[data-v-df31ff14],p[data-v-df31ff14]{font-size:var(--rh-font-size-body-text-lg,1.125rem)}aside[data-v-df31ff14]{align-items:center;background:var(--rh-color-surface-lightest,#fff);border:var(--rh-border-width-sm,1px) solid var(--rh-color-border-subtle-on-light,#c7c7c7);border-radius:var(--rh-border-radius-default,3px);border-top:calc(var(--rh-border-width-md, 2px)*2) solid var(--rh-color-text-brand-on-light,#e00);box-shadow:var(--rh-box-shadow-sm,0 2px 4px 0 hsla(0,0%,8%,.2));display:flex;flex-direction:column;justify-content:space-between;margin-top:var(--rh-space-2xl,32px);padding:var(--rh-space-xl,24px)}aside[data-v-df31ff14],aside>div[data-v-df31ff14]{width:100%}.text-container[data-v-df31ff14]{margin:auto;max-width:442px;text-align:center}.desktop[data-v-df31ff14]{display:none}.sr-only[data-v-df31ff14]{height:1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0;clip-path:inset(50%);white-space:nowrap}form[data-v-df31ff14]{display:flex}button[data-v-df31ff14],input[data-v-df31ff14]{border:1px solid var(--rh-color-black-500,#8a8d90);box-sizing:border-box;height:40px}input[data-v-df31ff14]{border-right:none;flex:1;font-family:var(--rh-font-family-heading,RedHatDisplay,"Red Hat Display","Noto Sans Arabic","Noto Sans Hebrew","Noto Sans JP","Noto Sans KR","Noto Sans Malayalam","Noto Sans SC","Noto Sans TC","Noto Sans Thai",Helvetica,Arial,sans-serif);font-size:var(--rh-font-size-body-text-md,1rem);padding-left:var(--rh-space-md,8px);width:100%}button[data-v-df31ff14]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border-left:none;display:flex;width:var(--rh-size-icon-04,40px)}button[data-v-df31ff14]:before{background:var(--rh-context-light-color-text-link,#06c);content:"";cursor:pointer;display:block;height:28px;margin:auto;width:28px}.search-icon[data-v-df31ff14]{margin:auto}ul[data-v-df31ff14]{max-width:275px;padding:0}ul li[data-v-df31ff14]{display:inline-block;list-style:none;margin-right:var(--rh-space-xl,24px);padding:var(--rh-space-xs,4px) 0}ul li a[data-v-df31ff14]{color:var(--rh-context-light-color-text-link,#06c);text-decoration:none}@media (min-width:992px){aside[data-v-df31ff14]{flex-direction:row}.mobile[data-v-df31ff14]{display:none}.desktop[data-v-df31ff14]{display:block}input[data-v-df31ff14]{width:auto}}</style> <style>@keyframes fade-in{0%{opacity:0;visibility:hidden}1%{visibility:visible}to{opacity:1;visibility:visible}}@media (min-height:48em){.rhdocs{--rh-table--maxHeight:calc(100vh - 12.5rem)}}*,.rhdocs *,.rhdocs :after,.rhdocs :before,:after,:before{box-sizing:border-box}.rhdocs img,.rhdocs object,.rhdocs svg,img,object,svg{display:inline-block;max-width:100%;vertical-align:middle}.rhdocs hr{border:0;border-top:.0625rem solid #d2d2d2;clear:both;margin:1rem 0}.rhdocs a{color:#06c;text-decoration:underline}.rhdocs a:focus,.rhdocs a:hover{color:#036}.rhdocs a.anchor-heading{color:#151515;cursor:pointer;text-decoration:none;word-break:break-all}.rhdocs p{margin:1.49963rem 0}.rhdocs li>p{margin:0}.rhdocs h1,.rhdocs h2,.rhdocs h3,.rhdocs h4,.rhdocs h5,.rhdocs h6{font-family:RedHatDisplay,Red Hat Display,Helvetica Neue,Arial,sans-serif;font-weight:500;margin:0 0 .625rem}.rhdocs h1{font-size:2.25rem;margin:2rem 0}.rhdocs h2{font-size:1.625rem;margin:2rem 0}.rhdocs h3{font-size:1.5rem;font-weight:400}.rhdocs h4,.rhdocs h5{font-size:1.25rem}.rhdocs h5{font-weight:400}.rhdocs h6{font-size:1.125rem;font-weight:500;line-height:1.6667}.rhdocs ol,.rhdocs ul{margin:1rem 0;padding:0 0 0 1.5rem}.rhdocs ol ::marker,.rhdocs ul ::marker{font:inherit}.rhdocs li{margin:0 0 .5em;padding:0}.rhdocs li>p{margin:.5rem 0}.rhdocs li>ol,.rhdocs li>ul{margin:0}.rhdocs dl dd{margin:.5rem 0 .5rem 1rem}.rhdocs dl dd>p{margin:.5rem 0}.rhdocs .informaltable,.rhdocs .table-contents,.rhdocs .table-wrapper{max-height:var(--rh-table--maxHeight);overflow:auto}.rhdocs table{border:0;font-size:1rem;line-height:1.6667;table-layout:fixed}.rhdocs table caption{color:#585858;margin-bottom:.5rem;margin-top:.5rem;text-align:left}.rhdocs table td,.rhdocs table th{border:0;border-bottom:.0625rem solid #d2d2d2;border-bottom:.0625rem solid var(--pfe-table--Border,#d2d2d2);padding:.5em 1rem}.rhdocs table td.halign-left,.rhdocs table th.halign-left{text-align:left}.rhdocs table td.halign-center,.rhdocs table th.halign-center,table td.halign-center,table th.halign-center{text-align:center}.rhdocs table td.halign-right,.rhdocs table th.halign-right{text-align:right}.rhdocs table td.valign-top,.rhdocs table th.valign-top{vertical-align:top}.rhdocs table td.valign-middle,.rhdocs table th.valign-middle{vertical-align:middle}.rhdocs table td.valign-bottom,.rhdocs table th.valign-bottom{vertical-align:bottom}.rhdocs table thead td,.rhdocs table thead th{background:#f5f5f5;font-weight:600}.rhdocs rh-table table,.rhdocs rh-table.rh-table--expanded-vertically{max-height:-moz-max-content;max-height:max-content}.rhdocs pre.nowrap{overflow:auto;overflow-wrap:normal;white-space:pre;word-break:normal}.rhdocs .codeblock__wrapper pre{background:transparent}.rh-table--full-screen code,.rhdocs .content--md code,.rhdocs .content--sm code,.rhdocs .rh-table--full-screen code{overflow-wrap:normal;word-break:normal}.rhdocs[class] pre code,[class] pre code{background:inherit;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;padding:0}.rhdocs .keycap,.rhdocs kbd{background-color:#eee;background-image:linear-gradient(180deg,#ddd,#eee,#fff);border-radius:.1875rem;box-shadow:0 -.0625rem 0 0 #fff,0 .0625rem 0 .1875rem #aaa;font-family:RedHatMono,Red Hat Mono,Consolas,monospace;font-size:90%;font-weight:400;margin:0 .25rem;padding:.125rem .375rem}.keycap strong,.rhdocs .keycap strong{font-weight:inherit}.rhdocs kbd.keyseq,kbd.keyseq{background:transparent;border:0;box-shadow:none;padding:0}.rhdocs kbd.keyseq kbd,kbd.keyseq kbd{display:inline-block;margin:0 .375rem}.rhdocs kbd.keyseq kbd:first-child,kbd.keyseq kbd:first-child{margin-left:0}.rhdocs b.button{font-size:90%;font-weight:700;padding:.1875rem}.rhdocs b.button:before{content:"["}.rhdocs b.button:after{content:"]"}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}.rhdocs audio,.rhdocs canvas,.rhdocs progress,.rhdocs video{display:inline-block;vertical-align:baseline}.rhdocs audio:not([controls]){display:none;height:0}[hidden],template{display:none}.rhdocs a{background:transparent}.rhdocs a:active,.rhdocs a:hover{outline:0}.rhdocs a.anchor-heading:hover:before{color:#151515;content:"#";margin-left:-1.6rem;position:absolute}.rhdocs a.anchor-heading:focus-visible{color:#151515}@media screen and (max-width:990px){.rhdocs a.anchor-heading:hover:before{font-size:16px;margin-left:-1rem;padding-top:8px}.rhdocs h1 a.anchor-heading:hover:before{padding-top:12px}.rhdocs h4 a.anchor-heading:hover:before,.rhdocs h5 a.anchor-heading:hover:before{padding-top:4px}.rhdocs h6 a.anchor-heading:hover:before{padding-top:2px}}.rhdocs abbr[title]{border-bottom:.0625rem dotted}.rhdocs dfn{font-style:italic}.rhdocs h1{font-size:2em;margin:.67em 0}.rhdocs mark{background:#ff0;color:#000}.rhdocs small{font-size:80%}.rhdocs sub,.rhdocs sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.rhdocs sup{top:-.5em}.rhdocs sub{bottom:-.25em}.rhdocs img{border:0}.rhdocs svg:not(:root){overflow:hidden}.rhdocs figure{margin:1em 2.5rem}.rhdocs hr{box-sizing:content-box;height:0}.rhdocs code,.rhdocs kbd,.rhdocs pre,.rhdocs samp{font-family:monospace,monospace;font-size:1em}.rhdocs button,.rhdocs optgroup,.rhdocs select,.rhdocs textarea,.rhdocsinput{color:inherit;font:inherit;margin:0}.rhdocs button.copy-link-btn{background:none;border:2px solid #fff;font:1px Red Hat Text}.rhdocs button.copy-link-btn:hover{border-bottom:2px solid #06c}.rhdocs button.copy-link-btn .link-icon{padding-bottom:4px}.rhdocs button{overflow:visible}.rhdocs button,.rhdocs select{text-transform:none}.rhdocs button,.rhdocs html input[type=button],.rhdocs input[type=reset],.rhdocs input[type=submit]{-moz-appearance:button;appearance:button;-webkit-appearance:button;cursor:pointer}.rhdocs button[disabled],.rhdocs html input[disabled]{cursor:default}.rhdocs button::-moz-focus-inner,.rhdocs input::-moz-focus-inner{border:0;padding:0}.rhdocs input{line-height:normal}.rhdocs input[type=checkbox],.rhdocs input[type=radio]{box-sizing:border-box;padding:0}.rhdocs input[type=number]::-webkit-inner-spin-button,.rhdocs input[type=number]::-webkit-outer-spin-button{height:auto}.rhdocs input[type=search]{-moz-appearance:textfield;appearance:textfield;-webkit-appearance:textfield;box-sizing:content-box}.rhdocs input[type=search]::-webkit-search-cancel-button,.rhdocs input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.rhdocs fieldset{border:.0625rem solid silver;margin:0 .125rem;padding:.35em .625em .75em}.rhdocs legend{border:0;padding:0}.rhdocs textarea{overflow:auto}.rhdocs optgroup{font-weight:700}.rhdocs table{border-collapse:collapse;border-spacing:0}.rhdocs td,.rhdocs th{padding:0}.rhdocs ._additional-resources[class][class][id]:last-child{margin-top:-2rem}.rhdocs ._additional-resources[class][class]:only-child{grid-column:1/-1}._additional-resources[class][class] .additional-resources__heading,._additional-resources[class][class] .heading,._additional-resources[class][class] h1,._additional-resources[class][class] h2,._additional-resources[class][class] h3,._additional-resources[class][class] h4,._additional-resources[class][class] h5,._additional-resources[class][class] h6,._additional-resources[class][class] p.title{display:block;font-family:RedHatDisplay,Red Hat Display,Helvetica Neue,Arial,sans-serif;font-size:1.125rem;font-weight:700;line-height:1.5rem;margin:0 0 .5rem;padding:0;text-transform:uppercase}._additional-resources[class][class] ul{border:0;list-style:none;margin:0;padding:0;position:relative}.related-topic-content__wrapper ._additional-resources[class][class] ul{display:block}._additional-resources[class][class] ul:after{background-color:#fff;bottom:0;content:"";display:block;height:.125rem;position:absolute;width:100%}._additional-resources[class][class] li{border-bottom:.0625rem solid #d2d2d2;box-sizing:content-box;margin:0;padding:1rem 1.5rem 1rem 0;-moz-column-break-inside:avoid;break-inside:avoid}._additional-resources[class][class] li:only-child{grid-column:1/-1}._additional-resources[class][class] li:last-child{border:0}@media (min-width:1100px){._additional-resources[class][class] li:last-child{border-bottom:.0625rem solid #d2d2d2}}._additional-resources[class][class] li p:only-child{margin:0;padding:0}._additional-resources[class][class] li a{text-decoration:none}._additional-resources[class][class] li a:focus,._additional-resources[class][class] li a:hover{text-decoration:underline}.rhdocs table .admonitionblock>div:nth-child(2),.rhdocs table .caution>div:nth-child(2),.rhdocs table .important>div:nth-child(2),.rhdocs table .note>div:nth-child(2),.rhdocs table .tip>div:nth-child(2),.rhdocs table .warning>div:nth-child(2){margin:.5rem 0}.rhdocs table .admonitionblock>div:nth-child(2)>:first-child,.rhdocs table .caution>div:nth-child(2)>:first-child,.rhdocs table .important>div:nth-child(2)>:first-child,.rhdocs table .note>div:nth-child(2)>:first-child,.rhdocs table .tip>div:nth-child(2)>:first-child,.rhdocs table .warning>div:nth-child(2)>:first-child{margin-top:0}.rhdocs table .admonitionblock>div:nth-child(2)>:last-child,.rhdocs table .caution>div:nth-child(2)>:last-child,.rhdocs table .important>div:nth-child(2)>:last-child,.rhdocs table .note>div:nth-child(2)>:last-child,.rhdocs table .tip>div:nth-child(2)>:last-child,.rhdocs table .warning>div:nth-child(2)>:last-child{margin-bottom:0}.rhdocs .codeblock__wrapper+.codeblock__wrapper,.rhdocs pre+pre,.rhdocs pre[class]+pre[class]{margin-top:2rem}.rhdocs .codeblock__wrapper{background:#f8f8f8;overflow:visible;position:relative;transform:translate(0);z-index:0}.codeblock__wrapper:before{background-repeat:no-repeat;background-size:6.25rem 100%;bottom:var(--scrollbar__height,1px);content:"";display:block;height:7.125rem;max-height:100%;max-height:calc(100% - var(--scrollbar__height, 2px));position:absolute;right:var(--scrollbar__width,6px);top:.0625rem;width:4.0625rem;z-index:1}.rhdocs .codeblock__inner-wrapper,.rhdocs pre{max-height:calc(100vh - 6.25rem)}@media (min-height:48em){.rhdocs .codeblock__inner-wrapper,.rhdocs pre{max-height:calc(100vh - 12.5rem)}}.rhdocs .codeblock__inner-wrapper{display:grid;grid-template-columns:1fr 4.375rem}.rhdocs .codeblock__wrapper--expanded .codeblock__inner-wrapper{max-height:-moz-max-content;max-height:max-content}.codeblock__copy span{display:block;height:0;position:absolute;visibility:hidden;width:0}.codeblock__copy:focus{outline:.0625rem dashed currentcolor}.codeblock__copy svg#icon--copy{height:1rem;width:1rem}.codeblock__expand{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#f0efef;border:0;cursor:pointer;height:1.75rem;left:calc(100% - 2.75rem - var(--scrollbar__width, 0px));position:absolute;text-indent:-9999em;top:3.25rem;width:1.75rem;z-index:2}.codeblock__expand:before{background:#6a6e73;content:"";height:100%;left:0;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3C!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc.--%3E%3Cpath d='M182.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l41.4-41.4v293.4l-41.4-41.3c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0l96-96c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 402.7V109.3l41.4 41.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-96-96z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3C!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc.--%3E%3Cpath d='M182.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l41.4-41.4v293.4l-41.4-41.3c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0l96-96c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 402.7V109.3l41.4 41.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-96-96z'/%3E%3C/svg%3E");-webkit-mask-position:center center;mask-position:center center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:auto 1rem;mask-size:auto 1rem;position:absolute;top:0;width:100%}.codeblock__wrapper--expanded .codeblock__expand{background:#2b9af3}.codeblock__wrapper--expanded .codeblock__expand:before{background:#fff}.codeblock__expand:focus:before,.codeblock__expand:hover:before{background:#06c}.codeblock__wrapper--expanded .codeblock__expand:focus:before,.codeblock__wrapper--expanded .codeblock__expand:hover:before{background:#fff}.codeblock__expand:focus{outline:.0625rem dashed currentcolor}.rhdocs .calloutlist>ol,.rhdocs .colist>ol{counter-reset:colist;list-style:none;margin:1rem 0 2rem;padding:0}.rhdocs .calloutlist>ol>li,.rhdocs .colist>ol>li{counter-increment:colist;font-size:1rem;margin:.5rem 0;padding-left:1.75rem;position:relative}.rhdocs .calloutlist>ol>li .colist-num,.rhdocs .colist>ol>li .colist-num{display:none}.calloutlist>ol>li:before,.colist>ol>li:before{content:counter(colist);left:0;position:absolute;top:.1875rem}.calloutlist dt{clear:left;float:left;margin:0;padding:0 .5rem 0 0}.included-in-guides[class],.included-in-guides[class][id]:last-child{background:#fff;border:.0625rem solid #d2d2d2;border-radius:.1875rem;margin:2em 0 4em;padding:2rem 2rem 1rem}.included-in-guides[class][id]:last-child{margin-top:-2rem}.included-in-guides[class]:only-child{grid-column:1/-1}.included-in-guides[class] .additional-resources__heading,.included-in-guides[class] .heading,.included-in-guides[class] h1,.included-in-guides[class] h2,.included-in-guides[class] h3,.included-in-guides[class] h4,.included-in-guides[class] h5,.included-in-guides[class] h6,.included-in-guides[class] p.title{display:block;font-family:RedHatDisplay,Red Hat Display,Helvetica Neue,Arial,sans-serif;font-size:1.125rem;font-weight:700;line-height:1.5rem;margin:0 0 .5rem;padding:0;text-transform:uppercase}.included-in-guides[class] ul{border:0;list-style:none;margin:0;padding:0;position:relative}.related-topic-content__wrapper .included-in-guides[class] ul{display:block}.included-in-guides[class] ul:after{background-color:#fff;bottom:0;content:"";display:block;height:.125rem;position:absolute;width:100%}.included-in-guides[class] li{border-bottom:.0625rem solid #d2d2d2;box-sizing:content-box;margin:0;padding:1rem 1.5rem 1rem 0;-moz-column-break-inside:avoid;break-inside:avoid}.included-in-guides[class] li:only-child{grid-column:1/-1}.included-in-guides[class] li:last-child{border:0}@media (min-width:1100px){.included-in-guides[class] li:last-child{border-bottom:.0625rem solid #d2d2d2}}.included-in-guides[class] li p:only-child{margin:0;padding:0}.included-in-guides[class] li a{text-decoration:none}.included-in-guides[class] li a:focus,.included-in-guides[class] li a:hover{text-decoration:underline}.menuseq{display:inline-flex;overflow:hidden;text-indent:-9999em}.menuseq .menu,.menuseq .menuitem,.menuseq .submenu{display:block;position:relative;text-indent:0}.menuseq .menu+.menu:before,.menuseq .menu+.menuitem:before,.menuseq .menu+.submenu:before,.menuseq .menuitem+.menu:before,.menuseq .menuitem+.menuitem:before,.menuseq .menuitem+.submenu:before,.menuseq .submenu+.menu:before,.menuseq .submenu+.menuitem:before,.menuseq .submenu+.submenu:before{content:">";display:inline-block;font-weight:700;padding:0 .25em}.related-topic-content__wrapper{margin:2em 0}.related-topic-content__wrapper--for-guide{margin-bottom:-2.5rem;padding-bottom:.0625rem;position:relative;z-index:1}.related-topic-content__wrapper--for-guide:before{background:#f0f0f0;content:"";display:block;height:100%;left:-3rem;position:absolute;right:-4.5rem;top:0;width:auto;z-index:-1}@media (min-width:1100px){.related-topic-content__wrapper--for-guide:before{left:-2.5rem;right:-3.625rem}}.related-topic-content__wrapper--for-guide summary{padding:1em 2em 1em 2.1875rem}@media (min-width:950px){.related-topic-content__inner-wrapper{display:grid;gap:2em;grid-template-columns:repeat(2,minmax(0,1fr))}}.local-render .rhdocs-content{margin:0 auto}.rhdocs cp-documentation{display:block;padding-bottom:2.5rem}.rhdocs cp-documentation.PFElement,.rhdocs cp-documentation[pfelement]{padding:0}rh-table{display:block}::-webkit-scrollbar,:host .rhdocs ::-webkit-scrollbar{height:.625rem;width:.625rem}::-webkit-scrollbar,::-webkit-scrollbar-track,:host .rhdocs ::-webkit-scrollbar,:host .rhdocs ::-webkit-scrollbar-track{background-color:#d6d6d6}::-webkit-scrollbar-thumb,:host .rhdocs ::-webkit-scrollbar-thumb{background-color:#8e8e8e}*,:host .rhdocs *{scrollbar-color:#8e8e8e #d6d6d6}.rhdocs p:empty,p:empty{display:none}.rhdocs[class] h1 code,.rhdocs[class] h2 code,.rhdocs[class] h3 code,.rhdocs[class] h4 code,.rhdocs[class] h5 code,.rhdocs[class] h6 code,[class] h1 code,[class] h2 code,[class] h3 code,[class] h4 code,[class] h5 code,[class] h6 code{background:transparent;border:0;color:inherit;font:inherit;margin:0;padding:0}.pane-page-title h1,.rhdocs__header__primary-wrapper h1{font-family:RedHatDisplay,Red Hat Display,Helvetica Neue,Arial,sans-serif;font-size:2.25rem;line-height:1.333}.rhdocs details[class]{list-style:none;margin:1rem 0 3rem;padding:0}.rhdocs-toc[class]{background:#f2f2f2;margin:1rem 0 2rem;padding:1rem}.rhdocs-toc[class]>:last-child{margin-bottom:0}.rhdocs-toc[class] .rhdocs-toctitle{font-size:1.25rem;font-weight:400;line-height:1.6667;margin-top:0;text-transform:none}.rhdocs-toc[class] li{margin-bottom:.25em;padding-left:.5em}.preamble{margin:0 0 2rem}.sect1{margin:2rem 0 1rem}:host .sect1,cp-documentation .sect1{margin:0 0 2rem;padding:.0625rem 0 0}:host(.cp-documentation--has-external-header) .sect1:first-child>h2:first-child,:host(.cp-documentation--has-external-header) .sect1:first-child>h3:first-child{margin-top:0}.listingblock,.literalblock{margin:1rem 0}.quoteblock,.verseblock{border-left:.25rem solid #d2d2d2;margin:1rem 0;padding:1rem 1rem 1rem 2rem}.quoteblock.pullleft,.verseblock.pullleft{float:left;margin-right:3rem;width:25rem}@media (min-width:768px){.quoteblock.pullleft,.verseblock.pullleft{margin-left:-1rem}}.quoteblock.pullright,.verseblock.pullright{float:right;margin-left:3rem;width:25rem}@media (min-width:768){.quoteblock.pullright,.verseblock.pullright{margin-right:-2rem}}@media (min-width:1100px){.quoteblock.pullright,.verseblock.pullright{margin-right:-10rem}}.quoteblock>:first-child,.verseblock>:first-child{margin-top:0}.quoteblock .content,.verseblock .content{font-family:RedHatText,Red Hat Text,Helvetica Neue,Arial,sans-serif;font-size:1.25rem;line-height:1.6667}.quoteblock .attribution,.verseblock .attribution{font-size:.875rem;font-style:italic;font-weight:600;line-height:1.6667;text-transform:uppercase}.quoteblock .attribution .citetitle,.verseblock .attribution .citetitle{color:#585858}.quoteblock .attribution cite,.verseblock .attribution cite{font-size:1em}.quoteblock blockquote{font-style:italic;margin:0;padding:0}.quoteblock blockquote .content>:first-child{margin-top:0}.quoteblock blockquote .content>:first-child:before{color:#e00;content:"“";display:block;float:left;font-size:2.75rem;font-style:normal;line-height:1.125em;margin-right:.5rem}.quoteblock blockquote .content>:first-child .content>:first-child:before{content:none}.imageblock{margin:1rem 0}.imageblock.pullleft{float:left;margin-right:3rem;width:25rem}@media (min-width:768px){.imageblock.pullleft{margin-left:-1rem}}.imageblock.pullright{float:right;margin-left:3rem;width:25rem}@media (min-width:768){.imageblock.pullright{margin-right:-2rem}}@media (min-width:1100px){.imageblock.pullright{margin-right:-10rem}}.imageblock.interrupter{margin:2rem 0}@media (min-width:768px){.imageblock.interrupter{margin-left:-1rem;margin-right:-2rem}.imageblock.interrupter .caption{margin-left:1rem;margin-right:2rem}}@media (min-width:1100px){.imageblock.interrupter{margin-right:-10rem}.imageblock.interrupter .caption{margin-right:10rem}}.imageblock.interrupter img{max-width:100%}.imageblock .caption{color:#585858;display:block;font-size:.875rem;line-height:1.6667;margin:.5rem 0 0}.rhdocs-footnotes{border-top:.0625rem solid #d2d2d2;margin:3rem 0 1rem;padding:1rem 0 0}.rhdocs-footnotes>ol{margin:0;padding:0 0 0 1.5rem}@supports (counter-reset:footnotenum){.rhdocs-footnotes>ol{counter-reset:footnotenum;list-style:none;padding:0}.rhdocs-footnotes>ol>li{counter-increment:footnotenum}.rhdocs-footnotes>ol>li:before{color:#585858;content:"[" counter(footnotenum) "]";display:inline-block;margin-right:.25rem}}.rhdocs-footer{background:#ededed;color:#151515;font-size:.875rem;line-height:1.6667;margin:3rem 0 0;padding:1rem}.center{margin-left:auto;margin-right:auto}.stretch{width:100%}.visually-hidden{overflow:hidden;position:absolute;clip:rect(0,0,0,0);border:0;height:.0625rem;margin:-.0625rem;padding:0;width:.0625rem}.rh-docs-legal-notice{margin-top:4em}pre,pre[class]{margin:0;padding:1.25em 1em;position:relative}code[class*=language-],pre[class*=language-]{color:#151515;-moz-tab-size:4;-o-tab-size:4;tab-size:4}code.language-none,code.language-text,code.language-txt,pre.language-none,pre.language-text,pre.language-txt{color:#151515}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{background:#cceae7;color:#263238}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{background:#cceae7;color:#263238}:not(pre)>code[class*=language-]{border-radius:.2em;padding:.1em;white-space:normal}.token.atrule{color:#40199a}.token.attr-name{color:#06c}.token.attr-value,.token.attribute{color:#b300b3}.token.boolean{color:#40199a}.token.builtin,.token.cdata,.token.char,.token.class,.token.class-name{color:#06c}.token.comment{color:#6a6e73}.token.constant{color:#40199a}.token.deleted{color:#c9190b}.token.doctype{color:#6a6e73}.token.entity{color:#c9190b}.token.function{color:#40199a}.token.hexcode{color:#b300b3}.token.id,.token.important{color:#40199a;font-weight:700}.token.inserted{color:#06c}.token.keyword{color:#40199a}.token.number{color:#b300b3}.token.operator{color:#06c}.token.prolog{color:#6a6e73}.token.property{color:#06c}.token.pseudo-class,.token.pseudo-element{color:#b300b3}.token.punctuation,.token.regex{color:#06c}.token.selector{color:#c9190b}.token.string{color:#b300b3}.token.symbol{color:#40199a}.token.unit{color:#b300b3}.token.url,.token.variable{color:#c9190b}.rhdocs.local-render{margin:0 auto;max-width:45.8125rem;padding:0 1.5rem}@media print{.field code,.field pre,code[class*=language-],pre,pre[class*=language-]{white-space:pre-wrap!important;word-wrap:break-word!important;overflow-wrap:break-word!important;word-break:break-word!important}}.book-nav__list[class]{display:flex;justify-content:space-between;line-height:var(--jupiter__lineHeight--xs,1.3333);list-style:none;margin:5rem 0 0;padding:0}@media (min-width:1200px){.book-nav__list[class]{display:grid;gap:2rem;grid-template-columns:repeat(2,minmax(0,1fr))}}.book-nav__item a{display:inline-block;font-size:.875rem;font-weight:500;padding-left:1.25rem;position:relative;text-transform:uppercase}.book-nav__item a:before{background:url(/sites/dxp-docs/penumbra-dist/jupiter/images/arrow-down-solid.svg) no-repeat;background-size:contain;content:"";display:block;height:.875rem;left:0;position:absolute;top:.125rem;transform:rotate(90deg);width:.875rem}.book>.titlepage:not(:last-child),.rhdocs .chapter,section[id]{padding-bottom:3.75rem}.book>.titlepage .chapter:last-child,.book>.titlepage section[id]:last-child,.chapter .chapter:last-child,.chapter section[id]:last-child,section[id] .chapter:last-child,section[id] section[id]:last-child{margin-bottom:-3.75rem}.rhdocs .codeblock__wrapper+section[id],pre+section[id]{padding-top:3.75rem}.rhdocs .cta-link{font-size:inherit}.rhdocs a{word-wrap:break-word;overflow-wrap:break-word}.rhdocs .caution,.rhdocs .important,.rhdocs .note,.rhdocs .tip,.rhdocs .warning{padding:.8888888889em;position:relative}.rhdocs .QSIPopOver{bottom:18.75rem!important;top:auto!important}.rhdocs .alert{position:relative}.rhdocs button.dismiss-button{background:none;border:0;cursor:pointer;height:2.5rem;margin-top:-1.25rem;padding:0;position:absolute;right:.3125rem;text-align:center;top:50%;width:2.5rem;z-index:50}.rhdocs button.dismiss-button:after{content:"\f109";display:inline-block;filter:alpha(opacity=30);font-family:rh-web-iconfont;font-size:1.3125rem;font-style:normal;font-variant:normal;font-weight:400;line-height:1;line-height:2.5rem;opacity:.3;text-decoration:inherit;text-rendering:optimizeLegibility;text-transform:none!important;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-smoothing:antialiased}.rhdocs .book>.titlepage,.rhdocs .chapter,.rhdocs section[id]{padding-bottom:var(--rh-space-4xl,64px)}.rhdocs .alert{border:0;border-radius:0}.rhdocs .alert>h2:first-child,.rhdocs .alert>h3:first-child,.rhdocs .alert>h4:first-child,.rhdocs .alert>h5:first-child,.rhdocs .alert>h6:first-child,.rhdocs .alert>p:first-child{margin-top:0!important}.rhdocs .alert>p:last-child{margin-bottom:0!important}.rhdocs .alert-w-icon[class]{padding-left:2.8125rem}.rhdocs .alert-w-icon .alert-icon{float:left;font-size:1.125rem;margin-left:-1.875rem;margin-right:.625rem}.rhdocs .alert-w-icon .alert-icon[class*=" rh-icon-"],.rhdocs .alert-w-icon .alert-icon[class^=rh-icon-]{font-size:2.25rem;line-height:1em;margin-left:-2.5rem;margin-top:-.375rem}.rhdocs .alert-w-icon .alert-icon[class*=" icon-innov-prev"],.rhdocs .alert-w-icon .alert-icon[class^=icon-innov-prev]{font-size:1.3125rem;margin-top:.25rem}.rhdocs .alert-w-icon.alert-plain{background:none;color:#151515;padding-left:5rem}.rhdocs .alert-w-icon.alert-plain .alert-icon{font-size:3rem;margin-left:-4.375rem;margin-right:0}.rhdocs .alert-w-icon.alert-plain.alert-success .alert-icon{color:#3f9c35}.rhdocs .alert-w-icon.alert-plain.alert-info .alert-icon{color:#0088ce}.rhdocs .alert-w-icon.alert-plain.alert-warning .alert-icon{color:#f0ab00}.rhdocs .alert-w-icon.alert-plain.alert-danger .alert-icon{color:#e00}#target_banner .copy-url{float:right;margin-top:0}#target_banner .dropdown-menu{font-size:inherit}.titlepage .svg-img[data*="title_logo.svg"]{margin:1.5rem 0;width:15rem}.para{margin:1.49963rem 0}.para[class]{margin-bottom:1.49963rem}dd{margin-bottom:2.5rem}.rhdocs .card-light,.rhdocs .card-light-gray,.rhdocs .card-light-grey{background:#f0f0f0;border:.0625rem solid #f0f0f0;color:#151515}.rhdocs .card-light-gray.push-bottom:first-child,.rhdocs .card-light-grey.push-bottom:first-child,.rhdocs .card-light.push-bottom:first-child{margin-bottom:3.125rem!important}.rhdocs .card-light a.card-link,.rhdocs .card-light h1,.rhdocs .card-light h2,.rhdocs .card-light h3,.rhdocs .card-light h4,.rhdocs .card-light h5,.rhdocs .card-light h6,.rhdocs .card-light-gray a.card-link,.rhdocs .card-light-gray h1,.rhdocs .card-light-gray h2,.rhdocs .card-light-gray h3,.rhdocs .card-light-gray h4,.rhdocs .card-light-gray h5,.rhdocs .card-light-gray h6,.rhdocs .card-light-grey a.card-link,.rhdocs .card-light-grey h1,.rhdocs .card-light-grey h2,.rhdocs .card-light-grey h3,.rhdocs .card-light-grey h4,.rhdocs .card-light-grey h5,.rhdocs .card-light-grey h6{color:#151515}.rhdocs .card-light-gray.card-active:after,.rhdocs .card-light-grey.card-active:after,.rhdocs .card-light.card-active:after{border-top-color:#f0f0f0}.rhdocs .card-md,.rhdocs .card-narrow{display:block;padding:1.1875rem;white-space:normal;word-wrap:break-word}.rhdocs .card .card-heading.card-heading-sm,.rhdocs .card-sm .card .card-heading{font-size:1.0625em;font-weight:500;line-height:1.5}.rhdocs .card .card-heading.card-heading-flush{margin-bottom:.25rem}.rhdocs .card .card-heading.card-heading-red{color:#d10000}.rhdocs .card>p{margin-top:0}.rhdocs .card>p:last-child{margin-bottom:0}.rhdocs .new-experience{background-color:#e7f1fa;border:.0625rem solid #bee1f4;font-size:1rem;margin:1.5rem;padding:1.5rem;position:relative;z-index:1}@media (min-width:48rem){.new-experience{display:flex}.new-experience--contained{left:50%;position:relative;transform:translateX(-50%);width:calc(100vw - 2.5rem)}}.new-experience__primary-content{flex-grow:1}@media (min-width:48rem){.new-experience__primary-content{margin-right:1.25rem}}.new-experience__title{font-size:inherit;font-weight:inherit;line-height:1.6;margin:0;padding:0}.new-experience__title+a,.new-experience__title+pfe-cta{display:inline-block;margin-top:1.5em}.new-experience__secondary-content{min-width:12.5rem}@media (min-width:48rem){.new-experience__secondary-content{text-align:right}}.example{border-left:.3125rem solid #ccc;margin-bottom:2rem;padding:1rem 0 1rem 1rem}dl.calloutlist[class]{display:grid;gap:1.25em .75em;grid-template-columns:min-content 1fr}dl.calloutlist[class] dt{float:none;margin:0;padding:0}dl.calloutlist[class] dd{margin:0;padding:0}dl.calloutlist[class] dd>:first-child{margin-top:0}dl.calloutlist[class] dd>:last-child{margin-bottom:0}.toast{background-color:#000;background-color:rgba(0,0,0,.9);bottom:.9375rem;box-shadow:0 .125rem .3125rem 0 rgba(0,0,0,.26);color:#fff;left:.9375rem;max-width:32.8125rem;min-width:6.25rem;padding:.9375rem;position:fixed;right:.9375rem;transform:translate3d(0,150%,0);transition:transform .2s cubic-bezier(.465,.183,.153,.946);will-change:transform;z-index:999}.toast.show{transform:translateZ(0)}.toast a{color:#fff;text-decoration:underline}.toast a:focus,.toast a:hover{color:#2b9af3}.toast a.btn{text-decoration:none}.toast .btn.btn-link{color:#fff}.toast .close{color:#fff;opacity:.3;text-decoration:none}.toast .close:focus,.toast .close:hover{color:#fff;opacity:.5}.no-csstransforms3d.csstransitions .toast{transition:all .2s cubic-bezier(.465,.183,.153,.946)}.no-csstransforms3d .toast{opacity:0;visibility:hidden}.no-csstransforms3d .toast.show{opacity:1;visibility:visible}.annotator-outer[class][class]{display:none;flex-direction:column;flex-grow:1;height:auto;margin:0;position:static;width:auto}@media (min-width:1400px){.annotator-outer[class][class]{display:flex}}.annotator-frame[class] *{height:auto}@media (min-width:1400px){.annotator-frame .h-sidebar-iframe[class]{position:static;width:calc(100% + 1.5rem)}}.annotator-toolbar[class][class]{position:static;width:auto}.annotator-toolbar>ul,.annotator-toolbar>ul>li{display:block;height:auto;list-style:none;margin:0;padding:0;width:auto}.annotator-toolbar>ul>li{display:flex;justify-content:flex-end}.annotator-frame[class] .annotator-frame-button--sidebar_toggle,.annotator-outer .annotator-frame-button[class][class],.app-content-wrapper *{font-family:RedHatText,Red Hat Text,Helvetica Neue,Arial,sans-serif!important}.annotator-outer .annotator-frame-button[class][class]{font-size:.9375rem;font-weight:500;height:auto;line-height:1.333;margin-right:1.875rem;padding:.75em 1em;position:static}@media (min-width:1400px){.annotator-outer .annotator-frame-button[class][class]{margin-right:0}}.annotator-outer iframe{flex-grow:1;margin-bottom:1.25rem}@media (min-width:1400px){.annotator-outer iframe{min-height:37.5rem}}.producttitle{color:#000;font-size:1.25rem;text-transform:uppercase}.producttitle .productnumber{color:var(--jupiter__palette__red--50,#e00)}.cp-modal-open,.zoom-open{overflow:hidden}.cp-modal,.cp-video-modal,.zoom-modal{bottom:0;display:none;filter:alpha(opacity=0);left:0;opacity:0;outline:0;overflow:hidden;position:fixed;right:0;top:0;transition:all .2s cubic-bezier(.465,.183,.153,.946);z-index:1040;z-index:1050;-webkit-overflow-scrolling:touch}.rhdocs .in.cp-modal,.rhdocs .in.cp-video-modal,.rhdocs .in.zoom-modal{display:block;filter:alpha(opacity=100);opacity:1;overflow-x:hidden;overflow-y:auto}.rhdocs .cp-modal .close,.rhdocs .cp-video-modal .close,.rhdocs .zoom-modal .close{background-color:#fff;border-radius:50%;color:#1a1a1a;font-size:1.75rem;height:28px;height:1.75rem;line-height:1.75rem;margin-bottom:.375rem;margin-top:0;opacity:.9;position:absolute;right:-.5rem;text-shadow:none;top:0;width:28px;width:1.75rem}.cp-modal .close:after,.cp-video-modal .close:after,.zoom-modal .close:after{line-height:1.75rem}.cp-modal-wrap,.zoom-wrap{margin:.625rem;padding-top:.5rem;position:relative}@media (min-width:48rem){.rhdocs .cp-modal-wrap,.rhdocs .zoom-wrap{margin:2.8125rem auto;width:38.4375rem}}@media (min-width:62rem){.rhdocs .cp-modal-wrap,.rhdocs .zoom-wrap{width:49.8958rem}}@media (min-width:75rem){.rhdocs .cp-modal-wrap,.rhdocs .zoom-wrap{width:60.3125rem}}.rhdocs .cp-modal-body :last-child{margin-bottom:0}.rhdocs .cp-modal-backdrop,.rhdocs .zoom-backdrop{background-color:#000;bottom:0;display:none;filter:alpha(opacity=0);left:0;opacity:0;position:fixed;right:0;top:0;transition:opacity .2s cubic-bezier(.465,.183,.153,.946);z-index:1040}.rhdocs .in.cp-modal-backdrop,.rhdocs .in.zoom-backdrop{display:block;filter:alpha(opacity=80);opacity:.8}.rhdocs .cp-modal-body{background:#fff;padding:1.875rem}.rhdocs .cp-modal[data-cp-modal-video=true] .cp-modal-body,.rhdocs .cp-video-modal .cp-modal-body{padding:0}.rhdocs [data-action=zoom]{position:relative}.rhdocs [data-action=zoom]:after{background:rgba(0,0,0,.4);bottom:0;color:#fff;display:inline-block;font-family:rh-web-iconfont;font-style:normal;font-variant:normal;font-weight:400;line-height:1;padding:.375rem;position:absolute;right:0;text-decoration:inherit;text-decoration:none!important;text-rendering:optimizeLegibility;text-transform:none!important;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-smoothing:antialiased}.rhdocs [data-action=zoom]:focus:after,.rhdocs [data-action=zoom]:hover:after{background:rgba(0,0,0,.9)}.rhdocs .zoom-wrap .zoom-larger{text-align:center}.rhdocs .zoom-wrap .zoom-larger a{color:#fff}.rhdocs .zoom-wrap .zoom-larger a:focus,.rhdocs .zoom-wrap .zoom-larger a:hover{color:#fff;text-decoration:underline}.rhdocs .zoom-wrap .zoom-larger a:after{content:"â¿»";display:inline-block;margin-left:.25rem}.rhdocs .zoom-body{background:#fff;border-radius:.5rem;margin:0 0 1rem;padding:1rem;text-align:center}.rhdocs .zoom-body .video-wrapper{height:0;overflow:hidden;padding-bottom:56.25%;position:relative}.rhdocs .zoom-body .video-wrapper[data-aspect-ratio="4:3"]{padding-bottom:75%}.rhdocs .zoom-body iframe{height:100%;left:0;position:absolute;top:0;width:100%}.rhdocs .para>.title[class],.rhdocs p.title[class]{font-size:1rem;font-style:normal;font-weight:700;line-height:1.6667;margin:1.25rem 0 0;text-transform:none}.rhdocs .para>.title[class]+.content>:first-child,.rhdocs .para>.title[class]+p,.rhdocs p.title[class]+.content>:first-child,.rhdocs p.title[class]+p{margin-top:0}.rhdocs [class] pre .caution,.rhdocs [class] pre .important,.rhdocs [class] pre .note,.rhdocs [class] pre .tip,.rhdocs [class] pre .warning{background:transparent;border:0;color:inherit;font:inherit;margin:0;padding:0}.rhdocs [class] pre .caution:after,.rhdocs [class] pre .important:after,.rhdocs [class] pre .note:after,.rhdocs [class] pre .tip:after,.rhdocs [class] pre .warning:after{content:none}.rhdocs [class] code.email{background-color:transparent;font:inherit;padding:0}.rhdocs [class] .author{margin-bottom:1.5rem}.rhdocs [class] .author .author{margin-bottom:0}.rhdocs table{margin:2rem 0}.rhdocs [class] table{width:auto}.rhdocs table .table-contents table{max-width:100%;overflow:auto}.rhdocs rh-table table{margin:0;max-width:9999em;overflow:visible}.rhdocs td,.rhdocs th{border-left:0;padding:.5em 1rem;transition:background .25s ease-out}.rhdocs td.content--md[class][class],.rhdocs th.content--md[class][class]{min-width:13em}.rhdocs td.content--lg[class][class],.rhdocs th.content--lg[class][class]{min-width:20em}.rhdocs thead th{padding-top:1.5em}.rhdocs caption{color:currentColor;color:var(--pfe-table__caption--Color,currentColor);font-weight:700;margin-bottom:.5rem;margin-top:.5rem;text-align:center}.rhdocs .revhistory table td,.rhdocs .revhistory table th{border-color:transparent}.rhdocs .revhistory table td{padding:.625rem .875rem}.rhdocs .revhistory table.simplelist{margin:0}@media print{#masthead{display:none!important}}.rh-table--is-full-screen #to-top{display:none}.rhdocs{--rh-table--maxHeight:calc(100vh - 6.25rem);color:#151515;font-family:var(--rh-font-family-body-text,RedHatText,"Red Hat Text","Noto Sans Arabic","Noto Sans Hebrew","Noto Sans JP","Noto Sans KR","Noto Sans Malayalam","Noto Sans SC","Noto Sans TC","Noto Sans Thai",Helvetica,Arial,sans-serif);font-size:var(--rh-body-copy-lage,1.125rem);line-height:1.6667;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.rhdocs rh-codeblock::slotted(#content){border-radius:.25rem;padding:var (--rh-space-lg,16px)}.rhdocs rh-codeblock .screen{display:grid;grid-template-columns:1fr 4.375rem}.rhdocs rh-codeblock[class][class][class][class][class]{max-width:99999em}.rhdocs .codeblock__copy span{display:block;height:0;position:absolute;visibility:hidden;width:0}.rhdocs .codeblock__copy:focus{outline:.0625rem dashed currentcolor}.rhdocs .codeblock__copy svg#icon--copy{height:1rem;width:1rem}.rhdocs pre{border:0;max-height:-moz-max-content;max-height:max-content}.rhdocs pre,pre[class]{margin:0;padding:1.25em 1em;position:relative}.rhdocs rh-code-block>div.codeblock__inner-wrapper>pre,.rhdocs rh-code-block>div.codeblock__inner-wrapper>pre[class]{margin:0;padding:0;position:relative}.rhdocs code[class*=language-],pre[class*=language-]{color:#151515;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.rhdocs code.literal{background:#eee;border-radius:.25rem;color:#000;font-size:.875rem;line-height:1.6667;overflow-wrap:break-word;padding:.125em .5em;word-break:break-word}.rhdocs code.literal,.rhdocs kbd,.rhdocs span.keycap{font-family:RedHatMono,Red Hat Mono,Consolas,monospace}.rhdocs kbd,.rhdocs span.keycap{background-color:#eee;background-image:linear-gradient(180deg,#ddd,#eee,#fff);border-radius:.1875rem;box-shadow:0 -.0625rem 0 0 #fff,0 .0625rem 0 .1875rem #aaa;font-size:90%;font-weight:400;margin:0 .25rem;padding:.125rem .375rem}.rhdocs ol,.rhdocs ul{margin:1rem 0;padding:0 0 0 1.5rem}.rhdocs ._additional-resources[class][class],.rhdocs ._additional-resources[class][class][id]:last-child{background:#fff;border:.0625rem solid #d2d2d2;border-radius:.1875rem;margin:2em 0 4em;padding:2rem 2rem 1rem}.rhdocs ._additional-resources[class][class] ul{border:0;list-style:none;margin:0;padding:0;position:relative}.rhdocs ._additional-resources[class][class] li{border-bottom:.0625rem solid #d2d2d2;box-sizing:content-box;margin:0;padding:1rem 1.5rem 1rem 0;-moz-column-break-inside:avoid;break-inside:avoid}.rhdocs ._additional-resources[class][class] li:last-child{border:0}.rhdocs section.section#additional_resource .additional-resources__heading,.rhdocs section.section#additional_resource .heading,.rhdocs section.section#additional_resource h1,.rhdocs section.section#additional_resource h2,.rhdocs section.section#additional_resource h3,.rhdocs section.section#additional_resource h4,.rhdocs section.section#additional_resource h5,.rhdocs section.section#additional_resource h6,.rhdocs section.section#additional_resource p.title{display:block;font-family:RedHatDisplay,Red Hat Display,Helvetica Neue,Arial,sans-serif;font-size:1.125rem;font-weight:700;line-height:1.5rem;margin:0 0 .5rem;padding:0;text-transform:uppercase}.rhdocs section.section:first-of-type{margin-top:var(--rh-space-4xl,64px)}.rhdocs section.section p{margin-bottom:var(--rh-space-lg,16px);margin-top:0;word-wrap:break-word}.rhdocs .section.section h1,.rhdocs .section.section h2,.rhdocs .section.section h3,.rhdocs .section.section h4,.rhdocs .section.section h5,.rhdocs .section.section h6,.rhdocs h1,.rhdocs h2,.rhdocs h3,.rhdocs h4,.rhdocs h5,.rhdocs h6{font-family:RedHatDisplay,Red Hat Display,Helvetica Neue,Arial,sans-serif;font-weight:400;line-height:1.3333}.rhdocs h1:first-of-type,.rhdocs h2:first-of-type,.rhdocs h3:first-of-type,.rhdocs h4:first-of-type,.rhdocs h5:first-of-type,.rhdocs h6:first-of-type{margin-top:0}.rhdocs h1,.rhdocs h2,.rhdocs h3,.rhdocs h4,.rhdocs h5,.rhdocs h6{font-family:RedHatDisplay,Red Hat Display,Helvetica,Arial,sans-serif;font-weight:400;line-height:1.3333}.rhdocs h2,.rhdocs section.section h2{font-size:var(--rh-font-size-heading-md,1.75rem)}.rhdocs h3,.rhdocs section.section h3{font-size:1.5rem;font-weight:400}.rhdocs dl dt{font-weight:600;margin:.5rem 0}.rhdocs dl{display:block;margin-block-end:1em;margin-block-start:1em;margin-inline-end:0;margin-inline-start:0}.rhdocs .para{margin:1.49963rem 0}.rhdocs dl.calloutlist[class] dt{float:none;margin:0;padding:0}.rhdocs dl.calloutlist[class] dd>:last-child{margin-bottom:0}.rhdocs dl.calloutlist[class]{display:grid;gap:1.25em .75em;grid-template-columns:fit-content(40%) 1fr}.rhdocs .calloutlist dt{clear:left;display:flex;flex-wrap:wrap;float:left;margin:0;padding:0 .5rem 0 0}.rhdocs .calloutlist dt a:not(:first-child){padding-left:4px}.rhdocs dl.calloutlist[class] dd{margin:0;padding:0}.rhdocs .callout,.rhdocs .colist>ol>li:before,.rhdocs .conum{background:#06c;border-radius:50%;color:#fff;display:inline-block;font-family:RedHatText,Red Hat Text,Helvetica Neue,Arial,sans-serif;font-size:.75rem;font-style:normal;font-weight:600;height:1.25rem;line-height:1.35rem;padding:0;position:relative;text-align:center;top:-.125em;vertical-align:middle;width:1.25rem}.rhdocs img,.rhdocs object,.rhdocs svg{display:inline-block;max-width:100%;vertical-align:middle}.rhdocs .titlepage .svg-img[data*="title_logo.svg"]{margin:1.5rem 0;width:15rem}.rhdocs[class] .author{margin-bottom:1.5rem}.rhdocs[class] .author .author{margin-bottom:0}.rhdocs .para>.title[class],p.title[class]{font-size:1rem;font-style:normal;font-weight:700;line-height:1.6667;margin:1.25rem 0 0}.rhdocs .example{border-left:.3125rem solid #ccc;margin-bottom:2rem;padding:1rem 0 1rem 1rem}.rhdocs code{background:#eee;color:#000;font-family:RedHatMono,Red Hat Mono,Consolas,monospace;font-size:.875rem;line-height:1.6667;overflow-wrap:break-word;padding:.125em .5em;word-break:break-word}.rhdocs .para[class]{margin-bottom:1.49963rem}.rhdocs[class] code.email{background-color:transparent;font:inherit;padding:0}rh-alert.admonition #description,rh-alert.admonition p{font-size:var(--rh-font-size-body-text-md,1rem)}rh-alert{width:-moz-fit-content;width:fit-content}.rhdocs .producttitle{color:#000;font-size:1.25rem;text-transform:uppercase}.rhdocs dl{margin:1rem 0}.rhdocs dl dt{font-weight:600;margin:.5rem 0}.rhdocs ol ol{list-style:lower-roman}.rhdocs .codeblock--processed pf-clipboard-copy::part(input),.rhdocs .codeblock--processed pf-clipboard-copy::part(span){display:none}.token.tag{color:#c9190b}.calloutlist div.para{margin:0}rh-alert.admonition{margin-bottom:var(--rh-space-lg,1rem)}.guibutton,.guimenu,.guimenuitem{font-weight:700}.guibutton{font-size:90%;padding:.1875rem}.guibutton:before{content:"["}.guibutton:after{content:"]"}.docs-content-container,.rhdocs{--rh-table--maxHeight:calc(100vh - 6.25rem);color:#151515;font-family:RedHatText,Red Hat Text,Helvetica Neue,Arial,sans-serif;font-size:1.125rem;line-height:1.6667;-moz-tab-size:4;-o-tab-size:4;tab-size:4}pre[hidden]{display:none}.codeblock[class][class][class][class][class]{max-width:99999em}.codeblock__wrapper{background:var(--rh-color-surface-lighter,#f2f2f2);margin:1rem 0;overflow:visible;position:relative;transform:translate(0);z-index:0}.codeblock__inner-wrapper:after{content:"";display:block;min-height:.625rem;width:4.375rem}.codeblock__copy{--pfe-clipboard--icon--Color--hover:#06c;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#f0efef;height:1.75rem;left:calc(100% - 2.75rem - var(--scrollbar__width, 0px));padding:.3125rem .375rem;position:absolute;top:1rem;width:1.75rem;z-index:2}.codeblock__inner-wrapper pre{border:0;max-height:-moz-max-content;max-height:max-content}.pfe-clipboard:not([copied]) .pfe-clipboard__text--success,:host(:not([copied])) .pfe-clipboard__text--success{display:none!important}.codeblock[class]{margin:0;overflow:visible;padding-right:0}pre{display:block;font-size:.8125rem;line-height:1.42857;margin:0 0 .625rem;word-break:break-all;word-wrap:break-word;background-color:var(--rh-color-surface-lighter,#f2f2f2);border:.0625rem solid #ccc;border-radius:.25rem;color:#333}.docs-content-container pre,.rhdocs pre{background:var(--rh-color-surface-lighter,#f2f2f2);color:#151515;font-family:RedHatMono,Red Hat Mono,Consolas,monospace;font-size:.875rem;line-height:1.6667;overflow-wrap:normal;white-space:pre;word-break:normal}.rhdocs pre[class]{line-height:1.6667;overflow-x:auto}rh-codeblock pre[class][class]{overflow-x:auto}.pfe-clipboard__text--success{background-color:#ddd;border:1px solid #000;border-radius:2px}*,:after,:before{box-sizing:border-box}:root{--rh-space-xs:4px;--rh-space-sm:6px;--rh-space-md:8px;--rh-space-lg:16px;--rh-space-xl:24px;--rh-space-2xl:32px;--rh-space-3xl:48px;--rh-space-4xl:64px;--rh-space-5xl:80px;--rh-space-6xl:96px;--rh-space-7xl:128px;--rh-font-size-body-text-xs:.75rem;--rh-font-size-body-text-sm:.875rem;--rh-font-size-body-text-md:1rem;--rh-font-size-body-text-lg:1.125rem;--rh-font-size-body-text-xl:1.25rem;--rh-font-size-body-text-2xl:1.5rem;--rh-font-size-heading-xs:1.25rem;--rh-font-size-heading-sm:1.5rem;--rh-font-size-heading-md:1.75rem;--rh-font-size-heading-lg:2.25rem;--rh-font-size-heading-xl:2.5rem;--rh-font-size-heading-2xl:3rem;--pfe-navigation--logo--maxWidth:200px;--pfe-navigation__logo--height:40px;--pfe-navigation--fade-transition-delay:500ms;--pfe-navigation__nav-bar--highlight-color:var(--rh-color-brand-red-on-dark,#e00);--pf-global--icon--FontSize--sm:.75rem}body,html{font-family:Red Hat Text,sans-serif;font-size:var(--rh-font-size-body-text-md,1rem);line-height:var(--rh-line-height-body-text,1.5);margin:0}h1,h2,h3,h4,h5,h6{font-family:Red Hat Display,sans-serif;font-weight:400;line-height:var(--rh-line-height-heading,1.3)}h1{font-size:var(--rh-font-size-heading-2xl,3rem);line-height:62px}h2{font-size:var(--rh-font-size-heading-xl,2.5rem);line-height:48px}h3{font-size:var(--rh-font-size-heading-lg,2.25rem)}h4{font-size:var(--rh-font-size-heading-md,2.25rem)}h5{font-size:var(--rh-font-size-heading-sm,2.25rem)}h6{font-size:var(--rh-font-size-heading-xs,2.25rem)}main{line-height:30px}section{padding-bottom:3rem;padding-top:3rem}img{height:auto;max-width:100%}a{color:var(--rh-color-interactive-blue-darker,#06c);text-decoration:none}a:hover{color:var(--rh-color-interactive-blue-darkest,#004080)}rh-alert.html-container a{text-decoration:underline}.container{padding-left:12px;padding-right:12px}.container,.container-fluid{margin-left:auto;margin-right:auto;width:100%}.container-fluid{padding:12px}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{min-width:1140px}}@media (min-width:1400px){.container{min-width:1320px}}.grid{display:grid;gap:var(--rh-space-xl,24px)}.grid-center{margin:auto}.grid.grid-col-2{grid-template-columns:repeat(2,1fr)}.grid.grid-col-3{grid-template-columns:repeat(3,1fr)}.grid.grid-col-4{grid-template-columns:repeat(4,1fr)}.grid.grid-col-5{grid-template-columns:repeat(5,1fr)}.grid.grid-col-6{grid-template-columns:repeat(6,1fr)}.grid.grid-col-7{grid-template-columns:repeat(7,1fr)}.grid.grid-col-8{grid-template-columns:repeat(8,1fr)}.grid.grid-col-9{grid-template-columns:repeat(9,1fr)}.grid.grid-col-10{grid-template-columns:repeat(10,1fr)}.grid.grid-col-11{grid-template-columns:repeat(11,1fr)}.grid.grid-col-12{grid-template-columns:repeat(12,1fr)}@media (min-width:768px){.grid.grid-col-md-2{grid-template-columns:repeat(2,1fr)}.grid.grid-col-md-3{grid-template-columns:repeat(3,1fr)}.grid.grid-col-md-4{grid-template-columns:repeat(4,1fr)}.grid.grid-col-md-5{grid-template-columns:repeat(5,1fr)}.grid.grid-col-md-6{grid-template-columns:repeat(6,1fr)}.grid.grid-col-md-7{grid-template-columns:repeat(7,1fr)}.grid.grid-col-md-8{grid-template-columns:repeat(8,1fr)}.grid.grid-col-md-9{grid-template-columns:repeat(9,1fr)}.grid.grid-col-md-10{grid-template-columns:repeat(10,1fr)}.grid.grid-col-md-11{grid-template-columns:repeat(11,1fr)}.grid.grid-col-md-12{grid-template-columns:repeat(12,1fr)}}@media (min-width:992px){.grid.grid-col-lg-2{grid-template-columns:repeat(2,1fr)}.grid.grid-col-lg-3{grid-template-columns:repeat(3,1fr)}.grid.grid-col-lg-4{grid-template-columns:repeat(4,1fr)}.grid.grid-col-lg-5{grid-template-columns:repeat(5,1fr)}.grid.grid-col-lg-6{grid-template-columns:repeat(6,1fr)}.grid.grid-col-lg-7{grid-template-columns:repeat(7,1fr)}.grid.grid-col-lg-8{grid-template-columns:repeat(8,1fr)}.grid.grid-col-lg-9{grid-template-columns:repeat(9,1fr)}.grid.grid-col-lg-10{grid-template-columns:repeat(10,1fr)}.grid.grid-col-lg-11{grid-template-columns:repeat(11,1fr)}.grid.grid-col-lg-12{grid-template-columns:repeat(12,1fr)}}.span-1{grid-column:span 1}.span-2{grid-column:span 2}.span-3{grid-column:span 3}.span-4{grid-column:span 4}.span-5{grid-column:span 5}.span-6{grid-column:span 6}.span-7{grid-column:span 7}.span-8{grid-column:span 8}.span-9{grid-column:span 9}.span-10{grid-column:span 10}.span-11{grid-column:span 11}.span-12{grid-column:span 12}@media (min-width:399px){.span-xs-1{grid-column:span 1}.span-xs-2{grid-column:span 2}.span-xs-3{grid-column:span 3}.span-xs-4{grid-column:span 4}.span-xs-5{grid-column:span 5}.span-xs-6{grid-column:span 6}.span-xs-7{grid-column:span 7}.span-xs-8{grid-column:span 8}.span-xs-9{grid-column:span 9}.span-xs-10{grid-column:span 10}.span-xs-11{grid-column:span 11}.span-xs-12{grid-column:span 12}}@media (min-width:768px){.span-md-1{grid-column:span 1}.span-md-2{grid-column:span 2}.span-md-3{grid-column:span 3}.span-md-4{grid-column:span 4}.span-md-5{grid-column:span 5}.span-md-6{grid-column:span 6}.span-md-7{grid-column:span 7}.span-md-8{grid-column:span 8}.span-md-9{grid-column:span 9}.span-md-10{grid-column:span 10}.span-md-11{grid-column:span 11}.span-md-12{grid-column:span 12}}@media (min-width:992px){.span-lg-1{grid-column:span 1}.span-lg-2{grid-column:span 2}.span-lg-3{grid-column:span 3}.span-lg-4{grid-column:span 4}.span-lg-5{grid-column:span 5}.span-lg-6{grid-column:span 6}.span-lg-7{grid-column:span 7}.span-lg-8{grid-column:span 8}.span-lg-9{grid-column:span 9}.span-lg-10{grid-column:span 10}.span-lg-11{grid-column:span 11}.span-lg-12{grid-column:span 12}}@media (min-width:1025px){.span-xl-1{grid-column:span 1}.span-xl-2{grid-column:span 2}.span-xl-3{grid-column:span 3}.span-xl-4{grid-column:span 4}.span-xl-5{grid-column:span 5}.span-xl-6{grid-column:span 6}.span-xl-7{grid-column:span 7}.span-xl-8{grid-column:span 8}.span-xl-9{grid-column:span 9}.span-xl-10{grid-column:span 10}.span-xl-11{grid-column:span 11}.span-xl-12{grid-column:span 12}}@media (min-width:1200px){.span-2xl-1{grid-column:span 1}.span-2xl-2{grid-column:span 2}.span-2xl-3{grid-column:span 3}.span-2xl-4{grid-column:span 4}.span-2xl-5{grid-column:span 5}.span-2xl-6{grid-column:span 6}.span-2xl-7{grid-column:span 7}.span-2xl-8{grid-column:span 8}.span-2xl-9{grid-column:span 9}.span-2xl-10{grid-column:span 10}.span-2xl-11{grid-column:span 11}.span-2xl-12{grid-column:span 12}}.flex{display:flex;flex-direction:column;gap:var(--rh-space-lg,16px)}.flex-row{flex-direction:row}.flex-column{flex-direction:column}@media (min-width:768px){.flex-md-row{flex-direction:row}.flex-md-column{flex-direction:column}}.typography-h1{font-size:var(--rh-font-size-heading-2xl,3rem)}.typography-h2{font-size:var(--rh-font-size-heading-xl,2.5rem)}.typography-h3{font-size:var(--rh-font-size-heading-lg,2.25rem)}.typography-h4{font-size:var(--rh-font-size-heading-md,1.75rem)}.typography-h5{font-size:var(--rh-font-size-heading-sm,1.5rem)}.typography-h6{font-size:var(--rh-font-size-heading-xs,1.25rem)}.content section{padding:0}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{margin:var(--rh-space-lg,16px) 0}.sr-only{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0}.list-unstyled{list-style:none;padding-left:0}.tooltip-content{align-items:center;display:flex;font-family:Red Hat Text;justify-content:center;text-transform:none}.tooltip-content .check-icon{margin-left:var(--rh-space-md,8px)}.doc-image-link{display:inline-block;text-decoration:none}.modal-img{display:block;width:100%}.modal-helper-text{margin-top:.5rem;text-align:center}.modal-helper-text a{color:#000;cursor:pointer}.modal-helper-text a:hover{text-decoration:underline}.modal-helper-text a:after{content:"⿻";margin-left:.25rem}pf-modal.pf-img-modal{--pf-c-modal-box--MaxHeight:90vh;overflow-y:scroll}pf-modal.pf-img-modal::part(close-button){background-color:#fff;border-radius:50%;color:#000;margin-right:-2rem;margin-top:-2rem}pf-modal.pf-img-modal::part(close-button):hover{opacity:.7}h2.truste-title{line-height:normal;margin-top:0}rh-alert p[slot=header]{color:#002952}@media (width < 992px){html:has(nav.mobile-nav .mobile-nav-wrapper){scroll-behavior:smooth;scroll-padding-top:4rem}html:has(nav.mobile-nav .mobile-jump-links){scroll-padding-top:7rem}html:has(nav.mobile-nav.hide-mobile-nav){scroll-padding-top:2rem}}.highlight{background:#fff4cc;color:#000}</style> <style>rh-alert[data-v-84359384]{width:100%}</style> <style>.search-btn[data-v-edc0d12c]{align-items:center;background-color:var(--rh-color-canvas-black,#151515);border:3px solid var(--rh-color-canvas-black,#151515);cursor:pointer;display:flex;flex-direction:column;height:100%;justify-content:center;outline:none;padding:14px var(--rh-space-md,8px)}.search-btn[data-v-edc0d12c]:focus{border-top:3px solid var(--rh-color-accent-brand-on-light,#e00);outline:2px dotted var(--rh-color-white,#fff)}.search-btn .search-icon[data-v-edc0d12c]{height:26px;padding:2px 0 var(--rh-space-xs,4px);width:20px}.search-btn .search-icon[data-v-edc0d12c],.search-icon-helper-text[data-v-edc0d12c]{color:var(--rh-color-white,#fff)}.search-mobile[data-v-edc0d12c]{margin-bottom:var(--rh-space-2xl,32px)}.search-mobile form[data-v-edc0d12c]{display:flex;gap:var(--rh-space-md,8px);margin:auto}.search-box[data-v-edc0d12c]{width:35rem}nav[data-v-edc0d12c]{background-color:#151515;justify-content:space-between;width:100%}a[data-v-edc0d12c],a[data-v-edc0d12c]:visited{color:#fff;display:inline-block;font-size:var(--rh-font-size-body-text-md,1rem)}.skip-link[class][class][data-v-edc0d12c]{font-size:var(--pf-global--FontSize--sm,.875rem);line-height:18px}.skip-link[class][class][data-v-edc0d12c]:focus{border-radius:.21429em;height:auto;left:50%;padding:.42857em .57143em;position:fixed;top:8px;transform:translateX(-50%);width:auto;z-index:99999;clip:auto;background:#fff;background:var(--pfe-navigation__skip-link--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff));color:#06c;color:var(--pfe-navigation__skip-link--Color,var(--pfe-theme--color--link,#06c));text-decoration:none}.visually-hidden[data-v-edc0d12c]{border:1px solid #06c;height:1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);white-space:nowrap}h3[data-v-edc0d12c]{color:#464646;font-family:var(--rh-font-family-heading,"Red Hat Display",Helvetica,Arial,sans-serif);font-size:var(--rh-font-size-body-text-lg,1.125rem)}.language-picker[data-v-edc0d12c]{align-items:center;background-color:#fff;display:flex;flex-direction:column;padding:var(--rh-space-xl,24px);width:100%}.language-picker h3[data-v-edc0d12c]{margin:0;padding:0 1rem 1rem}.language-picker ul[data-v-edc0d12c]{margin:0;padding:0}.language-picker a[data-v-edc0d12c]{color:#06c}.language-picker li[data-v-edc0d12c]{list-style:none}.language-dropdown[data-v-edc0d12c]{background:#fff;box-shadow:0 3px 6px rgba(0,0,0,.098);display:block!important;position:absolute;right:0;width:100%;z-index:104}.pfe-navigation.pfe-navigation--processed>[slot=secondary-links][data-v-edc0d12c]{height:auto;overflow:visible;visibility:visible;width:auto}.upper-navigation[data-v-edc0d12c]{padding:0 var(--rh-space-2xl,32px)}.upper-nav-container[data-v-edc0d12c]{border-bottom:1px solid #404040;margin:0}.upper-nav-hidden[data-v-edc0d12c]:not(:focus):not(:active){clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}.upper-nav-menu[data-v-edc0d12c]{align-items:center;display:flex;justify-content:flex-end;line-height:1.444;list-style:none;margin-bottom:0;margin-top:0;padding-left:0}.upper-nav-menu[data-v-edc0d12c],.upper-nav-menu>li[data-v-edc0d12c]{position:relative}.upper-nav-menu>li:not(:first-child)>a[data-v-edc0d12c]:before,.upper-nav-menu>li:not(:first-child)>button[data-v-edc0d12c]:before{background-color:#404040;content:"";height:40%;left:0;position:absolute;top:30%;width:1px}li[data-v-edc0d12c]{display:list-item;margin:0;padding:0;text-align:-webkit-match-parent}.upper-nav-menu button.upper-nav-links[data-v-edc0d12c]{border:0;border-top:3px solid transparent;cursor:pointer;line-height:1.444}.upper-nav-menu button.upper-nav-links[aria-expanded=true][data-v-edc0d12c]{outline-color:#151515}.upper-nav-menu button.upper-nav-links[aria-expanded=true] .upper-nav-arrow[data-v-edc0d12c]{filter:invert(0) sepia(2%) saturate(21%) hue-rotate(257deg) brightness(108%) contrast(100%);transform:rotate(270deg)}.upper-nav-menu button.upper-nav-links[aria-expanded=true][data-v-edc0d12c]:before{display:none}.upper-nav-menu .upper-nav-links[data-v-edc0d12c]{background-color:var(--pfe-navigation--BackgroundColor,var(--pfe-theme--color--surface--darkest,#151515));border-top:3px solid transparent;color:#fff;display:block;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:var(--rh-font-size-body-text-sm,.875rem);outline:none;padding:12px 12px 14px;text-decoration:none}.upper-nav-menu .upper-nav-links[data-v-edc0d12c]:hover{border-top-color:#b8bbbe}.upper-nav-menu .upper-nav-links[data-v-edc0d12c]:focus-within{outline:1px dashed var(--rh-color-white,#fff);outline-offset:-1px}.upper-nav-menu .upper-nav-links[data-v-edc0d12c]:focus-within:before{display:none}.upper-nav-dropdown-container[data-v-edc0d12c]{background:#fff;box-shadow:0 3px 6px rgba(0,0,0,.098);display:none;padding:5px 30px 24px;position:absolute;right:0;top:100%;width:500px;z-index:105}.upper-nav-dropdown-container>ul[data-v-edc0d12c]{-moz-column-count:2;column-count:2;list-style-type:none;padding:0;width:auto}.upper-nav-dropdown-container>ul li[data-v-edc0d12c]{color:#151515;font-family:var(--rh-font-family-heading,"Red Hat Display",Helvetica,Arial,sans-serif);font-size:var(--rh-font-size-body-text-sm,.875rem);list-style-type:none;margin-bottom:0}.upper-nav-dropdown-container>ul li span[data-v-edc0d12c]{font-weight:var(--rh-font-weight-body-text-medium,500)}.upper-nav-dropdown-container>ul ul[data-v-edc0d12c]{padding-left:0;padding-top:9px}.upper-nav-dropdown-container>ul>li[data-v-edc0d12c]{padding-top:19px;-moz-column-break-inside:avoid;break-inside:avoid}.upper-nav-dropdown-container>ul>li>ul>li[data-v-edc0d12c]{line-height:1.45;padding:4px 0}.upper-nav-menu .upper-nav-arrow[data-v-edc0d12c]{display:inline-block;filter:invert(100%) sepia(8%) saturate(7%) hue-rotate(1turn) brightness(100%) contrast(93%);height:18px;margin-left:5px;transform:rotate(90deg);vertical-align:middle;width:8px}#pfe-navigation__secondary-links .show[data-v-edc0d12c],.upper-navigation .show[data-v-edc0d12c]{display:block}.upper-nav-menu .upper-nav-links[aria-expanded=true][data-v-edc0d12c]:active,.upper-nav-menu .upper-nav-links[aria-expanded=true][data-v-edc0d12c]:focus,.upper-nav-menu .upper-nav-links[aria-expanded=true][data-v-edc0d12c]:hover{background-color:#fff;color:#151515}.upper-nav-menu .upper-nav-links[aria-expanded=true][data-v-edc0d12c]{background-color:#fff;border-top-color:#b8bbbe;color:#000;position:relative;z-index:1}.upper-nav-dropdown-container>ul a[data-v-edc0d12c]{color:var(--rh-color-accent-base-on-light,#06c);font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:14px;text-decoration:none}.pfe-navigation__search[data-v-edc0d12c]{background-color:var(--rh-color-white,#fff)}.pfe-navigation__search form[data-v-edc0d12c]{display:flex;gap:var(--rh-space-md,8px);margin:auto;max-width:992px}pfe-navigation [slot=secondary-links] .buttons[data-v-edc0d12c]{display:flex;flex-wrap:wrap;gap:var(--rh-space-md,8px);margin-top:4px}pfe-navigation [slot=secondary-links] .buttons a[data-v-edc0d12c]{border:1px solid #d2d2d2;border-radius:3px;color:#06c;cursor:pointer;flex-basis:calc(50% - 5px);font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-weight:var(--rh-font-weight-code-regular,400);padding:1em;text-align:center;text-decoration:none}pfe-navigation [slot=secondary-links] .mobile-lang-select[data-v-edc0d12c]{border:1px solid #d2d2d2;border-bottom-color:#3c3f42;cursor:pointer;display:flex;margin:3rem 0;position:relative}pfe-navigation [slot=secondary-links] .mobile-lang-select label[data-v-edc0d12c]{bottom:100%;color:#000;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:14px;font-weight:500;margin-bottom:5px;position:absolute}pfe-navigation [slot=secondary-links] .mobile-lang-select select[data-v-edc0d12c]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-style:none;color:#000;flex-basis:100%;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:16px;line-height:24px;padding:6px 24px 6px 8px}select[data-v-edc0d12c]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none' viewBox='0 0 10 6'%3E%3Cpath fill='%23151515' d='M.678 0h8.644c.596 0 .895.797.497 1.195l-4.372 4.58c-.298.3-.695.3-.993 0L.18 1.196C-.216.797.081 0 .678 0'/%3E%3C/svg%3E");background-position:98% 50%;background-repeat:no-repeat}#inputLabel[data-v-edc0d12c]{align-items:center;display:flex;position:relative}#inputLabel form[data-v-edc0d12c]{width:100%}.input-box[data-v-edc0d12c]{font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:var(--rh-font-size-body-text-md,1rem);height:36px;padding:0 8px;width:100%}.input-box[data-v-edc0d12c]::-moz-placeholder{color:#6a6e73;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:var(--rh-font-size-body-text-md,1rem);font-weight:var(--rh-font-weight-code-regular,400);line-height:24px}.input-box[data-v-edc0d12c]::placeholder{color:#6a6e73;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:var(--rh-font-size-body-text-md,1rem);font-weight:var(--rh-font-weight-code-regular,400);line-height:24px}@media(max-width:960px){.search-box[data-v-edc0d12c]{width:28rem}}@media (max-width:768px){.right-navigation[data-v-edc0d12c],.upper-navigation[data-v-edc0d12c]{display:none}}@media (min-width:767px){.pfe-navigation__search form[data-v-edc0d12c]{padding:var(--rh-space-2xl,32px) 0}}</style> <style>.element-invisible,.sr-only,.visually-hidden{height:1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0;white-space:nowrap}@keyframes reveal-nav{0%{max-height:72px;max-height:var(--pfe-navigation__nav-bar--Height,72px);opacity:0;visibility:hidden}99%{max-height:72px;max-height:var(--pfe-navigation__nav-bar--Height,72px)}to{max-height:9999em;opacity:1;visibility:visible}}@keyframes reveal-nav-parts{0%{max-height:72px;max-height:var(--pfe-navigation__nav-bar--Height,72px);opacity:0;visibility:hidden}1%{visibility:visible}99%{max-height:72px;max-height:var(--pfe-navigation__nav-bar--Height,72px)}to{max-height:9999em;opacity:1;visibility:visible}}@media print{.pfe-navigation__menu,pfe-navigation [slot]{display:none!important}}pfe-navigation{--pfe-broadcasted--text:var(--pfe-theme--color--text,#151515);--pfe-broadcasted--text--muted:var(--pfe-theme--color--text--muted,#6a6e73);--pfe-broadcasted--link:var(--pfe-theme--color--link,#06c);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover,#004080);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus,#004080);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited,#6753ac);--pfe-broadcasted--link-decoration:var(--pfe-theme--link-decoration,none);--pfe-broadcasted--link-decoration--hover:var(--pfe-theme--link-decoration--hover,underline);--pfe-broadcasted--link-decoration--focus:var(--pfe-theme--link-decoration--focus,underline);--pfe-broadcasted--link-decoration--visited:var(--pfe-theme--link-decoration--visited,none)}@supports (display:grid){pfe-navigation{animation:reveal-nav .1618s 4s 1 forwards;max-height:72px;max-height:var(--pfe-navigation__nav-bar--Height,72px)}pfe-navigation>*{animation:reveal-nav-parts .1618s 4s 1 forwards;opacity:0;transition:opacity .1618s ease-in-out;transition:opacity var(--pfe-reveal-duration,.1618s) ease-in-out;visibility:hidden}}pfe-navigation.pfe-navigation--processed,pfe-navigation.pfe-navigation--processed>*{animation:none;opacity:1;visibility:visible}pfe-navigation pfe-primary-detail{display:none}pfe-navigation[pfelement]{display:block}pfe-navigation-dropdown{color:#151515;color:var(--pfe-navigation__dropdown--Color,#151515)}#pfe-navigation[breakpoint=desktop] .hidden-at-desktop[class][class][class],#pfe-navigation[breakpoint=mobile] .hidden-at-mobile[class][class][class],#pfe-navigation[breakpoint=tablet] .hidden-at-tablet[class][class][class],pfe-navigation[breakpoint=desktop] .hidden-at-desktop[class][class][class],pfe-navigation[breakpoint=mobile] .hidden-at-mobile[class][class][class],pfe-navigation[breakpoint=tablet] .hidden-at-tablet[class][class][class]{display:none}#pfe-navigation,#pfe-navigation *,pfe-navigation,pfe-navigation *{box-sizing:border-box}#pfe-navigation [pfelement] .pfe-navigation__log-in-link,pfe-navigation [pfelement] .pfe-navigation__log-in-link{display:none}#pfe-navigation,pfe-navigation{align-items:stretch;background:#151515;background:var(--pfe-navigation__nav-bar--Background,#151515);color:#fff;color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));display:flex;font-family:Red Hat Text,RedHatText,Arial,Helvetica,sans-serif;font-family:var(--pfe-navigation--FontFamily,Red Hat Text,RedHatText,Arial,Helvetica,sans-serif);font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);height:72px;height:var(--pfe-navigation__nav-bar--Height,72px);height:auto;line-height:1.5;margin:0;max-width:9999em;min-height:72px;min-height:var(--pfe-navigation__nav-bar--Height,72px);padding:0 16px;position:relative;z-index:95;z-index:var(--pfe-navigation--ZIndex,var(--pfe-theme--zindex--navigation,95))}@media (min-width:768px){#pfe-navigation,pfe-navigation{flex-wrap:wrap;margin:0;max-width:9999em;padding:0 16px}}@media (min-width:1200px){#pfe-navigation,pfe-navigation{margin:0 auto;padding:0 32px}}#pfe-navigation .pfe-navigation__dropdown,#pfe-navigation pfe-navigation-dropdown,pfe-navigation .pfe-navigation__dropdown,pfe-navigation pfe-navigation-dropdown{display:none}#pfe-navigation>[slot=account],#pfe-navigation>[slot=search],#pfe-navigation>[slot=secondary-links],pfe-navigation>[slot=account],pfe-navigation>[slot=search],pfe-navigation>[slot=secondary-links]{height:0;overflow:hidden;visibility:hidden;width:0}@media (min-width:768px){#pfe-navigation nav.pfe-navigation,pfe-navigation nav.pfe-navigation{align-items:stretch;display:flex;flex-wrap:wrap}}@media (min-width:992px){#pfe-navigation nav.pfe-navigation,pfe-navigation nav.pfe-navigation{flex-wrap:nowrap}}#pfe-navigation .pfe-navigation__logo-wrapper,pfe-navigation .pfe-navigation__logo-wrapper{align-items:center;display:flex;justify-content:flex-start;margin:0;min-width:150px;padding:10px 16px 10px 0}@media (min-width:768px){.pfe-navigation--no-main-menu #pfe-navigation .pfe-navigation__logo-wrapper,.pfe-navigation--no-main-menu pfe-navigation .pfe-navigation__logo-wrapper{margin-right:auto}}.pfe-navigation--collapse-secondary-links .pfe-navigation--no-main-menu #pfe-navigation .pfe-navigation__logo-wrapper,.pfe-navigation--collapse-secondary-links .pfe-navigation--no-main-menu pfe-navigation .pfe-navigation__logo-wrapper{margin-right:0}#pfe-navigation .pfe-navigation__logo-link,pfe-navigation .pfe-navigation__logo-link{border-radius:3px;display:block;margin-left:-8px;outline:0;padding:6px 8px;position:relative}#pfe-navigation .pfe-navigation__logo-link:focus,pfe-navigation .pfe-navigation__logo-link:focus{outline:0}#pfe-navigation .pfe-navigation__logo-link:focus:after,pfe-navigation .pfe-navigation__logo-link:focus:after{border:1px dashed #fff;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation .pfe-navigation__logo-image,pfe-navigation .pfe-navigation__logo-image{display:block;height:auto;width:100%}@media (min-width:576px){#pfe-navigation .pfe-navigation__logo-image,pfe-navigation .pfe-navigation__logo-image{height:40px;height:var(--pfe-navigation__logo--height,40px);width:auto}}@media print{#pfe-navigation .pfe-navigation__logo-image,pfe-navigation .pfe-navigation__logo-image{display:none}}#pfe-navigation .pfe-navigation__logo-image:only-child,pfe-navigation .pfe-navigation__logo-image:only-child{display:block}@media (min-width:576px){#pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--small,pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--small{height:32px;height:var(--pfe-navigation__logo--height,32px)}}@media print{#pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--screen,pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--screen{display:none!important}}@media screen{#pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--print,pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--print{display:none!important}}#pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--screen.pfe-navigation__logo-image--print,pfe-navigation .pfe-navigation__logo-image.pfe-navigation__logo-image--screen.pfe-navigation__logo-image--print{display:inline-block!important}#pfe-navigation .pfe-navigation__fallback-links a,#pfe-navigation .pfe-navigation__log-in-link,#pfe-navigation .pfe-navigation__menu-link,#pfe-navigation .pfe-navigation__secondary-link,pfe-navigation .pfe-navigation__fallback-links a,pfe-navigation .pfe-navigation__log-in-link,pfe-navigation .pfe-navigation__menu-link,pfe-navigation .pfe-navigation__secondary-link{--pfe-icon--color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0 0;border:0;color:#06c;color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));color:#fff;color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));cursor:pointer;display:flex;font-family:inherit;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);justify-content:flex-start;justify-content:center;margin:0;outline:0;padding:8px 24px;position:relative;text-align:center;text-decoration:none;white-space:nowrap;width:100%}@media print{#pfe-navigation .pfe-navigation__fallback-links a,#pfe-navigation .pfe-navigation__log-in-link,#pfe-navigation .pfe-navigation__menu-link,#pfe-navigation .pfe-navigation__secondary-link,pfe-navigation .pfe-navigation__fallback-links a,pfe-navigation .pfe-navigation__log-in-link,pfe-navigation .pfe-navigation__menu-link,pfe-navigation .pfe-navigation__secondary-link{display:none!important}}@media (min-width:768px){#pfe-navigation .pfe-navigation__fallback-links a,#pfe-navigation .pfe-navigation__log-in-link,#pfe-navigation .pfe-navigation__menu-link,#pfe-navigation .pfe-navigation__secondary-link,pfe-navigation .pfe-navigation__fallback-links a,pfe-navigation .pfe-navigation__log-in-link,pfe-navigation .pfe-navigation__menu-link,pfe-navigation .pfe-navigation__secondary-link{--pfe-icon--color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));color:#fff;color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));display:flex;flex-direction:column;font-size:12px;font-size:var(--pfe-navigation--FontSize--xs,12px);height:72px;height:var(--pfe-navigation__nav-bar--Height,72px);justify-content:flex-end;padding:14px 8px;width:auto}@supports (display:grid){#pfe-navigation .pfe-navigation__fallback-links a,#pfe-navigation .pfe-navigation__log-in-link,#pfe-navigation .pfe-navigation__menu-link,#pfe-navigation .pfe-navigation__secondary-link,pfe-navigation .pfe-navigation__fallback-links a,pfe-navigation .pfe-navigation__log-in-link,pfe-navigation .pfe-navigation__menu-link,pfe-navigation .pfe-navigation__secondary-link{align-items:center;display:grid;grid-template-rows:26px 18px;justify-items:center}}#pfe-navigation .pfe-navigation__fallback-links a[class]:focus,#pfe-navigation .pfe-navigation__fallback-links a[class]:hover,#pfe-navigation .pfe-navigation__log-in-link[class]:focus,#pfe-navigation .pfe-navigation__log-in-link[class]:hover,#pfe-navigation .pfe-navigation__menu-link[class]:focus,#pfe-navigation .pfe-navigation__menu-link[class]:hover,#pfe-navigation .pfe-navigation__secondary-link[class]:focus,#pfe-navigation .pfe-navigation__secondary-link[class]:hover,pfe-navigation .pfe-navigation__fallback-links a[class]:focus,pfe-navigation .pfe-navigation__fallback-links a[class]:hover,pfe-navigation .pfe-navigation__log-in-link[class]:focus,pfe-navigation .pfe-navigation__log-in-link[class]:hover,pfe-navigation .pfe-navigation__menu-link[class]:focus,pfe-navigation .pfe-navigation__menu-link[class]:hover,pfe-navigation .pfe-navigation__secondary-link[class]:focus,pfe-navigation .pfe-navigation__secondary-link[class]:hover{box-shadow:inset 0 4px 0 0 #06c;box-shadow:inset 0 4px 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}}#pfe-navigation .pfe-navigation__fallback-links a:focus,#pfe-navigation .pfe-navigation__fallback-links a:hover,#pfe-navigation .pfe-navigation__log-in-link:focus,#pfe-navigation .pfe-navigation__log-in-link:hover,#pfe-navigation .pfe-navigation__menu-link:focus,#pfe-navigation .pfe-navigation__menu-link:hover,#pfe-navigation .pfe-navigation__secondary-link:focus,#pfe-navigation .pfe-navigation__secondary-link:hover,pfe-navigation .pfe-navigation__fallback-links a:focus,pfe-navigation .pfe-navigation__fallback-links a:hover,pfe-navigation .pfe-navigation__log-in-link:focus,pfe-navigation .pfe-navigation__log-in-link:hover,pfe-navigation .pfe-navigation__menu-link:focus,pfe-navigation .pfe-navigation__menu-link:hover,pfe-navigation .pfe-navigation__secondary-link:focus,pfe-navigation .pfe-navigation__secondary-link:hover{box-shadow:inset 4px 0 0 0 #06c;box-shadow:inset 4px 0 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}@media (min-width:768px){#pfe-navigation .pfe-navigation__fallback-links a:focus,#pfe-navigation .pfe-navigation__fallback-links a:hover,#pfe-navigation .pfe-navigation__log-in-link:focus,#pfe-navigation .pfe-navigation__log-in-link:hover,#pfe-navigation .pfe-navigation__menu-link:focus,#pfe-navigation .pfe-navigation__menu-link:hover,#pfe-navigation .pfe-navigation__secondary-link:focus,#pfe-navigation .pfe-navigation__secondary-link:hover,pfe-navigation .pfe-navigation__fallback-links a:focus,pfe-navigation .pfe-navigation__fallback-links a:hover,pfe-navigation .pfe-navigation__log-in-link:focus,pfe-navigation .pfe-navigation__log-in-link:hover,pfe-navigation .pfe-navigation__menu-link:focus,pfe-navigation .pfe-navigation__menu-link:hover,pfe-navigation .pfe-navigation__secondary-link:focus,pfe-navigation .pfe-navigation__secondary-link:hover{box-shadow:inset 0 4px 0 0 #06c;box-shadow:inset 0 4px 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}}.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__fallback-links a:focus,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__fallback-links a:hover,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__log-in-link:focus,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__log-in-link:hover,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__menu-link:focus,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__menu-link:hover,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__secondary-link:focus,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__secondary-link:hover,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__fallback-links a:focus,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__fallback-links a:hover,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__log-in-link:focus,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__log-in-link:hover,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__menu-link:focus,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__menu-link:hover,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__secondary-link:focus,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__secondary-link:hover{box-shadow:inset 4px 0 0 0 #06c;box-shadow:inset 4px 0 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}#pfe-navigation .pfe-navigation__fallback-links a:focus,#pfe-navigation .pfe-navigation__log-in-link:focus,#pfe-navigation .pfe-navigation__menu-link:focus,#pfe-navigation .pfe-navigation__secondary-link:focus,pfe-navigation .pfe-navigation__fallback-links a:focus,pfe-navigation .pfe-navigation__log-in-link:focus,pfe-navigation .pfe-navigation__menu-link:focus,pfe-navigation .pfe-navigation__secondary-link:focus{outline:0}#pfe-navigation .pfe-navigation__fallback-links a:focus:after,#pfe-navigation .pfe-navigation__log-in-link:focus:after,#pfe-navigation .pfe-navigation__menu-link:focus:after,#pfe-navigation .pfe-navigation__secondary-link:focus:after,pfe-navigation .pfe-navigation__fallback-links a:focus:after,pfe-navigation .pfe-navigation__log-in-link:focus:after,pfe-navigation .pfe-navigation__menu-link:focus:after,pfe-navigation .pfe-navigation__secondary-link:focus:after{border:1px dashed;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation .pfe-navigation__fallback-links a pfe-icon,#pfe-navigation .pfe-navigation__log-in-link pfe-icon,#pfe-navigation .pfe-navigation__menu-link pfe-icon,#pfe-navigation .pfe-navigation__secondary-link pfe-icon,pfe-navigation .pfe-navigation__fallback-links a pfe-icon,pfe-navigation .pfe-navigation__log-in-link pfe-icon,pfe-navigation .pfe-navigation__menu-link pfe-icon,pfe-navigation .pfe-navigation__secondary-link pfe-icon{pointer-events:none}#pfe-navigation .pfe-navigation__fallback-links a .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__fallback-links a>pfe-icon,#pfe-navigation .pfe-navigation__log-in-link .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__log-in-link>pfe-icon,#pfe-navigation .pfe-navigation__menu-link .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__menu-link>pfe-icon,#pfe-navigation .pfe-navigation__secondary-link .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__secondary-link>pfe-icon,pfe-navigation .pfe-navigation__fallback-links a .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__fallback-links a>pfe-icon,pfe-navigation .pfe-navigation__log-in-link .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__log-in-link>pfe-icon,pfe-navigation .pfe-navigation__menu-link .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__menu-link>pfe-icon,pfe-navigation .pfe-navigation__secondary-link .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__secondary-link>pfe-icon{--pfe-icon--size:18px;padding-right:5px}@media (min-width:768px){#pfe-navigation .pfe-navigation__fallback-links a .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__fallback-links a>pfe-icon,#pfe-navigation .pfe-navigation__log-in-link .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__log-in-link>pfe-icon,#pfe-navigation .pfe-navigation__menu-link .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__menu-link>pfe-icon,#pfe-navigation .pfe-navigation__secondary-link .secondary-link__icon-wrapper,#pfe-navigation .pfe-navigation__secondary-link>pfe-icon,pfe-navigation .pfe-navigation__fallback-links a .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__fallback-links a>pfe-icon,pfe-navigation .pfe-navigation__log-in-link .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__log-in-link>pfe-icon,pfe-navigation .pfe-navigation__menu-link .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__menu-link>pfe-icon,pfe-navigation .pfe-navigation__secondary-link .secondary-link__icon-wrapper,pfe-navigation .pfe-navigation__secondary-link>pfe-icon{padding-right:0;padding:2px 0 4px}}.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__fallback-links a .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__fallback-links a>pfe-icon,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__log-in-link .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__log-in-link>pfe-icon,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__menu-link .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__menu-link>pfe-icon,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__secondary-link .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__secondary-link>pfe-icon,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__fallback-links a .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__fallback-links a>pfe-icon,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__log-in-link .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__log-in-link>pfe-icon,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__menu-link .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__menu-link>pfe-icon,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__secondary-link .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__secondary-link>pfe-icon{padding:0 16px 0 0}#pfe-navigation .pfe-navigation__fallback-links a pfe-icon,#pfe-navigation .pfe-navigation__log-in-link pfe-icon,#pfe-navigation .pfe-navigation__menu-link pfe-icon,#pfe-navigation .pfe-navigation__secondary-link pfe-icon,pfe-navigation .pfe-navigation__fallback-links a pfe-icon,pfe-navigation .pfe-navigation__log-in-link pfe-icon,pfe-navigation .pfe-navigation__menu-link pfe-icon,pfe-navigation .pfe-navigation__secondary-link pfe-icon{display:block;height:18px}#pfe-navigation .pfe-navigation__fallback-links a[class],#pfe-navigation .pfe-navigation__fallback-links a[href],#pfe-navigation .pfe-navigation__log-in-link[class],#pfe-navigation .pfe-navigation__log-in-link[href],#pfe-navigation .pfe-navigation__menu-link[class],#pfe-navigation .pfe-navigation__menu-link[href],#pfe-navigation .pfe-navigation__secondary-link[class],#pfe-navigation .pfe-navigation__secondary-link[href],pfe-navigation .pfe-navigation__fallback-links a[class],pfe-navigation .pfe-navigation__fallback-links a[href],pfe-navigation .pfe-navigation__log-in-link[class],pfe-navigation .pfe-navigation__log-in-link[href],pfe-navigation .pfe-navigation__menu-link[class],pfe-navigation .pfe-navigation__menu-link[href],pfe-navigation .pfe-navigation__secondary-link[class],pfe-navigation .pfe-navigation__secondary-link[href]{align-items:center;justify-content:center}#pfe-navigation .pfe-navigation__account-toggle,#pfe-navigation [slot=account]>a[href],pfe-navigation .pfe-navigation__account-toggle,pfe-navigation [slot=account]>a[href]{--pfe-icon--color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0 0;border:0;color:#06c;color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));cursor:pointer;font-family:inherit;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);justify-content:flex-start;margin:0;outline:0;position:relative;text-align:center;text-decoration:none;white-space:nowrap;width:100%;--pfe-icon--color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));color:#fff;color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));display:flex;flex-direction:column;font-size:12px;font-size:var(--pfe-navigation--FontSize--xs,12px);height:72px;height:var(--pfe-navigation__nav-bar--Height,72px);justify-content:flex-end;padding:14px 8px;width:auto}@media print{#pfe-navigation .pfe-navigation__account-toggle,#pfe-navigation [slot=account]>a[href],pfe-navigation .pfe-navigation__account-toggle,pfe-navigation [slot=account]>a[href]{display:none!important}}#pfe-navigation .pfe-navigation__account-toggle:focus,#pfe-navigation .pfe-navigation__account-toggle:hover,#pfe-navigation [slot=account]>a[href]:focus,#pfe-navigation [slot=account]>a[href]:hover,pfe-navigation .pfe-navigation__account-toggle:focus,pfe-navigation .pfe-navigation__account-toggle:hover,pfe-navigation [slot=account]>a[href]:focus,pfe-navigation [slot=account]>a[href]:hover{box-shadow:inset 4px 0 0 0 #06c;box-shadow:inset 4px 0 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}#pfe-navigation .pfe-navigation__account-toggle:focus,#pfe-navigation [slot=account]>a[href]:focus,pfe-navigation .pfe-navigation__account-toggle:focus,pfe-navigation [slot=account]>a[href]:focus{outline:0}#pfe-navigation .pfe-navigation__account-toggle:focus:after,#pfe-navigation [slot=account]>a[href]:focus:after,pfe-navigation .pfe-navigation__account-toggle:focus:after,pfe-navigation [slot=account]>a[href]:focus:after{border:1px dashed;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation .pfe-navigation__account-toggle pfe-icon,#pfe-navigation [slot=account]>a[href] pfe-icon,pfe-navigation .pfe-navigation__account-toggle pfe-icon,pfe-navigation [slot=account]>a[href] pfe-icon{pointer-events:none}@supports (display:grid){#pfe-navigation .pfe-navigation__account-toggle,#pfe-navigation [slot=account]>a[href],pfe-navigation .pfe-navigation__account-toggle,pfe-navigation [slot=account]>a[href]{align-items:center;display:grid;grid-template-rows:26px 18px;justify-items:center}}#pfe-navigation .pfe-navigation__account-toggle[class]:focus,#pfe-navigation .pfe-navigation__account-toggle[class]:hover,#pfe-navigation [slot=account]>a[href][class]:focus,#pfe-navigation [slot=account]>a[href][class]:hover,pfe-navigation .pfe-navigation__account-toggle[class]:focus,pfe-navigation .pfe-navigation__account-toggle[class]:hover,pfe-navigation [slot=account]>a[href][class]:focus,pfe-navigation [slot=account]>a[href][class]:hover{box-shadow:inset 0 4px 0 0 #06c;box-shadow:inset 0 4px 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}@media print{#pfe-navigation .pfe-navigation__account-toggle,#pfe-navigation [slot=account]>a[href],pfe-navigation .pfe-navigation__account-toggle,pfe-navigation [slot=account]>a[href]{display:none}}#pfe-navigation .pfe-navigation__account-toggle pfe-icon,#pfe-navigation [slot=account]>a[href] pfe-icon,pfe-navigation .pfe-navigation__account-toggle pfe-icon,pfe-navigation [slot=account]>a[href] pfe-icon{--pfe-icon--size:18px;padding:2px 0 4px}@media (min-width:768px){#pfe-navigation .pfe-navigation__account-toggle pfe-icon,#pfe-navigation [slot=account]>a[href] pfe-icon,pfe-navigation .pfe-navigation__account-toggle pfe-icon,pfe-navigation [slot=account]>a[href] pfe-icon{padding-right:0}}#pfe-navigation .pfe-navigation__account-toggle:focus,#pfe-navigation .pfe-navigation__account-toggle:hover,#pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true],#pfe-navigation [slot=account]>a[href][href]:focus,#pfe-navigation [slot=account]>a[href][href]:hover,pfe-navigation .pfe-navigation__account-toggle:focus,pfe-navigation .pfe-navigation__account-toggle:hover,pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true],pfe-navigation [slot=account]>a[href][href]:focus,pfe-navigation [slot=account]>a[href][href]:hover{box-shadow:inset 0 4px 0 0 #06c;box-shadow:inset 0 4px 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}#pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true],pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true]{--pfe-icon--color:var(--pfe-navigation__nav-bar--Color--active,var(--pfe-theme--color--text,#151515));background:#fff;background:var(--pfe-navigation__nav-bar--toggle--BackgroundColor--active,var(--pfe-theme--color--surface--lightest,#fff));color:#151515;color:var(--pfe-navigation__nav-bar--Color--active,var(--pfe-theme--color--text,#151515))}#pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true]:focus,pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true]:focus{outline:0}#pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true]:focus:after,pfe-navigation .pfe-navigation__account-toggle[aria-expanded=true]:focus:after{border:1px dashed #151515;border:1px dashed var(--pfe-navigation__nav-bar--Color--active,var(--pfe-theme--color--text,#151515));bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation .pfe-navigation__fallback-links,#pfe-navigation .pfe-navigation__menu,pfe-navigation .pfe-navigation__fallback-links,pfe-navigation .pfe-navigation__menu{font-size:inherit;list-style:none;margin:0;padding:0}@media (min-width:768px){#pfe-navigation .pfe-navigation__fallback-links,#pfe-navigation .pfe-navigation__menu,pfe-navigation .pfe-navigation__fallback-links,pfe-navigation .pfe-navigation__menu{align-items:stretch;display:flex}}#pfe-navigation .pfe-navigation__fallback-links li,#pfe-navigation .pfe-navigation__menu li,pfe-navigation .pfe-navigation__fallback-links li,pfe-navigation .pfe-navigation__menu li{font-size:inherit;margin:0;padding:0}#pfe-navigation .pfe-navigation__fallback-links li:before,#pfe-navigation .pfe-navigation__menu li:before,pfe-navigation .pfe-navigation__fallback-links li:before,pfe-navigation .pfe-navigation__menu li:before{content:none}#pfe-navigation .pfe-navigation__fallback-links,pfe-navigation .pfe-navigation__fallback-links{margin-left:auto}#pfe-navigation .pfe-navigation__menu-link,pfe-navigation .pfe-navigation__menu-link{display:flex;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);white-space:nowrap}#pfe-navigation.pfe-navigation--processed,pfe-navigation.pfe-navigation--processed{display:block;padding:0}#pfe-navigation.pfe-navigation--processed:before,pfe-navigation.pfe-navigation--processed:before{content:none}#pfe-navigation.pfe-navigation--processed>[slot=account],#pfe-navigation.pfe-navigation--processed>[slot=search],#pfe-navigation.pfe-navigation--processed>[slot=secondary-links],pfe-navigation.pfe-navigation--processed>[slot=account],pfe-navigation.pfe-navigation--processed>[slot=search],pfe-navigation.pfe-navigation--processed>[slot=secondary-links]{height:auto;overflow:visible;visibility:visible;width:auto}#pfe-navigation.pfe-navigation--processed pfe-navigation-dropdown,pfe-navigation.pfe-navigation--processed pfe-navigation-dropdown{display:block}#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown,#pfe-navigation.pfe-navigation--processed pfe-navigation-dropdown,#pfe-navigation.pfe-navigation--processed>[slot],pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown,pfe-navigation.pfe-navigation--processed pfe-navigation-dropdown,pfe-navigation.pfe-navigation--processed>[slot]{animation:none;opacity:1}#pfe-navigation.pfe-navigation--processed [slot=secondary-links],pfe-navigation.pfe-navigation--processed [slot=secondary-links]{display:block;height:auto;list-style:none;margin:0 0 8px;padding:0;width:auto}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links],pfe-navigation.pfe-navigation--processed [slot=secondary-links]{margin:0}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links],.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]{margin:0 0 8px}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button{--pfe-icon--color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0 0;border:0;color:#06c;color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));cursor:pointer;display:flex;font-family:inherit;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);justify-content:flex-start;margin:0;outline:0;padding:8px 24px;position:relative;text-align:center;text-decoration:none;white-space:nowrap;width:100%}@media print{#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button{display:none!important}}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button{--pfe-icon--color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));color:#fff;color:var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));display:flex;flex-direction:column;font-size:12px;font-size:var(--pfe-navigation--FontSize--xs,12px);height:72px;height:var(--pfe-navigation__nav-bar--Height,72px);justify-content:flex-end;padding:14px 8px;width:auto}@supports (display:grid){#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button{align-items:center;display:grid;grid-template-rows:26px 18px;justify-items:center}}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[class]:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[class]:hover,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[class]:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[class]:hover,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[class]:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[class]:hover,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[class]:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[class]:hover{box-shadow:inset 0 4px 0 0 #06c;box-shadow:inset 0 4px 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:hover,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:hover,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:hover,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:hover{box-shadow:inset 4px 0 0 0 #06c;box-shadow:inset 4px 0 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:hover,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:hover,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:hover,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:hover{box-shadow:inset 0 4px 0 0 #06c;box-shadow:inset 0 4px 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:hover,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:hover,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:hover,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:hover{box-shadow:inset 4px 0 0 0 #06c;box-shadow:inset 4px 0 0 0 var(--pfe-navigation__nav-bar--highlight-color,var(--pfe-theme--color--ui-accent,#06c))}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus{outline:0}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus:after,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus:after,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus:after,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus:after{border:1px dashed;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a pfe-icon,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button pfe-icon{pointer-events:none}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a .secondary-link__icon-wrapper,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a>pfe-icon,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button .secondary-link__icon-wrapper,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button>pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a .secondary-link__icon-wrapper,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a>pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button .secondary-link__icon-wrapper,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button>pfe-icon{--pfe-icon--size:18px;padding-right:5px}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a .secondary-link__icon-wrapper,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a>pfe-icon,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button .secondary-link__icon-wrapper,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button>pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a .secondary-link__icon-wrapper,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a>pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button .secondary-link__icon-wrapper,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button>pfe-icon{padding-right:0;padding:2px 0 4px}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a>pfe-icon,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button>pfe-icon,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a>pfe-icon,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button .secondary-link__icon-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button>pfe-icon{padding:0 16px 0 0}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a pfe-icon,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a pfe-icon,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button pfe-icon{display:block;height:18px}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus{outline:0}#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus:after,#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus:after,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus:after,pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus:after{border:1px dashed #fff;border:1px dashed var(--pfe-navigation__nav-bar--Color--default,var(--pfe-theme--color--ui-base--text,#fff));bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a:focus,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button:focus{box-shadow:none}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[aria-expanded=true],#pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[aria-expanded=true],pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[aria-expanded=true],pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[aria-expanded=true]{--pfe-icon--color:var(--pfe-navigation__nav-bar--Color--active,var(--pfe-theme--color--text,#151515));background:#fff;background:var(--pfe-navigation__nav-bar--toggle--BackgroundColor--active,var(--pfe-theme--color--surface--lightest,#fff));color:#151515;color:var(--pfe-navigation__nav-bar--Color--active,var(--pfe-theme--color--text,#151515))}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[aria-expanded=true],.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[aria-expanded=true],.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>a[aria-expanded=true],.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links]>button[aria-expanded=true]{background:0 0;box-shadow:none}#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown__wrapper--single-column,pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown__wrapper--single-column{position:relative}#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown__wrapper,pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown__wrapper{display:block}#pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class],pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class]{height:0;transition:height .25s ease-in-out;transition:var(--pfe-navigation--accordion-transition,height .25s ease-in-out)}@media (prefers-reduced-motion){#pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class],pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class]{transition:none}}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class],pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class]{position:absolute;right:0;top:72px;top:var(--pfe-navigation__nav-bar--Height,72px)}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class],.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class]{position:static}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class][aria-hidden=false],pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class][aria-hidden=false]{height:auto}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class][aria-hidden=false],.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed [slot=secondary-links] .pfe-navigation__dropdown-wrapper[class][aria-hidden=false]{height:0}#pfe-navigation.pfe-navigation--processed[breakpoint=mobile] [slot=secondary-links][mobile-slider] .pfe-navigation__dropdown-wrapper,pfe-navigation.pfe-navigation--processed[breakpoint=mobile] [slot=secondary-links][mobile-slider] .pfe-navigation__dropdown-wrapper{left:100vw;left:calc(100vw - 32px);left:calc(100vw - var(--pfe-navigation__mobile-dropdown--PaddingHorizontal,32px));position:absolute;top:0;width:100vw}#pfe-navigation.pfe-navigation--processed[breakpoint=mobile] [slot=secondary-links][mobile-slider] .pfe-navigation__dropdown-wrapper[aria-hidden=false],pfe-navigation.pfe-navigation--processed[breakpoint=mobile] [slot=secondary-links][mobile-slider] .pfe-navigation__dropdown-wrapper[aria-hidden=false]{height:100vh;height:calc(100vh - 72px);height:calc(100vh - var(--pfe-navigation__nav-bar--Height,72px));overflow-y:scroll}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles,#pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown-wrapper,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles,pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown-wrapper{background:#fff;background:var(--pfe-navigation__dropdown--Background,var(--pfe-theme--color--surface--lightest,#fff));padding:0 24px;padding:0 var(--pfe-navigation__dropdown--full-width--spacing--mobile,24px)}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles,#pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown-wrapper,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles,pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown-wrapper{padding:0 64px24px;padding:0 var(--pfe-navigation__dropdown--full-width--spacing--desktop,64px) var(--pfe-navigation__dropdown--full-width--spacing--mobile,24px)}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown-wrapper{padding:0 24px;padding:0 var(--pfe-navigation__dropdown--full-width--spacing--mobile,24px)}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a{border:1px solid transparent;color:#06c;color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));display:inline-block}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a:hover{color:#036;color:var(--pfe-navigation__dropdown--link--Color--hover,#036);text-decoration:underline}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a:focus{border:1px dashed;outline:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level],#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level],#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level],pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level],pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6{margin:32px 0 .75em;margin:var(--pfe-navigation--gutter,32px) 0 .75em;padding:0;-moz-column-break-inside:avoid;break-inside:avoid;color:#464646;color:var(--pfe-navigation__dropdown--headings--Color,#464646);font-family:Red Hat Display,RedHatDisplay,Arial,Helvetica,sans-serif;font-family:var(--pfe-navigation--FontFamilyHeadline,Red Hat Display,RedHatDisplay,Arial,Helvetica,sans-serif);font-size:1.125rem;font-size:var(--pf-global--FontSize--lg,1.125rem);font-weight:500}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level]:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level]:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5:first-child,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level]:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level]:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5:first-child,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6:first-child{margin-top:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a{border:1px solid transparent;color:#464646;color:var(--pfe-navigation__dropdown--headings--Color,#464646);text-decoration:underline}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a:hover{color:#036;color:var(--pfe-navigation__dropdown--link--Color--hover,#036);text-decoration:none}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container .pfe-link-list--header a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container [role=heading][aria-heading-level] a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h2 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h3 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h4 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h5 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container h6 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles .pfe-link-list--header a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles [role=heading][aria-heading-level] a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h2 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h3 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h4 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h5 a:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles h6 a:focus{border:1px dashed;outline:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container li,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles li,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container li,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles li{margin:0 0 16px;-moz-column-break-inside:avoid;break-inside:avoid}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-card,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-card,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container a,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-card,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles a,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-card,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta{-moz-column-break-inside:avoid;break-inside:avoid}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[pfe-priority=primary],#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[priority=primary],#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[pfe-priority=primary],#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[priority=primary],pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[pfe-priority=primary],pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[priority=primary],pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[pfe-priority=primary],pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[priority=primary]{--pfe-cta--BackgroundColor:var(--pfe-navigation__dropdown--pfe-cta--BackgroundColor,#e00);--pfe-cta--BackgroundColor--hover:var(--pfe-navigation__dropdown--pfe-cta--hover--BackgroundColor,#c00);--pfe-theme--ui--border-width:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[pfe-priority=primary]:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[pfe-priority=primary]:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[priority=primary]:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[priority=primary]:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[pfe-priority=primary]:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[pfe-priority=primary]:hover,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[priority=primary]:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[priority=primary]:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[pfe-priority=primary]:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[pfe-priority=primary]:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[priority=primary]:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta[priority=primary]:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[pfe-priority=primary]:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[pfe-priority=primary]:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[priority=primary]:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta[priority=primary]:hover{--pfe-cta--BackgroundColor:var(--pfe-navigation__dropdown--pfe-cta--hover--BackgroundColor,#c00)}pfe-card #pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta,pfe-card #pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta,pfe-card pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container pfe-cta,pfe-card pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles pfe-cta{margin-top:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container li,#pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container ul,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles li,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles ul,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container li,pfe-navigation.pfe-navigation--processed .pfe-navigation-item__tray--container ul,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles li,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--default-styles ul{list-style:none;margin:0;padding:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles,pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles{color:#151515;color:var(--pfe-navigation__dropdown--Color,#151515);-moz-column-count:auto;column-count:auto;display:block;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);gap:0;margin-left:auto;margin-right:auto;max-width:1136px;max-width:var(--pfe-navigation--content-max-width,1136px);padding-bottom:12px;padding-top:12px;width:calc(100% + 32px)}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles,pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles{-moz-column-count:3;column-count:3;display:block;gap:32px;gap:var(--pfe-navigation--gutter,32px);padding-bottom:12px;padding-top:12px}}@media (min-width:1200px){#pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles,pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles{-moz-column-count:auto;column-count:auto;display:flex;flex-wrap:wrap;padding-bottom:32px;padding-top:32px}@supports (display:grid){#pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles,pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles{display:grid;gap:32px;gap:var(--pfe-navigation--gutter,32px);grid-auto-flow:row;grid-template-columns:repeat(4,minmax(0,1fr))}}}.pfe-navigation--collapse-main-menu #pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,.pfe-navigation--collapse-main-menu #pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles,.pfe-navigation--collapse-main-menu pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,.pfe-navigation--collapse-main-menu pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles{-moz-column-count:3;column-count:3;display:block;gap:32px;gap:var(--pfe-navigation--gutter,32px);padding-bottom:12px;padding-top:12px}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles{-moz-column-count:auto;column-count:auto;display:block;gap:0;margin-left:-16px;margin-right:-16px;max-width:1136px;max-width:var(--pfe-navigation--content-max-width,1136px);padding-bottom:12px;padding-top:12px;width:calc(100% + 32px)}.pfe-navigation__menu-item--open #pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,.pfe-navigation__menu-item--open #pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles,.pfe-navigation__menu-item--open pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,.pfe-navigation__menu-item--open pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles{transition-delay:0s;visibility:visible}#pfe-navigation.pfe-navigation--processed .pfe-navigation-grid>*,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles>*,pfe-navigation.pfe-navigation--processed .pfe-navigation-grid>*,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles>*{margin:0 0 18px;-moz-column-break-inside:avoid;break-inside:avoid}@media (min-width:1200px){#pfe-navigation.pfe-navigation--processed .pfe-navigation-grid>*,#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles>*,pfe-navigation.pfe-navigation--processed .pfe-navigation-grid>*,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles>*{margin:0}}.pfe-navigation--collapse-main-menu #pfe-navigation.pfe-navigation--processed .pfe-navigation-grid>*,.pfe-navigation--collapse-main-menu #pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles>*,.pfe-navigation--collapse-main-menu pfe-navigation.pfe-navigation--processed .pfe-navigation-grid>*,.pfe-navigation--collapse-main-menu pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--default-styles>*{margin:0 0 18px}#pfe-navigation.pfe-navigation--processed .pfe-navigation-grid,pfe-navigation.pfe-navigation--processed .pfe-navigation-grid{max-width:100%}#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--1-x,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown--1-x{display:block}#pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown,pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown{background:#fff}#pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher,pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher{margin-left:auto;margin-right:auto;max-width:1136px;max-width:var(--pfe-navigation--content-max-width,1136px);padding:12px 24px;padding:12px var(--pfe-navigation__dropdown--full-width--spacing--mobile,24px)}@media (min-width:1200px){#pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher,pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher{padding:32px 64px;padding:32px var(--pfe-navigation__dropdown--full-width--spacing--desktop,64px)}}.pfe-navigation--collapse-main-menu #pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher,.pfe-navigation--collapse-main-menu pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher{padding:12px 24px;padding:12px var(--pfe-navigation__dropdown--full-width--spacing--mobile,24px)}#pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher .container,pfe-navigation.pfe-navigation--processed .pfe-navigation__site-switcher .pfe-navigation__dropdown site-switcher .container{margin:0;padding:0;width:auto}#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--invisible[class],pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--invisible[class]{padding:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--invisible pfe-navigation-dropdown,pfe-navigation.pfe-navigation--processed .pfe-navigation__dropdown-wrapper--invisible pfe-navigation-dropdown{visibility:hidden}#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class],pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class]{padding:0}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class],pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class]{box-shadow:0 1px 2px rgba(0,0,0,.12);box-shadow:var(--pfe-navigation__dropdown--BoxShadow,0 1px 2px rgba(0,0,0,.12));max-width:100%;min-width:13em;padding:0 32px;position:absolute;top:100%}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class],.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class]{box-shadow:none;max-width:100%;position:static}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class],pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--single-column[class]{right:0}}#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class],pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class]{width:100%}@media (min-width:768px){#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class],pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class]{left:0;position:absolute;right:0}}.pfe-navigation--collapse-secondary-links #pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class],.pfe-navigation--collapse-secondary-links pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class]{position:static}#pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class] .pfe-navigation__dropdown,pfe-navigation.pfe-navigation--processed .pfe-navigation__custom-dropdown--full[class] .pfe-navigation__dropdown{width:100%}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles{padding-left:16px;padding-right:16px}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles form,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles form{align-items:center;display:flex}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button,#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input{padding:10px;transition:box-shadow .2s}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input{border:1px solid #f0f0f0;border-bottom-color:#8b8e91;color:#717579;flex-basis:0%;flex-grow:1;flex-shrink:1;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);margin-right:8px}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input::-moz-placeholder,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input::-moz-placeholder{color:#717579}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input::placeholder,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input::placeholder{color:#717579}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button{background-color:#e00;border:1px solid #e00;border-radius:2px;color:#fff;flex-basis:auto;flex-grow:0;flex-shrink:1;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem)}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:hover{outline:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:focus:after,#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:hover:after,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:focus:after,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles input:hover:after{border:1px dashed #000;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:focus,#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:hover,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:focus,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:hover{outline:0}#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:focus:after,#pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:hover:after,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:focus:after,pfe-navigation.pfe-navigation--processed .pfe-navigation__search--default-styles button:hover:after{border:1px dashed #fff;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation .pfe-navigation__site-switcher__back-wrapper,pfe-navigation .pfe-navigation__site-switcher__back-wrapper{border-bottom:1px solid #d2d2d2;border-bottom:var(--pfe-navigation__dropdown--separator--Border,1px solid var(--pfe-theme--color--ui--border--lighter,#d2d2d2));display:block}@media (min-width:768px){#pfe-navigation .pfe-navigation__site-switcher__back-wrapper,pfe-navigation .pfe-navigation__site-switcher__back-wrapper{display:none}}.pfe-navigation--collapse-secondary-links #pfe-navigation .pfe-navigation__site-switcher__back-wrapper,.pfe-navigation--collapse-secondary-links pfe-navigation .pfe-navigation__site-switcher__back-wrapper{display:block}#pfe-navigation .pfe-navigation__site-switcher__back-button,pfe-navigation .pfe-navigation__site-switcher__back-button{background-color:transparent;border:1px solid transparent;color:#06c;color:var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));cursor:pointer;font-size:1rem;font-size:var(--pf-global--FontSize--md,1rem);padding:21px 21px 21px 45px;position:relative;text-align:left;width:100%}#pfe-navigation .pfe-navigation__site-switcher__back-button:before,pfe-navigation .pfe-navigation__site-switcher__back-button:before{border:2px solid #06c;border:2px solid var(--pfe-navigation__dropdown--link--Color,var(--pfe-theme--color--link,#06c));border-right:0;border-top:0;content:"";display:block;height:8px;left:35px;position:absolute;right:auto;top:27px;transform:rotate(45deg);transform-origin:left top;width:8px}#pfe-navigation .pfe-navigation__site-switcher__back-button:focus,#pfe-navigation .pfe-navigation__site-switcher__back-button:hover,pfe-navigation .pfe-navigation__site-switcher__back-button:focus,pfe-navigation .pfe-navigation__site-switcher__back-button:hover{border:1px dashed #151515;border-top:1px dashed #151515;border:1px dashed var(--pfe-navigation__dropdown--Color,#151515);color:#036;color:var(--pfe-navigation__dropdown--link--Color--hover,#036);outline:0}#pfe-navigation.pfe-navigation--processed site-switcher,pfe-navigation.pfe-navigation--processed site-switcher{-moz-columns:auto;columns:auto;display:block}#pfe-navigation.pfe-navigation--stuck,pfe-navigation.pfe-navigation--stuck{left:0;position:fixed;top:0;width:100%;z-index:95;z-index:var(--pfe-theme--zindex--navigation,95)}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__outer-menu-wrapper__inner,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__outer-menu-wrapper__inner{opacity:1!important}#pfe-navigation.pfe-navigation--in-crusty-browser pfe-navigation-account,#pfe-navigation.pfe-navigation--in-crusty-browser rh-account-dropdown,pfe-navigation.pfe-navigation--in-crusty-browser pfe-navigation-account,pfe-navigation.pfe-navigation--in-crusty-browser rh-account-dropdown{display:none!important}#pfe-navigation.pfe-navigation--in-crusty-browser[open-toggle=pfe-navigation__account-toggle] pfe-navigation-account,#pfe-navigation.pfe-navigation--in-crusty-browser[open-toggle=pfe-navigation__account-toggle] rh-account-dropdown,pfe-navigation.pfe-navigation--in-crusty-browser[open-toggle=pfe-navigation__account-toggle] pfe-navigation-account,pfe-navigation.pfe-navigation--in-crusty-browser[open-toggle=pfe-navigation__account-toggle] rh-account-dropdown{display:block!important}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-item,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-item{display:block}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-link[aria-expanded=true],pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-link[aria-expanded=true]{--pfe-icon--color:var(--pfe-navigation__nav-bar--Color--active,var(--pfe-theme--color--text,#151515));background:#fff;background:var(--pfe-navigation__nav-bar--toggle--BackgroundColor--active,var(--pfe-theme--color--surface--lightest,#fff));color:#151515;color:var(--pfe-navigation__nav-bar--Color--active,var(--pfe-theme--color--text,#151515))}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-link[aria-expanded=true]:focus,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-link[aria-expanded=true]:focus{outline:0}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-link[aria-expanded=true]:focus:after,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__menu-link[aria-expanded=true]:focus:after{border:1px dashed;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown{display:flex;flex-wrap:wrap}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown>.style-scope,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown>.style-scope{flex-basis:25%}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown .pfe-navigation__footer.style-scope,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown .pfe-navigation__footer.style-scope{flex-basis:100%}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown .pfe-navigation__footer.style-scope>.style-scope,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown .pfe-navigation__footer.style-scope>.style-scope{margin-right:16px}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column,#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column ul,#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column>.style-scope,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column ul,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column>.style-scope{display:flex;flex-direction:column;flex-wrap:nowrap}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column>.style-scope,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__dropdown--single-column>.style-scope{flex-basis:auto}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle,#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link,#pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link,pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a{color:#fff!important;justify-content:center!important}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle[aria-expanded=true],#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link[aria-expanded=true],#pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a[aria-expanded=true],pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle[aria-expanded=true],pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link[aria-expanded=true],pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a[aria-expanded=true]{color:#151515!important}#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__account-wrapper--logged-in .pfe-navigation__log-in-link,#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle .secondary-link__icon-wrapper,#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle pfe-icon,#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link .secondary-link__icon-wrapper,#pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link pfe-icon,#pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a .secondary-link__icon-wrapper,#pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a pfe-icon,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__account-wrapper--logged-in .pfe-navigation__log-in-link,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle .secondary-link__icon-wrapper,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__search-toggle pfe-icon,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link .secondary-link__icon-wrapper,pfe-navigation.pfe-navigation--in-crusty-browser .pfe-navigation__secondary-link pfe-icon,pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a .secondary-link__icon-wrapper,pfe-navigation.pfe-navigation--in-crusty-browser [slot=secondary-links]>a pfe-icon{display:none!important}[id=pfe-navigation__account-dropdown][class][class]{display:block;height:auto;left:0;padding:0;position:absolute;top:72px;top:var(--pfe-navigation__nav-bar--Height,72px);width:100%}[id=pfe-navigation__account-dropdown].pfe-navigation__dropdown-wrapper--invisible[class]{display:none}.pfe-navigation__dropdown-wrapper{overflow:hidden}@media (min-width:768px){.pfe-navigation__custom-dropdown--single-column{min-width:25em}}.pfe-navigation--collapse-secondary-links .pfe-navigation__custom-dropdown--single-column{min-width:0}.secondary-link__icon-wrapper{align-items:center;display:flex;justify-content:center}.secondary-link__alert-count{background:#06c;background:var(--pfe-navigation__nav-bar--alert-color,var(--pfe-theme--color--link,#06c));border-radius:20px;color:#fff;color:var(--pfe-navigation__nav-bar--Color--on-highlight,var(--pfe-theme--color--text--on-saturated,#fff));display:block;font-size:12px;font-size:var(--pfe-navigation--FontSize--xs,12px);line-height:20px;margin:0 4px 0 2px;min-width:23px;overflow:hidden;padding:0 8px}.secondary-link__alert-count:empty{display:none}#pfe-navigation__1x-skip-links{left:0;position:absolute;top:0}#pfe-navigation__1x-skip-links,#pfe-navigation__1x-skip-links li{height:0;list-style:none;margin:0;padding:0;width:0}.skip-link[class][class]{font-size:.875rem;font-size:var(--pf-global--FontSize--sm,.875rem);line-height:18px}.skip-link[class][class]:focus{border-radius:.21429em;height:auto;left:50%;padding:.42857em .57143em;position:fixed;top:8px;transform:translateX(-50%);width:auto;z-index:99999;clip:auto;background:#fff;background:var(--pfe-navigation__skip-link--BackgroundColor,var(--pfe-theme--color--surface--lightest,#fff));color:#06c;color:var(--pfe-navigation__skip-link--Color,var(--pfe-theme--color--link,#06c));text-decoration:none}pfe-navigation pfe-navigation-account[slot=account]{background:#fff;background:var(--pfe-navigation__dropdown--Background,var(--pfe-theme--color--surface--lightest,#fff));width:100%}</style> <style>:host([size=sm]) #container[data-v-8589d091]{--_size:var(--pf-global--icon--FontSize--sm,12px)}.content-wrapper[data-v-8589d091]{height:auto;margin:0 auto;min-height:46vh}.content[data-v-8589d091]{max-width:1000px}#left-content[data-v-8589d091]{max-width:330px;z-index:1}.line-below-chp[data-v-8589d091]{margin:var(--rh-space-xl,24px) 0 var(--rh-space-3xl,48px)}.toc-container[data-v-8589d091]{border-right:1px solid var(--rh-color-gray-30,#c7c7c7);min-height:100vh;position:sticky;top:0;transition:transform .3s ease-in-out}nav#toc[data-v-8589d091]{height:auto;overflow-y:auto;padding-bottom:var(--rh-space-2xl,32px)}.max-height-85[data-v-8589d091]{max-height:85vh}.max-height-75[data-v-8589d091]{max-height:75vh}.toc-filter[data-v-8589d091]{background-color:#fff;padding:var(--rh-space-lg,16px) var(--rh-space-2xl,32px);position:sticky;top:-1px;width:100%;z-index:1}#text[data-v-8589d091],.toc-filter[data-v-8589d091]{align-items:center;display:flex}#text[data-v-8589d091]{flex:1;flex-direction:row}#search-icon[data-v-8589d091]{color:#151515;left:2.5rem;position:absolute;top:55%;transform:translateY(-50%)}pf-icon[data-v-8589d091]{--pf-icon--size:16px}#text:focus-within #icon[data-v-8589d091],#text:hover #icon[data-v-8589d091]{color:#151515}#text[data-v-8589d091]:after,#text[data-v-8589d091]:before{content:"";inset:0;pointer-events:none;position:absolute}#text-input[data-v-8589d091]:focus,#text-input:focus+#utilities[data-v-8589d091]{border-bottom:2px solid #06c;outline:none}#text-input[data-v-8589d091]{background-color:transparent;border:1px solid #f0f0f0;border-bottom-color:#8a8d90;color:#151515;font-family:inherit;font-size:100%;grid-area:text-input;line-height:1.5;overflow:hidden;padding:.375rem .25rem .375rem 2rem;position:relative;text-overflow:ellipsis;white-space:nowrap;width:100%}#utilities[data-v-8589d091]{align-items:center;border:1px solid #f0f0f0;border-bottom:1px solid #8a8d90;border-left:0;display:flex}#utilities rh-badge[data-v-8589d091]{border-radius:80px;font-weight:var(--rh-font-weight-heading-medium,500);--_background-color:#e0e0e0;margin-right:8px}#clear-button[data-v-8589d091]{--pf-c-button--PaddingTop:0.625rem;--pf-c-button--PaddingRight:.25rem;--pf-c-button--PaddingBottom:0.625rem;--pf-c-button--PaddingLeft:.25rem;margin-right:8px}#text-input.no-right-border[data-v-8589d091]{border-right:0}.btn-container[data-v-8589d091]{bottom:0;display:flex;justify-content:flex-end;padding:1rem;pointer-events:none;position:fixed;right:0;z-index:2}.top-scroll-btn[data-v-8589d091]{--pf-c-button--BorderRadius:64px;pointer-events:all}.focusable[data-v-8589d091]:focus-visible{border:2px solid var(--rh-color-interactive-blue,#06c)}.mobile-nav-wrapper[data-v-8589d091]{align-items:center;border-bottom:1px solid #c7c7c7;display:flex;height:auto;justify-content:space-between;padding:var(--rh-space-sm,.5rem)}.mobile-nav[data-v-8589d091]{align-items:center;background-color:var(--rh-color-bg-page,#fff);min-height:51px;position:sticky;top:0;z-index:5}.active-mobile-menu[data-v-8589d091]{color:#151515;padding-left:.5rem}.hidden[data-v-8589d091]{display:none}.mobile-nav-btn[data-v-8589d091]{background-color:transparent;border:none;font-family:inherit;font-size:.875rem;font-weight:500;margin:0;min-height:40px;min-width:40px}.border-right[data-v-8589d091]{border-right:1px solid #c7c7c7}.toc-focus-container[data-v-8589d091]{position:sticky;top:0;z-index:2}.toc-focus-btn[data-v-8589d091]{align-items:center;background-color:var(--rh-color-white,#fff);border:1px solid var(--rh-color-blue-50,#06c);border-radius:50%;cursor:pointer;display:flex;height:40px;justify-content:center;position:absolute;right:-20px;top:15px;width:40px}.toc-focus-btn[data-v-8589d091]:focus-visible,.toc-focus-btn[data-v-8589d091]:hover{background-color:var(--rh-color-blue-10,#e0f0ff);box-shadow:var(--rh-box-shadow-sm,0 2px 4px 0 hsla(0,0%,8%,.2))}.toc-focus-btn[data-v-8589d091]:focus-visible{border:2px solid var(--rh-color-blue-50,#06c)}.toc-focus-btn-icon[data-v-8589d091]{color:var(--rh-color-blue-50,#06c)}.toc-wrapper[data-v-8589d091]{padding:0}.product-container[data-v-8589d091]{border-bottom:1px solid var(--rh-color-gray-30,#c7c7c7);padding:var(--rh-space-xl,24px) var(--rh-space-2xl,32px)}.product-container h1.product-title[data-v-8589d091]{font-size:var(--rh-font-size-code-xl,1.25rem);line-height:30px;margin-bottom:0;margin-top:0}.product-container .product-version[data-v-8589d091]{align-items:center;display:flex;flex-wrap:wrap;margin-top:var(--rh-space-lg,16px)}.product-version .version-label[data-v-8589d091]{color:var(--rh-color-canvas-black,#151515);font-family:Red Hat Text;font-size:var(--rh-font-size-body-text-sm,.875rem);font-weight:500}.product-version .version-select-dropdown[data-v-8589d091]{margin:var(--rh-space-md,8px) var(--rh-space-sm,6px);max-width:9.75rem;min-height:2rem;min-width:3rem;overflow:hidden;width:-moz-min-content;width:min-content;word-wrap:nowrap;-webkit-appearance:none;-moz-appearance:none;background:var(--rh-color-white,#fff);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none' viewBox='0 0 10 6'%3E%3Cpath fill='%23151515' d='M.678 0h8.644c.596 0 .895.797.497 1.195l-4.372 4.58c-.298.3-.695.3-.993 0L.18 1.196C-.216.797.081 0 .678 0'/%3E%3C/svg%3E");background-position-x:85%;background-position-y:50%;background-repeat:no-repeat;border:1px solid var(--rh-color-gray-30,#c7c7c7);border-bottom:0;box-shadow:0 -1px 0 0 var(--rh-color-gray-60,#4d4d4d) inset;cursor:pointer;font-size:var(--rh-font-size-body-text-md,1rem);padding:var(--rh-space-md,8px);padding-right:24px;text-overflow:ellipsis}pf-popover[data-v-8589d091]{margin-top:var(--rh-space-md,8px);--pf-c-popover__arrow--BackgroundColor:var(--rh-color-canvas-black,#151515);--pf-c-popover__content--BackgroundColor:var(--rh-color-canvas-black,#151515);--pf-c-popover--BoxShadow:0px 4px 8px 0px #15151540;--pf-c-popover__title-text--Color:var(--rh-color-white,#fff);--pf-c-popover--MaxWidth:300px;--pf-c-popover--MinWidth:300px;--pf-c-popover--c-button--Top:20px;--pf-c-popover--c-button--Right:4px;--pf-c-button--m-plain--hover--Color:var(--rh-color-white,#fff)}pf-popover[data-v-8589d091]::part(content){padding:var(--rh-space-2xl,32px)}pf-popover[data-v-8589d091]::part(body){margin-top:var(--rh-space-lg,16px)}pf-popover[data-v-8589d091]::part(close-button){--pf-c-button--m-plain--focus--Color:var(--rh-color-gray-30,#c7c7c7);--pf-c-button--m-plain--Color:var(--rh-color-gray-30,#c7c7c7)}.popover-header-text[data-v-8589d091]{color:var(--rh-color-white,#fff);font-size:var(--rh-font-size-code-md,1rem);margin:0;max-width:80%;padding:0}.popover-body-link[data-v-8589d091]{color:var(--rh-color-blue-30,#92c5f9);text-decoration:none}.popover-trigger-btn[data-v-8589d091]{align-items:center;background:none;border:none;cursor:pointer;display:flex;justify-content:center}#first-button[data-v-8589d091]{width:80%}#second-button[data-v-8589d091]{text-align:right;width:20%}#toc-btn[data-v-8589d091]{text-align:left;width:100%}.toc-error[data-v-8589d091]{margin:0;max-width:100%}#layout label[data-v-8589d091]{font-weight:500}.page-layout-options[data-v-8589d091]{background-color:#fff;display:flex;flex-direction:column;padding-bottom:var(--rh-space-lg,16px)}.sticky-top[data-v-8589d091]{position:sticky;top:0}summary[data-v-8589d091]{cursor:pointer;list-style:none;position:relative}summary[data-v-8589d091]::-webkit-details-marker{display:none}details#jump-links-details .jump-links-heading[data-v-8589d091]{background-color:var(--rh-color-white,#fff);display:block;margin-top:var(--rh-space-lg,16px);padding:var(--rh-space-lg,16px) 0 0 var(--rh-space-xl,24px);position:sticky;top:0}details#jump-links-details .jump-links-heading[data-v-8589d091]:before{border-right:3px solid #151515;border-top:3px solid #151515;color:#151515;content:"";display:flex;height:9px;left:2px;position:absolute;top:26px;transform:rotate(-135deg);width:9px}details#jump-links-details[open] .jump-links-heading[data-v-8589d091]:before{transform:rotate(135deg)}.table-of-contents>ol[data-v-8589d091]{list-style:none;margin:0;padding:0}nav.table-of-contents[data-v-8589d091]{z-index:1}nav.table-of-contents ol[data-v-8589d091]{list-style:none;margin:0;padding:0}#mobile-browse-docs[data-v-8589d091]{font-weight:var(--rh-font-weight-body-text-medium,500);padding-left:var(--rh-space-2xl,32px)}.docs-content-container[data-v-8589d091]{font-size:var(--rh-font-size-body-text-lg,1.125rem);font-weight:var(--rh-font-weight-body-text-regular,400);line-height:1.6667;padding-left:6rem;padding-right:6rem;padding-top:var(--rh-space-3xl,4rem)}.chapter-title[data-v-8589d091]{font-family:Red Hat Display}h1.chapter-title[data-v-8589d091]{font-size:var(--rh-fontsize-heading-xl,2.25rem);line-height:46.8px;margin:0;padding:0}.chapter .section h4[data-v-8589d091]{font-size:24px;font-weight:400}.banner-wrapper[data-v-8589d091]{padding:3rem 6rem 0}.page-format-dropdown[data-v-8589d091]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#fff;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAGCAYAAAD68A/GAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABtSURBVHgBhc4xCoAwDAXQxE6li0K76w0cPZqjHsEb6AlcHb2BR9ADdG7GmIKTWv0QSOAFPjrndgAo4TtHxszTD4JoVAhh1VoXiNgkUO+971Q8iGgxxlSy1jc3CGof39baWTrzNSOkkksEbG/oBGEJIn6gD3jAAAAAAElFTkSuQmCC");background-position:8.5rem;background-repeat:no-repeat;background-size:auto;border:1px solid #c7c7c7;box-shadow:inset 0 -1px 0 0 #4d4d4d;font-family:Red Hat Text;font-size:var(--rh-font-size-body-text-md,1rem);margin-top:var(--rh-space-xs,4px);max-width:168px;min-height:36px;min-width:168px;overflow:hidden;padding:0 var(--rh-space-xl,24px) 0 var(--rh-space-md,8px);text-overflow:ellipsis;white-space:nowrap}.content-format-selectors[data-v-8589d091]{color:#151515;font-family:Red Hat Text;font-size:var(--rh-font-size-body-text-sm,.875rem);font-weight:var(--rh-font-weight-body-text-medium,500);margin-right:var(--rh-space-2xl,32px);max-width:250px;min-width:250px;padding-top:var(--rh-space-2xl,32px)}.chapter .section .simpara[data-v-8589d091],.chapter .section p[data-v-8589d091]{font-family:Red Hat Text;font-size:var(--rh-font-size-body-text-lg,1.125rem);font-weight:var(--rh-font-weight-body-text-regular,400);line-height:30px}#toggle-focus-mode[data-v-8589d091]{padding-right:var(--rh-space-lg,1rem)}@keyframes slideaway-left-8589d091{0%{display:block}to{opacity:0;transform:translateX(-40px)}}@keyframes slideaway-right-8589d091{0%{display:block}to{opacity:0;transform:translateX(40px)}}@keyframes enter-left-8589d091{0%{display:none;transform:translateX(-40px)}to{opacity:1}}@keyframes enter-right-8589d091{0%{display:none;transform:translateX(40px)}to{opacity:1}}.hide-left[data-v-8589d091]{animation:slideaway-left-8589d091 .2s;display:none}.enter-left[data-v-8589d091]{animation:enter-left-8589d091 .3s;border-right:none;display:block}.enter-right[data-v-8589d091]{animation:enter-right-8589d091 .3s;display:block}.hide-right[data-v-8589d091]{animation:slideaway-right-8589d091 .2s;display:none}.toc-container.enter-toc-container-left[data-v-8589d091]{transform:translateX(-85%)}.alert-section[data-v-8589d091]{padding-bottom:3rem}rh-alert[data-v-8589d091]{width:auto}@media (min-width:992px){#mobile-nav[data-v-8589d091],#toc-list-mobile[data-v-8589d091]{display:none}}@media (min-width:992px) and (max-width:1400px){.docs-ocp-content-container[data-v-8589d091]{padding:var(--rh-space-4xl,64px) var(--rh-space-lg,16px) 0}}@media (width < 992px){#breadcrumbs[data-v-8589d091],.content-format-selectors[data-v-8589d091],.toc-container[data-v-8589d091]{display:none}#mobile-nav-content-wrapper[data-v-8589d091]{border-bottom:1px solid #c7c7c7;border-top:1px solid #c7c7c7}#toc-wrapper-mobile[data-v-8589d091]{padding:var(--rh-space-md,1.5rem)}.product-container[data-v-8589d091]{padding:var(--rh-space-2xl,32px) var(--rh-space-lg,16px)}.product-container.shrink-product-padding[data-v-8589d091]{padding:var(--rh-space-lg,16px)}.product-version .version-select-dropdown[data-v-8589d091]{margin:0 var(--rh-space-lg,16px)}#page-content-options-mobile[data-v-8589d091]{padding:var(--rh-space-lg,2rem)}label[for=page-format][data-v-8589d091],label[for=toggle-focus-mode][data-v-8589d091]{display:block}.page-format-dropdown[data-v-8589d091]{background-position:97%;max-width:100%}nav#mobile-toc-menu[data-v-8589d091]{max-height:50vh;overflow-y:scroll}.mobile-jump-links #first-button[data-v-8589d091]{width:100%}#jump-links-btn[data-v-8589d091]{text-align:left;width:100%}#mobile-jump-links-content-wrapper[data-v-8589d091]{border-bottom:1px solid #c7c7c7;border-top:1px solid #c7c7c7;padding:0 var(--rh-space-lg,16px) var(--rh-space-2xl,32px)}.table-of-contents #browse-docs[data-v-8589d091]{margin-top:1rem;padding-top:var(--rh-space-md,1.5rem)}.mobile-nav[data-v-8589d091]{display:block}.hide-mobile-nav[data-v-8589d091],.mobile-nav[data-v-8589d091]{transition:transform .3s ease-in-out}.hide-mobile-nav[data-v-8589d091]{transform:translateY(-100%)}.docs-content-container[data-v-8589d091]{padding-left:1.25rem;padding-right:1.25rem;padding-top:var(--rh-space-xl,24px)}.banner-wrapper[data-v-8589d091]{padding:0 1rem}.toc-filter-mobile[data-v-8589d091]{align-items:center;display:flex;padding:var(--rh-space-lg,16px);width:100%}#text-input[data-v-8589d091]{padding-left:.5rem}.toc-filter[data-v-8589d091]{display:none}}@media (width <=576px){.content-format-selectors[data-v-8589d091]{display:none}}.informaltable[data-v-8589d091],.rhdocs .informaltable[data-v-8589d091],.rhdocs .table-contents[data-v-8589d091],.rhdocs .table-wrapper[data-v-8589d091],.table-contents[data-v-8589d091],.table-wrapper[data-v-8589d091]{max-height:var(--rh-table--maxHeight);overflow:auto}rh-table[data-v-8589d091]{display:block;margin:2rem 0;max-width:100%}.pvof-doc__wrapper[data-v-8589d091],.rhdocs[data-v-8589d091]{--rh-table--maxHeight:calc(100vh - 12.5rem)}</style> <style>:is(rh-footer-block) a[data-v-97dd2752]{text-decoration:underline}</style> <style>:is(rh-footer,:is(rh-footer-universal,rh-global-footer)) a{color:var(--rh-color-link-inline-on-dark,var(--rh-color-interactive-blue-lighter,#92c5f9));text-decoration:none}:is(rh-footer,:is(rh-footer-universal,rh-global-footer)) a:hover{color:var(--rh-color-link-inline-hover-on-dark,var(--rh-color-interactive-blue-lightest,#b9dafc));text-decoration:underline}:is(rh-footer,:is(rh-footer-universal,rh-global-footer)) a:is(:focus,:focus-within){color:var(--rh-color-link-inline-focus-on-dark,var(--rh-color-interactive-blue-lightest,#b9dafc));text-decoration:underline}:is(rh-footer,:is(rh-footer-universal,rh-global-footer)) a:visited{color:var(--rh-color-link-inline-visited-on-dark,var(--rh-color-interactive-blue-lightest,#b9dafc));text-decoration:none}:is(rh-footer,:is(rh-footer-universal,rh-global-footer)) a[slot^=logo]{display:block}:is(rh-footer) a[slot^=logo]>img{display:block;height:100%;height:var(--rh-size-icon-04,40px);width:auto}:is(rh-footer,rh-footer-universal,rh-global-footer) :is(h1,h2,h3,h4,h5,h6){font-family:var(--rh-font-family-heading,RedHatDisplay,"Red Hat Display","Noto Sans Arabic","Noto Sans Hebrew","Noto Sans JP","Noto Sans KR","Noto Sans Malayalam","Noto Sans SC","Noto Sans TC","Noto Sans Thai",Helvetica,Arial,sans-serif);line-height:var(--rh-line-height-heading,1.3)}rh-footer [slot=links]:is(h1,h2,h3,h4,h5):nth-of-type(n+5){--_link-header-margin:calc(var(--rh-space-2xl, 32px) - var(--rh-space-lg, 16px))}rh-footer [slot^=links] a{gap:var(--rh-footer-links-gap,var(--rh-space-md,8px))}:is(rh-footer,:is(rh-footer-universal,rh-global-footer)) [slot^=links] li{display:contents;margin:0;padding:0}:is(rh-footer,:is(rh-footer-universal,rh-global-footer)) [slot^=links] a{color:var(--rh-color-text-primary-on-dark,#fff)!important;display:block;font-size:var(--rh-footer-link-font-size,var(--rh-font-size-body-text-sm,.875rem));width:-moz-fit-content;width:fit-content}:is(rh-footer-universal,rh-global-footer) [slot^=links] a{font-size:inherit}:is(rh-footer,rh-footer-universal,rh-global-footer){--rh-footer-section-side-gap:var(--rh-space-lg,16px)}@media screen and (min-width:768px){:is(rh-footer,rh-footer-universal,rh-global-footer){--rh-footer-section-side-gap:var(--rh-space-2xl,32px)}}@media screen and (min-width:1440px){:is(rh-footer,rh-footer-universal,rh-global-footer){--rh-footer-section-side-gap:var(--rh-space-4xl,64px)}}rh-footer:not(:defined){background-color:var(--rh-color-surface-darker,#1f1f1f);display:grid;grid-template-areas:"footer" "global";grid-template-rows:1fr auto;min-height:var(--rh-footer-nojs-min-height,750px);width:100%}:is(rh-footer-universal,rh-global-footer):not(:defined):before{grid-area:global}rh-footer:not(:defined)>[slot=logo]{padding:var(--rh-space-2xl,32px) var(--_section-side-gap)}:is(rh-footer-universal,rh-global-footer):not(:defined)>*,rh-footer:not(:defined)>:not([slot=logo],:is(rh-footer-universal,rh-global-footer)){border:0;clip:rect(1px,1px,1px,1px);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}:is(rh-footer-universal,rh-global-footer):not(:defined){background-color:var(--rh-color-surface-darkest,#151515);display:block;min-height:176px;width:100%}rh-footer-universal rh-footer-copyright{grid-column:-1/1}</style> <style>.status-legal .status-page-widget[data-v-5f538988]{display:block;margin:.5rem 0;width:11.3125rem;width:-moz-max-content;width:max-content}.status-page-widget[data-v-5f538988]{align-items:center;display:flex;flex-direction:row}.status-legal .status-page-widget .status-description[data-v-5f538988]{color:#ccc;font-weight:600;letter-spacing:.0125rem;line-height:1.5;margin-right:.5rem}.status-good[data-v-5f538988]{background-color:#3e8536}.status-critical[data-v-5f538988]{background-color:#a30100}.status-partial[data-v-5f538988]{background-color:#f5c12d}.status-maintentance[data-v-5f538988]{background-color:#316dc1}.status-minor[data-v-5f538988]{background-color:#b85c00}.status-description[data-v-5f538988]{color:#ccc;font-weight:500;letter-spacing:.2px;line-height:1.5}.current-status-indicator[data-v-5f538988]{border-radius:6px;display:inline-block;height:12px;margin:0 0 0 5px;width:12px}.current-status-indicator.small[data-v-5f538988]{border-radius:4px;display:inline-block;height:8px;margin:0 0 0 5px;width:8px}</style> <style>.search-container[data-v-69710f44]{height:100%}.form-box[data-v-69710f44],.search-container[data-v-69710f44]{justify-content:center}.form-box[data-v-69710f44],.search-box[data-v-69710f44],.search-container[data-v-69710f44]{align-items:center;display:flex;width:100%}.search-box[data-v-69710f44]{justify-content:space-between;position:relative}ul[data-v-69710f44]{list-style-type:none}#search-list[data-v-69710f44]{background:#fff;border:1px solid #f0f0f0;box-shadow:0 4px 4px 0 #00000040;color:#151515;display:block;left:0;margin:0;padding:0;position:absolute;top:37px;width:100%;z-index:200}#search-list li[data-v-69710f44]{align-items:center;display:flex;justify-content:space-between;padding:.75rem}#search-list .active[data-v-69710f44],#search-list li[data-v-69710f44]:hover{background:#f0f0f0}.group-title[data-v-69710f44]{border-top:1px solid #4d4d4d;color:#4d4d4d;cursor:default;font-size:12px;font-weight:400;pointer-events:none}.group-title[data-v-69710f44],.group-title[data-v-69710f44]:hover{background:#fff}.search-item-text-elipsis[data-v-69710f44]{display:inline-block;max-width:48%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.search-item-text[data-v-69710f44]{padding-left:1.75rem}.search-item-chip[data-v-69710f44]{float:right}.search-product-version[data-v-69710f44]{background:#fff;border:1px solid #f0f0f0;border-radius:3px;font-size:1rem;font-weight:400;line-height:24px}.search-icon-form[data-v-69710f44]{color:var(--rh-color-gray-50,#707070);left:12px;position:absolute}.input-search-box[data-v-69710f44]{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:var(--rh-font-size-body-text-md,1rem);height:36px;padding:0 40px;width:100%}.input-clear-btn[data-v-69710f44]{align-items:center;background-color:transparent;border:none;display:flex;height:36px;justify-content:center;margin-right:-30px;outline:none;transform:translateX(-30px)}.input-clear-btn[data-v-69710f44]:focus{border:1px solid var(--rh-color-accent-base-on-light,#06c)}.input-clear-btn:focus .input-clear-icon[data-v-69710f44]{color:var(--rh-color-canvas-black,#151515)}.input-clear-icon[data-v-69710f44]{color:#6b6e72;cursor:pointer}.input-clear-icon[data-v-69710f44]:hover{color:var(--rh-color-canvas-black,#151515)}.form-submit-btn[data-v-69710f44]::part(button){align-items:center;background-color:var(--rh-color-gray-20,#e0e0e0);border-radius:0;display:flex;height:36px;justify-content:center;--_default-border-color:var(--rh-color-gray-20,#e0e0e0)}.input-close-btn[data-v-69710f44]{background:none;border:none;cursor:pointer;margin:0 var(--rh-space-lg,16px)}.input-close-icon[data-v-69710f44]{color:var(--rh-color-white,#fff)}@media (max-width:992px){.form-box[data-v-69710f44]{gap:var(--rh-space-md,8px);margin:auto;width:100%}.input-search-box[data-v-69710f44]{border:1px solid var(--rh-color-gray-30,#c7c7c7)}.input-search-box[data-v-69710f44]::-moz-placeholder{color:#6a6e73;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:var(--rh-font-size-body-text-md,1rem);font-weight:var(--rh-font-weight-code-regular,400);line-height:24px}.input-search-box[data-v-69710f44]::placeholder{color:#6a6e73;font-family:var(--rh-font-family-body-text,"Red Hat Text","RedHatText",Arial,sans-serif);font-size:var(--rh-font-size-body-text-md,1rem);font-weight:var(--rh-font-weight-code-regular,400);line-height:24px}.search-item-text-elipsis[data-v-69710f44]{max-width:60%}}@media (max-width:767px){.input-close-btn[data-v-69710f44]{display:none}.search-container[data-v-69710f44]{border:1px solid #f0f0f0}}</style> <style>.breadcrumbs[data-v-798f280c]{align-items:center;background-color:#f6f6f6;display:flex;gap:var(--rh-space-xl,24px);padding:var(--rh-space-lg,16px) var(--rh-space-2xl,32px)}nav[data-v-798f280c]{flex:1}ol[data-v-798f280c]{background-color:#f6f6f6;font-size:.875rem;list-style:none;margin:0;padding:0}li[data-v-798f280c]{color:#151515;display:inline}a[data-v-798f280c]:after{border-bottom-color:transparent;border-left-color:transparent;box-shadow:inset .25rem .25rem 0 .0625rem #8a8d8d;content:"";display:inline-block;height:1.07143em;margin:0 .5em;position:relative;right:0;top:.75em;transform:translateY(-.5em) rotate(135deg) scale(.5);width:1.07143em}</style> <style>ol[data-v-fa0dae77]{margin:0;padding:0}li[data-v-fa0dae77],ol[data-v-fa0dae77],ul[data-v-fa0dae77]{list-style:none;margin:0}.chapter-title[data-v-fa0dae77]{font-size:1em}.sub-chapter-title[data-v-fa0dae77],.sub-chapter-title a[data-v-fa0dae77]{font-size:.875rem}#toc .link[data-v-fa0dae77],#toc-mobile .link[data-v-fa0dae77],.heading[data-v-fa0dae77],.sub-nav .link[data-v-fa0dae77],.sub-nav .link .link[data-v-fa0dae77]{display:block;padding:var(--rh-space-md,8px) var(--rh-space-2xl,32px);padding-right:2.5em;text-decoration:none;transition:background-color .25s}.heading[data-v-fa0dae77]:hover,.link[data-v-fa0dae77]:hover,.sub-nav .link[data-v-fa0dae77]:hover{background:var(--rh-color-surface-lighter,#f2f2f2);box-shadow:inset 3px 0 0 0 #d2d2d2;color:#151515}details[open]:first-of-type>.heading[data-v-fa0dae77]:after{transform:rotate(135deg)}.item[data-v-fa0dae77]{line-height:22px}#toc .link[data-v-fa0dae77],#toc-mobile .link[data-v-fa0dae77]{color:var(--rh-color-text-primary-on-light,#151515)}.sub-nav[data-v-fa0dae77],.toc-wrapper[data-v-fa0dae77]{list-style:none;margin:0}.toc-wrapper[data-v-fa0dae77]{min-width:100%;padding:0}.sub-nav[data-v-fa0dae77]{font-size:1em;line-height:24px;padding-left:1rem;padding-left:16px}.sub-nav .link[data-v-fa0dae77]:hover{color:#151515}.active[data-v-fa0dae77]{background:var(--rh-color-surface-lighter,#f2f2f2);box-shadow:inset 3px 0 0 0 var(--rh-color-icon-primary-on-light,#e00)}.chapter-landing-page[data-v-fa0dae77]{font-weight:500}summary[data-v-fa0dae77]{cursor:pointer;list-style:none;position:relative}summary[data-v-fa0dae77]::-webkit-details-marker{display:none}@keyframes slideDown-fa0dae77{0%{height:0;opacity:0}to{height:var(--details-height-open,"100%");opacity:1}}html[data-v-fa0dae77]{--details-transition-time:400ms}details[data-v-fa0dae77]{max-height:var(--details-height-closed,auto);transition:all ease-out var(--details-transition-time,0)}details[open][data-v-fa0dae77]{max-height:var(--details-height-open,auto)}details .heading.sub-chapter-title[data-v-fa0dae77]:after,details .heading[data-v-fa0dae77]:after{border-right:3px solid #151515;border-top:3px solid #151515;color:#151515;content:"";display:flex;float:right;height:9px;margin-left:16px;position:absolute;right:var(--rh-space-xl,24px);top:14px;transform:rotate(45deg);width:9px}details .heading.sub-chapter-title[data-v-fa0dae77]:after{height:8px;width:8px}</style> <style>.item[data-v-b883c74f]{line-height:22px}#toc .link[data-v-b883c74f],#toc-mobile .link[data-v-b883c74f]{color:var(--rh-color-text-primary-on-light,#151515)}#toc .link[data-v-b883c74f],#toc-mobile .link[data-v-b883c74f],.heading[data-v-b883c74f],.sub-nav .link[data-v-b883c74f],.sub-nav .link .link[data-v-b883c74f]{display:block;padding:var(--rh-space-md,8px) var(--rh-space-2xl,32px);padding-right:2.5em;text-decoration:none;transition:background-color .25s}.heading[data-v-b883c74f]:hover,.link[data-v-b883c74f]:hover,.sub-nav .link[data-v-b883c74f]:hover{background:var(--rh-color-surface-lighter,#f2f2f2);box-shadow:inset 3px 0 0 0 #d2d2d2;color:#151515}ol[data-v-b883c74f]{margin:0;padding:0}li[data-v-b883c74f],ol[data-v-b883c74f],ul[data-v-b883c74f]{list-style:none;margin:0}.chapter-title[data-v-b883c74f]{font-size:1em}.sub-nav[data-v-b883c74f]{font-size:1em;line-height:24px;list-style:none;margin:0;padding-left:1rem;padding-left:16px}.sub-nav .link[data-v-b883c74f]:hover{color:#151515}.active[data-v-b883c74f]{background:var(--rh-color-surface-lighter,#f2f2f2);box-shadow:inset 3px 0 0 0 var(--rh-color-icon-primary-on-light,#e00)}.sub-chapter-title[data-v-b883c74f],.sub-chapter-title a[data-v-b883c74f]{font-size:.875rem}summary[data-v-b883c74f]{cursor:pointer;list-style:none;position:relative}summary[data-v-b883c74f]::-webkit-details-marker{display:none}html[data-v-b883c74f]{--details-transition-time:400ms}.chapter-landing-page[data-v-b883c74f]{font-weight:500}details[open]:first-of-type>.heading[data-v-b883c74f]:after{transform:rotate(135deg)}details[data-v-b883c74f]{max-height:var(--details-height-closed,auto);transition:all ease-out var(--details-transition-time,0)}details[open][data-v-b883c74f]{max-height:var(--details-height-open,auto)}details .heading.sub-chapter-title[data-v-b883c74f]:after,details .heading[data-v-b883c74f]:after{border-right:3px solid #151515;border-top:3px solid #151515;color:#151515;content:"";display:flex;float:right;height:9px;margin-left:16px;position:absolute;right:var(--rh-space-xl,24px);top:14px;transform:rotate(45deg);width:9px}details .heading.sub-chapter-title[data-v-b883c74f]:after{height:8px;width:8px}</style> <style>.html-container[data-v-9c2a9ddb]{padding:2rem 1.5rem 0}rh-alert[data-v-9c2a9ddb]{color:#151515}@media (max-width:772px){.html-container[data-v-9c2a9ddb]{padding:3rem 1rem 0}}</style> <style>[variant=brick][data-v-a6039582]{max-width:150px}.pagination[data-v-a6039582]{display:flex;justify-content:space-between;margin-bottom:var(--rh-space-6xl,96px);margin-top:var(--rh-space-4xl,4rem)}.previous-btn[data-v-a6039582]{margin-right:auto}.next-btn[data-v-a6039582]{margin-left:auto}.next-btn[data-v-a6039582]:hover,.previous-btn[data-v-a6039582]:hover{cursor:pointer}.next-btn.disabled[data-v-a6039582],.previous-btn.disabled[data-v-a6039582]{background-color:var(--rh-color-bg-disabled,#f2f2f2);cursor:not-allowed;pointer-events:none}</style> <style>.jump-links[data-v-1d1b84c1]{margin-top:var(--rh-space-lg,16px);max-height:85vh;overflow-y:auto}.jump-links ul[data-v-1d1b84c1]{align-items:flex-start;border-left:1px solid #c7c7c7;display:flex;flex-direction:column;list-style:none;padding:0}.jump-link-item[data-v-1d1b84c1]{border-left:3px solid transparent}.jump-link-item a[data-v-1d1b84c1]{color:#4d4d4d;cursor:pointer;display:block;font-family:Red Hat Text;font-weight:400;line-height:21px;padding:var(--rh-space-md,8px) var(--rh-space-lg,16px)}.active_link[data-v-1d1b84c1]{border-left:3px solid #e00}.active_link a[data-v-1d1b84c1],.jump-link-item a[data-v-1d1b84c1]:hover{color:#151515}@media (width < 992px){.jump-links[data-v-1d1b84c1]{max-height:50vh}}</style> <link rel="stylesheet" href="/_nuxt/entry.DNAluCmw.css" integrity="sha384-FnrZajt9k3u4tri3ClqikI96k+jP7kyrvgKKgdzBr5Y8CQEi3gusKE0+eMSLvGxm"> <link rel="stylesheet" href="/_nuxt/SearchAutocomplete.DkrJaF8R.css" integrity="sha384-Zw8gf6w7SrpWDmknvrab5QanIN+DSJRS/bPB9/lgDkhR7JhDmG/VF++MTMKU8mKB"> <link rel="stylesheet" href="/_nuxt/Breadcrumbs.BLkLxUMB.css" integrity="sha384-f6iEfCywVoZB0/hIKTRaxywtS21KzhBx2JOI/uVjjU9aqFcP7X9cqLH29w2HQvLe"> <link rel="stylesheet" href="/_nuxt/Alert.fTkXFs3h.css" integrity="sha384-yFMpT5E64LAQi3qJ10AJJ1oOH3DrI68OvLSjSivjNCQXZ25pmFxlPavPQ0TEyEpq"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/CNiJFZdP.js" integrity="sha384-URVP9DUVWSYV+JAjOlLaHBdTHOdweqttmSLAzZFSvViLMzkecvTbA+xtxD/wXGEN"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/Bv1fi8g6.js" integrity="sha384-8haXVCsFMHKst3KB4Kf0lHHxbxKNVVrFyrUGs/YOE3t1wtvDg7VP3SirBeMRz/c7"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/DQAkF__8.js" integrity="sha384-YIclgdAGudZR/trBF5+ecn9zOec/yzJN8I7AczepSGUBuUPvTD9LiEHpQEPFztyc"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/BxBriHwM.js" integrity="sha384-bejD6BN5N1iVRo5Ymn+LdVN0jvrnJTzgqgFD9xQ5+Yi46U6ff+s5W2AISzRWvJaM"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/Cky2U5sC.js" integrity="sha384-MDsUzDHhd0WaZsr2KGFtIXsAPJxJ411VNI0N3wEYx3WD5b0t8TuS7khttda92NdX"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/DcPuD3Fl.js" integrity="sha384-axPK3ka/zdfm9NOi0pKc0TjaQPyicNrqIWjVeDHDfZZOUx1nTd97FCWpOpV+Jz0T"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/Bkb9ltmc.js" integrity="sha384-vY/93XX3aYkUVJknIF1OQcjsm0eOkId78OUxCNS9dXXtCCuWVBfzLyAuYRtTPrnq"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/JI5C9S6O.js" integrity="sha384-jy6b36IHAU1aS8sCc3UT3LTtLZdRP6Pa0SEQnDZPehcbWg5alyj+0drAPKvV50DC"> <link rel="modulepreload" as="script" crossorigin href="/_nuxt/D6LL9Uar.js" integrity="sha384-slZCQR+F8ZiFxNAJFqFtsk6nPMPxUwi3OZ2IfzHQdnTcx7bXyf5NEEkE+08ZBICK"> <link rel="prefetch" as="script" crossorigin href="/_nuxt/Bk1ABdVS.js"> <link rel="prefetch" as="script" crossorigin href="/_nuxt/Ccb2Tfpa.js"> <link rel="prefetch" as="script" crossorigin href="/_nuxt/DcO9tLDe.js"> <link rel="prefetch" as="script" crossorigin href="/_nuxt/Ciddaed-.js"> <link rel="prefetch" as="image" type="image/svg+xml" href="/_nuxt/Footer_Cloud.DpSdW8MR.svg"> <script type="module"> import "@rhds/elements/rh-cta/rh-cta.js"; </script> <script type="module"> import '@rhds/elements/rh-alert/rh-alert.js'; </script> <script type="module"> import "/scripts/v1/@cpelements/pfe-navigation/dist/pfe-navigation.min.js"; import "/scripts/v1/@rhds/elements/elements/rh-button/rh-button.js"; </script> <script type="module">import "@rhds/elements/rh-footer/rh-footer.js"</script> <script type="module"> import "/scripts/v1/@rhds/elements/elements/rh-button/rh-button.js"; import "@patternfly/elements/pf-badge/pf-badge.js"; </script> <link rel="canonical" href="https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/developing-operators"> <script type="module"> import "@rhds/elements/rh-alert/rh-alert.js"; import "@rhds/elements/rh-code-block/rh-code-block.js"; import '@rhds/elements/rh-cta/rh-cta.js'; import '@patternfly/elements/pf-switch/pf-switch.js'; import '@cpelements/rh-table/dist/rh-table.js'; import '@patternfly/pfe-clipboard/dist/pfe-clipboard.min.js'; import '@patternfly/elements/pf-button/pf-button.js'; import '@patternfly/elements/pf-modal/pf-modal.js'; import '@patternfly/elements/pf-icon/pf-icon.js'; import '@patternfly/elements/pf-popover/pf-popover.js'; import '@patternfly/elements/pf-tooltip/pf-tooltip.js'; import '@rhds/elements/rh-badge/rh-badge.js'; </script> <meta name="description" content="Chapter 5. Developing Operators | Red Hat Documentation"> <meta name="app-version" content="v0.0.1"> <script type="module"> import "/scripts/v1/@rhds/elements/elements/rh-button/rh-button.js"; </script> <script type="module"> import '@rhds/elements/rh-alert/rh-alert.js'; </script> <script type="module" src="/_nuxt/CNiJFZdP.js" crossorigin integrity="sha384-URVP9DUVWSYV+JAjOlLaHBdTHOdweqttmSLAzZFSvViLMzkecvTbA+xtxD/wXGEN"></script></head><body><div id="__nuxt"><!--[--><!--[--><!----><header data-v-edc0d12c><a href="#pfe-navigation" id="global-skip-to-nav" class="skip-link visually-hidden" data-v-edc0d12c>Skip to navigation</a><a href="#main-content" class="skip-link visually-hidden" data-v-edc0d12c>Skip to content</a><nav id="upper-navigation" class="upper-navigation" aria-labelledby="upper-navigation-label" data-analytics-region="upper-navigation" data-v-edc0d12c><p id="upper-navigation-label" class="upper-nav-hidden" data-v-edc0d12c>Featured links</p><div class="upper-nav-container" data-v-edc0d12c><ul class="upper-nav-menu" data-v-edc0d12c><li data-v-edc0d12c><a href="https://access.redhat.com/" class="upper-nav-links" data-analytics-text="Support" data-analytics-category="Featured Links" data-v-edc0d12c>Support</a></li><li data-v-edc0d12c><a href="https://console.redhat.com/" class="upper-nav-links" data-analytics-text="Console" data-analytics-category="Featured Links" data-v-edc0d12c>Console</a></li><li data-v-edc0d12c><a href="https://developers.redhat.com/" class="upper-nav-links" data-analytics-text="Developers" data-analytics-category="Featured Links" data-v-edc0d12c>Developers</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/en/products/trials" class="upper-nav-links" data-analytics-text="Start a trial" data-analytics-category="Featured Links" data-v-edc0d12c>Start a trial</a></li><li data-v-edc0d12c><button id="all-red-hat" class="upper-nav-links" data-analytics-text="All Red Hat" data-analytics-category="Featured Links" aria-expanded="false" data-analytics-linktype="tab" data-v-edc0d12c>All Red Hat<svg class="upper-nav-arrow" xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" aria-hidden="true" data-v-edc0d12c=""><path d="M810.642 511.557c0 8.905-3.447 16.776-10.284 23.613L322.31 1013.216c-6.835 6.837-14.706 10.284-23.61 10.284s-16.776-3.447-23.613-10.284l-51.303-51.303c-6.837-6.837-10.284-14.707-10.284-23.612s3.447-16.775 10.284-23.61L626.972 511.5 223.784 108.31c-6.837-6.835-10.284-14.706-10.284-23.61s3.447-16.776 10.284-23.613l51.303-51.303C281.924 2.947 289.794-.5 298.7-.5s16.775 3.447 23.61 10.284L800.36 487.83c6.837 6.837 10.284 14.708 10.284 23.613v.114" data-v-edc0d12c=""/></svg></button><div class="upper-nav-dropdown-container" data-v-edc0d12c><ul data-v-edc0d12c><li data-v-edc0d12c><span data-v-edc0d12c>For customers</span><ul data-v-edc0d12c><li data-v-edc0d12c><a href="https://access.redhat.com/support" data-pzn-audience="customers" data-analytics-category="All Red Hat|For customers" data-analytics-text="Customer support" data-v-edc0d12c>Customer support</a></li><li data-v-edc0d12c><a href="/products" data-pzn-audience="customers" data-analytics-category="All Red Hat|For customers" data-analytics-text="Documentation" data-v-edc0d12c>Documentation</a></li><li data-v-edc0d12c><a href="https://access.redhat.com/support/cases" data-pzn-audience="customers" data-analytics-category="All Red Hat|For customers" data-analytics-text="Support cases" data-v-edc0d12c>Support Cases</a></li><li data-v-edc0d12c><a href="https://access.redhat.com/management" data-pzn-audience="customers" data-analytics-category="All Red Hat|For customers" data-analytics-text="Subscription management" data-v-edc0d12c>Subscription management</a></li><li data-v-edc0d12c><a href="https://catalog.redhat.com/" data-analytics-category="All Red Hat|For customers" data-analytics-text="Red Hat Ecosystem Catalog" data-v-edc0d12c>Red Hat Ecosystem Catalog</a></li><li data-v-edc0d12c><a href="https://catalog.redhat.com/partners" data-analytics-category="All Red Hat|For customers" data-analytics-text="Find a partner" data-v-edc0d12c>Find a partner</a></li></ul></li><li data-v-edc0d12c><span data-v-edc0d12c>For partners</span><ul data-v-edc0d12c><li data-v-edc0d12c><a href="https://connect.redhat.com/login" data-pzn-audience="partners" data-analytics-category="All Red Hat|For partners" data-analytics-text="Partner login" data-v-edc0d12c>Partner login</a></li><li data-v-edc0d12c><a href="https://connect.redhat.com/en/support" data-pzn-audience="partners" data-analytics-category="All Red Hat|For partners" data-analytics-text="Partner support" data-v-edc0d12c>Partner support</a></li><li data-v-edc0d12c><a href="https://connect.redhat.com/" data-pzn-audience="partners" data-analytics-category="All Red Hat|For partners" data-analytics-text="Become a partner " data-v-edc0d12c>Become a partner</a></li></ul></li><li data-v-edc0d12c><span data-v-edc0d12c>Try, buy, &amp; sell</span><ul data-v-edc0d12c><li data-v-edc0d12c><a href="https://marketplace.redhat.com/en-us" data-analytics-category="All Red Hat|Try, buy, &amp; sell" data-analytics-text="Red Hat Marketplace" data-v-edc0d12c>Red Hat Marketplace</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/en/store" data-analytics-category="All Red Hat|Try, buy, &amp; sell" data-analytics-text="Red Hat Store" data-v-edc0d12c>Red Hat Store</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/en/contact" data-analytics-category="All Red Hat|Try, buy, &amp; sell" data-analytics-text="Contact sales" data-v-edc0d12c>Contact Sales</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/en/products/trials" data-analytics-category="All Red Hat|Try, buy, &amp; sell" data-analytics-text="Start a trial" data-v-edc0d12c>Start a trial</a></li></ul></li><li data-v-edc0d12c><span data-v-edc0d12c>Learning resources</span><ul data-v-edc0d12c><li data-v-edc0d12c><a href="https://www.redhat.com/en/services/training-and-certification" data-analytics-category="All Red Hat|Learning resources" data-analytics-text="Training and certification " data-v-edc0d12c>Training and certification</a></li><li data-v-edc0d12c><a href="https://developers.redhat.com/" data-pzn-audience="developers|community" data-analytics-category="All Red Hat|Learning resources" data-analytics-text="For developers" data-v-edc0d12c>For developers</a></li><li data-v-edc0d12c><a href="https://cloud.redhat.com/learn" data-analytics-category="All Red Hat|Learning resources" data-analytics-text="Hybrid cloud learning hub" data-v-edc0d12c>Hybrid cloud learning hub</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/en/interactive-labs" data-analytics-category="All Red Hat|Learning resources" data-analytics-text="Interactive labs" data-v-edc0d12c>Interactive labs</a></li><li data-v-edc0d12c><a href="https://learn.redhat.com/" data-analytics-category="All Red Hat|Learning resources" data-analytics-text="Learning community" data-v-edc0d12c>Learning community</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/en/tv" data-analytics-category="All Red Hat|Learning resources" data-analytics-text="Red Hat TV" data-v-edc0d12c>Red Hat TV</a></li></ul></li><li data-v-edc0d12c><span data-v-edc0d12c>Open source communities</span><ul data-v-edc0d12c><li data-v-edc0d12c><a href="https://www.ansible.com/community" data-analytics-category="All Red Hat|Open source communities" data-analytics-text="Ansible" data-v-edc0d12c>Ansible</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/sysadmin/" id="community" data-analytics-category="All Red Hat|Open source communities" data-analytics-text="For system administrators" data-v-edc0d12c>For system administrators</a></li><li data-v-edc0d12c><a href="https://www.redhat.com/architect/" data-pzn-audience="community" data-analytics-category="All Red Hat|Open source communities" data-analytics-text="For architects" data-v-edc0d12c>For architects</a></li></ul></li></ul></div></li></ul></div></nav><pfe-navigation full-width id="pfe-navigation" pf-sticky="true" lang="en" data-v-edc0d12c><nav class="pfe-navigation" aria-label="Main Navigation" data-v-edc0d12c><div class="pfe-navigation__logo-wrapper" id="pfe-navigation__logo-wrapper" data-v-edc0d12c><a href="/en" class="pfe-navigation__logo-link" data-v-edc0d12c><img class="pfe-navigation__logo-image pfe-navigation__logo-image--screen pfe-navigation__logo-image--small" src="/Logo-Red_Hat-Documentation-A-Reverse-RGB.svg" width="240" height="40" alt="Red Hat Documentation" data-v-edc0d12c></a></div></nav><span data-v-edc0d12c></span><div slot="secondary-links" data-v-edc0d12c><div class="hidden-at-desktop hidden-at-tablet search-mobile" data-v-edc0d12c><div id="search-form" class="search-container" opensearchbox="true" data-v-edc0d12c data-v-69710f44><form role="search" class="form-box" autocomplete="off" data-v-69710f44><div class="search-box" data-v-69710f44><pf-icon icon="search" size="md" class="search-icon-form" data-v-69710f44></pf-icon><input type="text" id="input-search" class="input-search-box" placeholder="Search documentation" value aria-autocomplete="list" data-v-69710f44><!----><!----><!----><rh-button disabled variant="tertiary" class="form-submit-btn" data-v-69710f44><img src="data:image/svg+xml,%3csvg%20width=&#39;14&#39;%20height=&#39;14&#39;%20viewBox=&#39;0%200%2014%2014&#39;%20fill=&#39;none&#39;%20xmlns=&#39;http://www.w3.org/2000/svg&#39;%3e%3cpath%20d=&#39;M7%200L5.6%201.4L10.3%206H0V8H10.3L5.6%2012.6L7%2014L14%207L7%200Z&#39;%20fill=&#39;%23707070&#39;/%3e%3c/svg%3e" alt="Submit button" data-v-69710f44></rh-button></div></form><!----></div></div><div class="hidden-at-desktop hidden-at-tablet buttons" data-v-edc0d12c><a href="https://access.redhat.com/" data-analytics-category="More Red Hat" data-analytics-text="Support" data-v-edc0d12c>Support</a><a href="https://console.redhat.com/" data-analytics-category="More Red Hat" data-analytics-text="Console" data-v-edc0d12c>Console</a><a href="https://developers.redhat.com/" data-analytics-category="More Red Hat" data-analytics-text="Developers" data-v-edc0d12c>Developers</a><a href="https://www.redhat.com/en/products/trials" data-analytics-category="More Red Hat" data-analytics-text="Start a trial" data-v-edc0d12c>Start a trial</a><a href="https://www.redhat.com/en/contact" data-analytics-category="More Red Hat" data-analytics-text="Contact" data-v-edc0d12c>Contact</a></div><div class="hidden-at-desktop hidden-at-tablet mobile-lang-select" data-v-edc0d12c><label for="lang_selection" data-v-edc0d12c>Select your language</label><select id="lang_selection" data-v-edc0d12c><!--[--><option value="en" xml:lang="en" hreflang="en" data-v-edc0d12c>English</option><option value="fr" xml:lang="fr" hreflang="fr" data-v-edc0d12c>Français</option><option value="ko" xml:lang="ko" hreflang="ko" data-v-edc0d12c>한국어</option><option value="ja" xml:lang="ja" hreflang="ja" data-v-edc0d12c>日本語</option><option value="zh-cn" xml:lang="zh-cn" hreflang="zh-cn" data-v-edc0d12c>中文 (中国)</option><option value="de" xml:lang="de" hreflang="de" data-v-edc0d12c>Deutsch</option><option value="it" xml:lang="it" hreflang="it" data-v-edc0d12c>Italiano</option><option value="pt-br" xml:lang="pt-br" hreflang="pt-br" data-v-edc0d12c>Português</option><option value="es" xml:lang="es" hreflang="es" data-v-edc0d12c>Español</option><!--]--></select></div></div></pfe-navigation></header><main id="main-content"><!--[--><!--[--><!--[--><!----><!----><!--]--><div class="breadcrumbs" id="breadcrumbs" data-v-8589d091 data-v-798f280c><nav aria-label="Breadcrumb" class="breadcrumb" data-v-798f280c><ol data-v-798f280c><li data-v-798f280c><a href="/" data-v-798f280c>Home</a></li><li data-v-798f280c><a href="/en/products" data-v-798f280c>Products</a></li><!--[--><li data-v-798f280c><a href="/en/documentation/openshift_container_platform/" data-v-798f280c>OpenShift Container Platform</a></li><li data-v-798f280c><a href="/en/documentation/openshift_container_platform/4.8/" data-v-798f280c>4.8</a></li><li data-v-798f280c><a href="/en/documentation/openshift_container_platform/4.8/html/operators/" data-v-798f280c>Operators</a></li><li data-v-798f280c><!--[-->Chapter 5. Developing Operators<!--]--></li><!--]--></ol></nav><span data-v-798f280c></span></div><!----><nav id="mobile-nav" class="mobile-nav" aria-label="mobile menu" data-v-8589d091><div class="mobile-nav-wrapper" data-v-8589d091><div id="first-button" data-v-8589d091><button id="toc-btn" aria-expanded="false" aria-controls="mobile-nav-content-wrapper" class="mobile-nav-btn" data-v-8589d091><span class="sr-only" data-v-8589d091>Open </span>Table of contents</button></div><div id="second-button" data-v-8589d091><button id="settings-btn" aria-expanded="false" aria-controls="mobile-nav-content-wrapper" class="mobile-nav-btn" data-v-8589d091><pf-icon icon="cog" size="md" data-v-8589d091></pf-icon><span class="sr-only" data-v-8589d091>Open page settings</span></button></div></div><div id="mobile-nav-content-wrapper" class="hidden" role="navigation" tabindex="0" data-v-8589d091><div id="toc-mobile" class="hidden" aria-labelledby="toc-btn" data-v-8589d091><div class="product-container" id="product-container-mobile" data-v-8589d091><h1 class="product-title" data-v-8589d091>OpenShift Container Platform</h1><div class="product-version" data-v-8589d091><label class="version-label" for="mobile-version-selector" data-v-8589d091>Version</label><select id="mobile-version-selector" class="version-select-dropdown" data-v-8589d091><!--[--><option value="4.17" data-v-8589d091>4.17</option><option value="4.16" data-v-8589d091>4.16</option><option value="4.15" data-v-8589d091>4.15</option><option value="4.14" data-v-8589d091>4.14</option><option value="4.13" data-v-8589d091>4.13</option><option value="4.12" data-v-8589d091>4.12</option><option value="4.11" data-v-8589d091>4.11</option><option value="4.10" data-v-8589d091>4.10</option><option value="4.9" data-v-8589d091>4.9</option><option value="4.8" selected data-v-8589d091>4.8</option><option value="4.7" data-v-8589d091>4.7</option><option value="4.6" data-v-8589d091>4.6</option><option value="4.5" data-v-8589d091>4.5</option><option value="4.4" data-v-8589d091>4.4</option><option value="4.3" data-v-8589d091>4.3</option><option value="4.2" data-v-8589d091>4.2</option><option value="4.1" data-v-8589d091>4.1</option><option value="3.11" data-v-8589d091>3.11</option><option value="3.10" data-v-8589d091>3.10</option><option value="3.9" data-v-8589d091>3.9</option><option value="3.7" data-v-8589d091>3.7</option><option value="3.6" data-v-8589d091>3.6</option><option value="3.5" data-v-8589d091>3.5</option><option value="3.4" data-v-8589d091>3.4</option><option value="3.3" data-v-8589d091>3.3</option><option value="3.2" data-v-8589d091>3.2</option><option value="3.1" data-v-8589d091>3.1</option><option value="3.0" data-v-8589d091>3.0</option><option value="2" data-v-8589d091>2</option><!--]--></select><pf-popover position="bottom" data-v-8589d091><p slot="heading" class="popover-header-text" data-v-8589d091>This documentation may not be available for all versions.</p><div slot="body" data-v-8589d091><a href="/en/documentation/openshift_container_platform" class="popover-body-link" data-v-8589d091>View the product page for all versions</a></div><button class="popover-trigger-btn" aria-label="toggle version information popover" data-v-8589d091><pf-icon set="patternfly" icon="info-alt" size="sm" data-v-8589d091></pf-icon></button></pf-popover></div></div><div class="toc-filter-mobile" data-v-8589d091><span id="text" part="text" data-v-8589d091><input id="text-input" aria-label="Search input" part="text-input" placeholder="Filter table of contents" type="text" class value data-v-8589d091><!----></span></div><div id="toc-wrapper-mobile" class="span-xs-12 span-sm-4 span-md-3" lang="en" data-v-8589d091><nav id="mobile-toc-menu" class="table-of-contents" aria-label="table of content - mobile" data-v-8589d091><!----></nav></div><!----></div><div id="page-content-options-mobile" class="hidden" aria-labelledby="settings-btn" data-v-8589d091><div class="page-layout-options" data-v-8589d091><label for="page-format-mobile" data-v-8589d091>Format</label><select id="page-format-mobile" class="page-format-dropdown" data-v-8589d091><option selected class="page-type" value="html" data-v-8589d091>Multi-page</option><option class="page-type" value="html-single" data-v-8589d091>Single-page</option><option class="page-type" value="pdf" data-v-8589d091>View full doc as PDF</option></select></div></div></div><div class="mobile-jump-links mobile-nav-wrapper" data-v-8589d091><div id="first-button" data-v-8589d091><button class="mobile-nav-btn" id="jump-links-btn" aria-expanded="false" aria-controls="mobile-jump-links-content-wrapper" data-v-8589d091>Jump to section</button></div><!----></div><!----></nav><div class="grid grid-col-12 content-wrapper" data-v-8589d091><aside id="left-content" class="span-xs-12 span-sm-4 span-md-3" lang="en-us" aria-label="left navigation" xml:lang="en-us" data-v-8589d091><div class="toc-container" id="toc-container" visible="true" data-v-8589d091><div class="toc-focus-container" id="toc-focus-container" data-v-8589d091><button class="toc-focus-btn" aria-label="toggle left menu" aria-controls="toc-container" aria-expanded="true" data-v-8589d091><pf-icon size="md" icon="angle-left" class="toc-focus-btn-icon" data-v-8589d091></pf-icon></button></div><div class="product-container" id="product-container-desktop" data-v-8589d091><h1 class="product-title" data-v-8589d091>OpenShift Container Platform</h1><div class="product-version" data-v-8589d091><label class="version-label" for="version-selector" data-v-8589d091>Version</label><select id="version-selector" class="version-select-dropdown" data-v-8589d091><!--[--><option value="4.17" data-v-8589d091>4.17</option><option value="4.16" data-v-8589d091>4.16</option><option value="4.15" data-v-8589d091>4.15</option><option value="4.14" data-v-8589d091>4.14</option><option value="4.13" data-v-8589d091>4.13</option><option value="4.12" data-v-8589d091>4.12</option><option value="4.11" data-v-8589d091>4.11</option><option value="4.10" data-v-8589d091>4.10</option><option value="4.9" data-v-8589d091>4.9</option><option value="4.8" selected data-v-8589d091>4.8</option><option value="4.7" data-v-8589d091>4.7</option><option value="4.6" data-v-8589d091>4.6</option><option value="4.5" data-v-8589d091>4.5</option><option value="4.4" data-v-8589d091>4.4</option><option value="4.3" data-v-8589d091>4.3</option><option value="4.2" data-v-8589d091>4.2</option><option value="4.1" data-v-8589d091>4.1</option><option value="3.11" data-v-8589d091>3.11</option><option value="3.10" data-v-8589d091>3.10</option><option value="3.9" data-v-8589d091>3.9</option><option value="3.7" data-v-8589d091>3.7</option><option value="3.6" data-v-8589d091>3.6</option><option value="3.5" data-v-8589d091>3.5</option><option value="3.4" data-v-8589d091>3.4</option><option value="3.3" data-v-8589d091>3.3</option><option value="3.2" data-v-8589d091>3.2</option><option value="3.1" data-v-8589d091>3.1</option><option value="3.0" data-v-8589d091>3.0</option><option value="2" data-v-8589d091>2</option><!--]--></select><pf-popover position="right" data-v-8589d091><p slot="heading" class="popover-header-text" data-v-8589d091>This documentation may not be available for all versions.</p><div slot="body" data-v-8589d091><a href="/en/documentation/openshift_container_platform" class="popover-body-link" data-v-8589d091>View the product page for all versions</a></div><button class="popover-trigger-btn" aria-label="toggle version information popover" data-v-8589d091><pf-icon set="patternfly" icon="info-alt" size="sm" data-v-8589d091></pf-icon></button></pf-popover></div></div><div class="toc-filter" id="toc-filter" data-v-8589d091><span id="text" part="text" data-v-8589d091><span id="search-icon" part="search-icon" data-v-8589d091><pf-icon icon="filter" size="md" data-v-8589d091></pf-icon></span><input id="text-input" aria-label="Search input" part="text-input" placeholder="Filter table of contents" type="text" class value data-v-8589d091><!----></span></div><div id="toc-wrapper" class="toc-wrapper" data-v-8589d091><nav id="toc" class="max-height-75 table-of-contents" aria-label="Table of contents" data-v-8589d091><ol id="toc-list" data-v-8589d091><!--[--><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Getting Started</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>About</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/about/index" id="chapter-landing--about-index" data-v-b883c74f>About</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/about/welcome-index" id="sub-link-to-about-welcome-index" data-v-b883c74f>OpenShift Container Platform 4.8 Documentation</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/about/learn_more_about_openshift" id="sub-link-to-about-learn_more_about_openshift" data-v-b883c74f>Learn more about OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/about/oke-about" id="sub-link-to-about-oke-about" data-v-b883c74f>About OpenShift Kubernetes Engine</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/about/kubernetes-overview" id="sub-link-to-about-kubernetes-overview" data-v-b883c74f>Kubernetes overview</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Release notes</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/release_notes/index" id="chapter-landing--release_notes-index" data-v-b883c74f>Release notes</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/release_notes/ocp-4-8-release-notes" id="sub-link-to-release_notes-ocp-4-8-release-notes" data-v-b883c74f>OpenShift Container Platform 4.8 release notes</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Architecture</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/architecture/index" id="chapter-landing--architecture-index" data-v-b883c74f>Architecture</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/architecture/architecture-overview" id="sub-link-to-architecture-architecture-overview" data-v-b883c74f>Architecture overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/architecture/architecture" id="sub-link-to-architecture-architecture" data-v-b883c74f>OpenShift Container Platform architecture</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/architecture/architecture-installation" id="sub-link-to-architecture-architecture-installation" data-v-b883c74f>Installation and update</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/architecture/control-plane" id="sub-link-to-architecture-control-plane" data-v-b883c74f>Control plane architecture</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/architecture/understanding-development" id="sub-link-to-architecture-understanding-development" data-v-b883c74f>Understanding OpenShift Container Platform development</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/architecture/architecture-rhcos" id="sub-link-to-architecture-architecture-rhcos" data-v-b883c74f>Red Hat Enterprise Linux CoreOS (RHCOS)</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/architecture/admission-plug-ins" id="sub-link-to-architecture-admission-plug-ins" data-v-b883c74f>Admission plugins</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Security and compliance</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/index" id="chapter-landing--security_and_compliance-index" data-v-b883c74f>Security and compliance</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/security-compliance-overview" id="sub-link-to-security_and_compliance-security-compliance-overview" data-v-b883c74f>OpenShift Container Platform security and compliance</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/container-security-1" id="sub-link-to-security_and_compliance-container-security-1" data-v-b883c74f>Container security</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/configuring-certificates" id="sub-link-to-security_and_compliance-configuring-certificates" data-v-b883c74f>Configuring certificates</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/certificate-types-and-descriptions" id="sub-link-to-security_and_compliance-certificate-types-and-descriptions" data-v-b883c74f>Certificate types and descriptions</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/compliance-operator" id="sub-link-to-security_and_compliance-compliance-operator" data-v-b883c74f>Compliance Operator</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/file-integrity-operator" id="sub-link-to-security_and_compliance-file-integrity-operator" data-v-b883c74f>File Integrity Operator</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/audit-log-view" id="sub-link-to-security_and_compliance-audit-log-view" data-v-b883c74f>Viewing audit logs</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/audit-log-policy-config" id="sub-link-to-security_and_compliance-audit-log-policy-config" data-v-b883c74f>Configuring the audit log policy</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/tls-security-profiles" id="sub-link-to-security_and_compliance-tls-security-profiles" data-v-b883c74f>Configuring TLS security profiles</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/seccomp-profiles" id="sub-link-to-security_and_compliance-seccomp-profiles" data-v-b883c74f>Configuring seccomp profiles</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/allowing-javascript-based-access-api-server" id="sub-link-to-security_and_compliance-allowing-javascript-based-access-api-server" data-v-b883c74f>Allowing JavaScript-based access to the API server from additional hosts</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/encrypting-etcd" id="sub-link-to-security_and_compliance-encrypting-etcd" data-v-b883c74f>Encrypting etcd data</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/security_and_compliance/pod-vulnerability-scan" id="sub-link-to-security_and_compliance-pod-vulnerability-scan" data-v-b883c74f>Scanning pods for vulnerabilities</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Install</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Installing</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/installing/index" id="chapter-landing--installing-index" data-v-b883c74f>Installing</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/ocp-installation-overview" id="sub-link-to-installing-ocp-installation-overview" data-v-b883c74f>OpenShift Container Platform installation overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-preparing" id="sub-link-to-installing-installing-preparing" data-v-b883c74f>Selecting a cluster installation method and preparing it for users</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-mirroring-installation-images" id="sub-link-to-installing-installing-mirroring-installation-images" data-v-b883c74f>Mirroring images for a disconnected installation</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-aws" id="sub-link-to-installing-installing-on-aws" data-v-b883c74f>Installing on AWS</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-azure" id="sub-link-to-installing-installing-on-azure" data-v-b883c74f>Installing on Azure</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-gcp" id="sub-link-to-installing-installing-on-gcp" data-v-b883c74f>Installing on GCP</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-bare-metal" id="sub-link-to-installing-installing-on-bare-metal" data-v-b883c74f>Installing on bare metal</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/deploying-installer-provisioned-clusters-on-bare-metal" id="sub-link-to-installing-deploying-installer-provisioned-clusters-on-bare-metal" data-v-b883c74f>Deploying installer-provisioned clusters on bare metal</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-with-z-vm-on-ibm-z-and-linuxone" id="sub-link-to-installing-installing-with-z-vm-on-ibm-z-and-linuxone" data-v-b883c74f>Installing with z/VM on IBM Z and LinuxONE</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-with-rhel-kvm-on-ibm-z-and-linuxone" id="sub-link-to-installing-installing-with-rhel-kvm-on-ibm-z-and-linuxone" data-v-b883c74f>Installing with RHEL KVM on IBM Z and LinuxONE</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-ibm-power-systems" id="sub-link-to-installing-installing-on-ibm-power-systems" data-v-b883c74f>Installing on IBM Power Systems</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-openstack" id="sub-link-to-installing-installing-on-openstack" data-v-b883c74f>Installing on OpenStack</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-rhv" id="sub-link-to-installing-installing-on-rhv" data-v-b883c74f>Installing on RHV</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-vsphere" id="sub-link-to-installing-installing-on-vsphere" data-v-b883c74f>Installing on vSphere</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-vmc" id="sub-link-to-installing-installing-on-vmc" data-v-b883c74f>Installing on VMC</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-on-any-platform" id="sub-link-to-installing-installing-on-any-platform" data-v-b883c74f>Installing on any platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installation-configuration" id="sub-link-to-installing-installation-configuration" data-v-b883c74f>Installation configuration</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/validating-an-installation" id="sub-link-to-installing-validating-an-installation" data-v-b883c74f>Validating an installation</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-troubleshooting" id="sub-link-to-installing-installing-troubleshooting" data-v-b883c74f>Troubleshooting installation issues</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/installing/installing-fips" id="sub-link-to-installing-installing-fips" data-v-b883c74f>Support for FIPS cryptography</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Upgrade</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Updating clusters</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/index" id="chapter-landing--updating_clusters-index" data-v-b883c74f>Updating clusters</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/understanding-openshift-updates" id="sub-link-to-updating_clusters-understanding-openshift-updates" data-v-b883c74f>Understanding OpenShift Container Platform updates</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-clusters-overview" id="sub-link-to-updating_clusters-updating-clusters-overview" data-v-b883c74f>Updating clusters overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/understanding-upgrade-channels-releases" id="sub-link-to-updating_clusters-understanding-upgrade-channels-releases" data-v-b883c74f>Understanding upgrade channels and releases</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/preparing-eus-eus-upgrade" id="sub-link-to-updating_clusters-preparing-eus-eus-upgrade" data-v-b883c74f>Preparing to perform an EUS-to-EUS update</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-cluster-within-minor" id="sub-link-to-updating_clusters-updating-cluster-within-minor" data-v-b883c74f>Updating a cluster using the web console</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-cluster-cli" id="sub-link-to-updating_clusters-updating-cluster-cli" data-v-b883c74f>Updating a cluster using the CLI</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/update-using-custom-machine-config-pools" id="sub-link-to-updating_clusters-update-using-custom-machine-config-pools" data-v-b883c74f>Performing a canary rollout update</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-cluster-rhel-compute" id="sub-link-to-updating_clusters-updating-cluster-rhel-compute" data-v-b883c74f>Updating a cluster that includes RHEL compute machines</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-a-cluster-in-a-disconnected-environment" id="sub-link-to-updating_clusters-updating-a-cluster-in-a-disconnected-environment" data-v-b883c74f>Updating a cluster in a disconnected environment</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Configure</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Storage</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/storage/index" id="chapter-landing--storage-index" data-v-b883c74f>Storage</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/storage/storage-overview" id="sub-link-to-storage-storage-overview" data-v-b883c74f>OpenShift Container Platform storage overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/storage/understanding-ephemeral-storage" id="sub-link-to-storage-understanding-ephemeral-storage" data-v-b883c74f>Understanding ephemeral storage</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/storage/understanding-persistent-storage" id="sub-link-to-storage-understanding-persistent-storage" data-v-b883c74f>Understanding persistent storage</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/storage/configuring-persistent-storage" id="sub-link-to-storage-configuring-persistent-storage" data-v-b883c74f>Configuring persistent storage</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/storage/using-container-storage-interface-csi" id="sub-link-to-storage-using-container-storage-interface-csi" data-v-b883c74f>Using Container Storage Interface (CSI)</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/storage/expanding-persistent-volumes" id="sub-link-to-storage-expanding-persistent-volumes" data-v-b883c74f>Expanding persistent volumes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/storage/dynamic-provisioning" id="sub-link-to-storage-dynamic-provisioning" data-v-b883c74f>Dynamic provisioning</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Authentication and authorization</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/index" id="chapter-landing--authentication_and_authorization-index" data-v-b883c74f>Authentication and authorization</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/overview-of-authentication-authorization" id="sub-link-to-authentication_and_authorization-overview-of-authentication-authorization" data-v-b883c74f>Overview of authentication and authorization</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/understanding-authentication" id="sub-link-to-authentication_and_authorization-understanding-authentication" data-v-b883c74f>Understanding authentication</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/configuring-internal-oauth" id="sub-link-to-authentication_and_authorization-configuring-internal-oauth" data-v-b883c74f>Configuring the internal OAuth server</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/configuring-oauth-clients" id="sub-link-to-authentication_and_authorization-configuring-oauth-clients" data-v-b883c74f>Configuring OAuth clients</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/managing-oauth-access-tokens" id="sub-link-to-authentication_and_authorization-managing-oauth-access-tokens" data-v-b883c74f>Managing user-owned OAuth access tokens</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/understanding-identity-provider" id="sub-link-to-authentication_and_authorization-understanding-identity-provider" data-v-b883c74f>Understanding identity provider configuration</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/configuring-identity-providers" id="sub-link-to-authentication_and_authorization-configuring-identity-providers" data-v-b883c74f>Configuring identity providers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/using-rbac" id="sub-link-to-authentication_and_authorization-using-rbac" data-v-b883c74f>Using RBAC to define and apply permissions</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/removing-kubeadmin" id="sub-link-to-authentication_and_authorization-removing-kubeadmin" data-v-b883c74f>Removing the kubeadmin user</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/understanding-and-creating-service-accounts" id="sub-link-to-authentication_and_authorization-understanding-and-creating-service-accounts" data-v-b883c74f>Understanding and creating service accounts</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/using-service-accounts" id="sub-link-to-authentication_and_authorization-using-service-accounts" data-v-b883c74f>Using service accounts in applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/using-service-accounts-as-oauth-client" id="sub-link-to-authentication_and_authorization-using-service-accounts-as-oauth-client" data-v-b883c74f>Using a service account as an OAuth client</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/tokens-scoping" id="sub-link-to-authentication_and_authorization-tokens-scoping" data-v-b883c74f>Scoping tokens</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/bound-service-account-tokens" id="sub-link-to-authentication_and_authorization-bound-service-account-tokens" data-v-b883c74f>Using bound service account tokens</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/managing-pod-security-policies" id="sub-link-to-authentication_and_authorization-managing-pod-security-policies" data-v-b883c74f>Managing security context constraints</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/impersonating-system-admin" id="sub-link-to-authentication_and_authorization-impersonating-system-admin" data-v-b883c74f>Impersonating the system:admin user</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/ldap-syncing" id="sub-link-to-authentication_and_authorization-ldap-syncing" data-v-b883c74f>Syncing LDAP groups</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/managing-cloud-provider-credentials" id="sub-link-to-authentication_and_authorization-managing-cloud-provider-credentials" data-v-b883c74f>Managing cloud provider credentials</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Networking</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/networking/index" id="chapter-landing--networking-index" data-v-b883c74f>Networking</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/understanding-networking" id="sub-link-to-networking-understanding-networking" data-v-b883c74f>Understanding networking</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/accessing-hosts" id="sub-link-to-networking-accessing-hosts" data-v-b883c74f>Accessing hosts</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/networking-operators-overview" id="sub-link-to-networking-networking-operators-overview" data-v-b883c74f>Networking Operators overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/cluster-network-operator" id="sub-link-to-networking-cluster-network-operator" data-v-b883c74f>Cluster Network Operator in OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/dns-operator" id="sub-link-to-networking-dns-operator" data-v-b883c74f>DNS Operator in OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/configuring-ingress" id="sub-link-to-networking-configuring-ingress" data-v-b883c74f>Ingress Operator in OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/verifying-connectivity-endpoint" id="sub-link-to-networking-verifying-connectivity-endpoint" data-v-b883c74f>Verifying connectivity to an endpoint</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/configuring-node-port-service-range" id="sub-link-to-networking-configuring-node-port-service-range" data-v-b883c74f>Configuring the node port service range</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/configuring-ipfailover" id="sub-link-to-networking-configuring-ipfailover" data-v-b883c74f>Configuring IP failover</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/using-sctp" id="sub-link-to-networking-using-sctp" data-v-b883c74f>Using the Stream Control Transmission Protocol (SCTP) on a bare metal cluster</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/configuring-ptp" id="sub-link-to-networking-configuring-ptp" data-v-b883c74f>Configuring PTP hardware</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/network-policy" id="sub-link-to-networking-network-policy" data-v-b883c74f>Network policy</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/multiple-networks" id="sub-link-to-networking-multiple-networks" data-v-b883c74f>Multiple networks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/hardware-networks" id="sub-link-to-networking-hardware-networks" data-v-b883c74f>Hardware networks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/openshift-sdn-default-cni-network-provider" id="sub-link-to-networking-openshift-sdn-default-cni-network-provider" data-v-b883c74f>OpenShift SDN default CNI network provider</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/ovn-kubernetes-default-cni-network-provider" id="sub-link-to-networking-ovn-kubernetes-default-cni-network-provider" data-v-b883c74f>OVN-Kubernetes default CNI network provider</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/configuring-routes" id="sub-link-to-networking-configuring-routes" data-v-b883c74f>Configuring Routes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/configuring-ingress-cluster-traffic" id="sub-link-to-networking-configuring-ingress-cluster-traffic" data-v-b883c74f>Configuring ingress cluster traffic</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/kubernetes-nmstate" id="sub-link-to-networking-kubernetes-nmstate" data-v-b883c74f>Kubernetes NMState</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/enable-cluster-wide-proxy" id="sub-link-to-networking-enable-cluster-wide-proxy" data-v-b883c74f>Configuring the cluster-wide proxy</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/configuring-a-custom-pki" id="sub-link-to-networking-configuring-a-custom-pki" data-v-b883c74f>Configuring a custom PKI</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/load-balancing-openstack" id="sub-link-to-networking-load-balancing-openstack" data-v-b883c74f>Load balancing on RHOSP</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/networking/associating-secondary-interfaces-metrics-to-network-attachments" id="sub-link-to-networking-associating-secondary-interfaces-metrics-to-network-attachments" data-v-b883c74f>Associating secondary interfaces metrics to network attachments</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Registry</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/registry/index" id="chapter-landing--registry-index" data-v-b883c74f>Registry</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/registry/registry-overview" id="sub-link-to-registry-registry-overview" data-v-b883c74f>OpenShift Container Platform registry overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/registry/configuring-registry-operator" id="sub-link-to-registry-configuring-registry-operator" data-v-b883c74f>Image Registry Operator in OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/registry/setting-up-and-configuring-the-registry" id="sub-link-to-registry-setting-up-and-configuring-the-registry" data-v-b883c74f>Setting up and configuring the registry</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/registry/accessing-the-registry" id="sub-link-to-registry-accessing-the-registry" data-v-b883c74f>Accessing the registry</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/registry/securing-exposing-registry" id="sub-link-to-registry-securing-exposing-registry" data-v-b883c74f>Exposing the registry</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Post-installation configuration</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/index" id="chapter-landing--post-installation_configuration-index" data-v-b883c74f>Post-installation configuration</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-configuration-overview" id="sub-link-to-post-installation_configuration-post-install-configuration-overview" data-v-b883c74f>Post-installation configuration overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/configuring-private-cluster" id="sub-link-to-post-installation_configuration-configuring-private-cluster" data-v-b883c74f>Configuring a private cluster</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-machine-configuration-tasks" id="sub-link-to-post-installation_configuration-post-install-machine-configuration-tasks" data-v-b883c74f>Post-installation machine configuration tasks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-cluster-tasks" id="sub-link-to-post-installation_configuration-post-install-cluster-tasks" data-v-b883c74f>Post-installation cluster tasks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-node-tasks" id="sub-link-to-post-installation_configuration-post-install-node-tasks" data-v-b883c74f>Post-installation node tasks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-network-configuration" id="sub-link-to-post-installation_configuration-post-install-network-configuration" data-v-b883c74f>Post-installation network configuration</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-storage-configuration" id="sub-link-to-post-installation_configuration-post-install-storage-configuration" data-v-b883c74f>Post-installation storage configuration</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-preparing-for-users" id="sub-link-to-post-installation_configuration-post-install-preparing-for-users" data-v-b883c74f>Preparing for users</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/configuring-alert-notifications" id="sub-link-to-post-installation_configuration-configuring-alert-notifications" data-v-b883c74f>Configuring alert notifications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-configure-additional-devices-ibmz" id="sub-link-to-post-installation_configuration-post-install-configure-additional-devices-ibmz" data-v-b883c74f>Configuring additional devices in an IBM Z or LinuxONE environment</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Migrate</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Migrating from version 3 to 4</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/index" id="chapter-landing--migrating_from_version_3_to_4-index" data-v-b883c74f>Migrating from version 3 to 4</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/migration-from-version-3-to-4-overview" id="sub-link-to-migrating_from_version_3_to_4-migration-from-version-3-to-4-overview" data-v-b883c74f>Migration from OpenShift Container Platform 3 to 4 overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/about-migrating-from-3-to-4" id="sub-link-to-migrating_from_version_3_to_4-about-migrating-from-3-to-4" data-v-b883c74f>About migrating from OpenShift Container Platform 3 to 4</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/planning-migration-3-4" id="sub-link-to-migrating_from_version_3_to_4-planning-migration-3-4" data-v-b883c74f>Differences between OpenShift Container Platform 3 and 4</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/planning-considerations-3-4" id="sub-link-to-migrating_from_version_3_to_4-planning-considerations-3-4" data-v-b883c74f>Network considerations</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/about-mtc-3-4" id="sub-link-to-migrating_from_version_3_to_4-about-mtc-3-4" data-v-b883c74f>About the Migration Toolkit for Containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/installing-3-4" id="sub-link-to-migrating_from_version_3_to_4-installing-3-4" data-v-b883c74f>Installing the Migration Toolkit for Containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/installing-restricted-3-4" id="sub-link-to-migrating_from_version_3_to_4-installing-restricted-3-4" data-v-b883c74f>Installing the Migration Toolkit for Containers in a restricted network environment</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/upgrading-3-4" id="sub-link-to-migrating_from_version_3_to_4-upgrading-3-4" data-v-b883c74f>Upgrading the Migration Toolkit for Containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/premigration-checklists-3-4" id="sub-link-to-migrating_from_version_3_to_4-premigration-checklists-3-4" data-v-b883c74f>Premigration checklists</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/migrating-applications-3-4" id="sub-link-to-migrating_from_version_3_to_4-migrating-applications-3-4" data-v-b883c74f>Migrating your applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/advanced-migration-options-3-4" id="sub-link-to-migrating_from_version_3_to_4-advanced-migration-options-3-4" data-v-b883c74f>Advanced migration options</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/troubleshooting-3-4" id="sub-link-to-migrating_from_version_3_to_4-troubleshooting-3-4" data-v-b883c74f>Troubleshooting</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Migration Toolkit for Containers</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/index" id="chapter-landing--migration_toolkit_for_containers-index" data-v-b883c74f>Migration Toolkit for Containers</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/about-mtc" id="sub-link-to-migration_toolkit_for_containers-about-mtc" data-v-b883c74f>About the Migration Toolkit for Containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/mtc-release-notes" id="sub-link-to-migration_toolkit_for_containers-mtc-release-notes" data-v-b883c74f>Migration Toolkit for Containers release notes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/installing-mtc" id="sub-link-to-migration_toolkit_for_containers-installing-mtc" data-v-b883c74f>Installing the Migration Toolkit for Containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/installing-mtc-restricted" id="sub-link-to-migration_toolkit_for_containers-installing-mtc-restricted" data-v-b883c74f>Installing the Migration Toolkit for Containers in a restricted network environment</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/upgrading-mtc" id="sub-link-to-migration_toolkit_for_containers-upgrading-mtc" data-v-b883c74f>Upgrading the Migration Toolkit for Containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/premigration-checklists-mtc" id="sub-link-to-migration_toolkit_for_containers-premigration-checklists-mtc" data-v-b883c74f>Premigration checklists</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/network-considerations-mtc" id="sub-link-to-migration_toolkit_for_containers-network-considerations-mtc" data-v-b883c74f>Network considerations</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/migrating-applications-with-mtc" id="sub-link-to-migration_toolkit_for_containers-migrating-applications-with-mtc" data-v-b883c74f>Migrating your applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/advanced-migration-options-mtc" id="sub-link-to-migration_toolkit_for_containers-advanced-migration-options-mtc" data-v-b883c74f>Advanced migration options</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/troubleshooting-mtc" id="sub-link-to-migration_toolkit_for_containers-troubleshooting-mtc" data-v-b883c74f>Troubleshooting</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Manage</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Backup and restore</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/backup_and_restore/index" id="chapter-landing--backup_and_restore-index" data-v-b883c74f>Backup and restore</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/backup_and_restore/backup-restore-overview" id="sub-link-to-backup_and_restore-backup-restore-overview" data-v-b883c74f>Backup and restore</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/backup_and_restore/graceful-shutdown-cluster" id="sub-link-to-backup_and_restore-graceful-shutdown-cluster" data-v-b883c74f>Shutting down the cluster gracefully</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/backup_and_restore/graceful-restart-cluster" id="sub-link-to-backup_and_restore-graceful-restart-cluster" data-v-b883c74f>Restarting the cluster gracefully</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/backup_and_restore/application-backup-and-restore" id="sub-link-to-backup_and_restore-application-backup-and-restore" data-v-b883c74f>Application backup and restore</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/backup_and_restore/control-plane-backup-and-restore" id="sub-link-to-backup_and_restore-control-plane-backup-and-restore" data-v-b883c74f>Control plane backup and restore</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Machine management</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/index" id="chapter-landing--machine_management-index" data-v-b883c74f>Machine management</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/overview-of-machine-management" id="sub-link-to-machine_management-overview-of-machine-management" data-v-b883c74f>Overview of machine management</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/creating-machine-sets" id="sub-link-to-machine_management-creating-machine-sets" data-v-b883c74f>Creating machine sets</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/manually-scaling-machineset" id="sub-link-to-machine_management-manually-scaling-machineset" data-v-b883c74f>Manually scaling a machine set</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/modifying-machineset" id="sub-link-to-machine_management-modifying-machineset" data-v-b883c74f>Modifying a machine set</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/deleting-machine" id="sub-link-to-machine_management-deleting-machine" data-v-b883c74f>Deleting a machine</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/applying-autoscaling" id="sub-link-to-machine_management-applying-autoscaling" data-v-b883c74f>Applying autoscaling to an OpenShift Container Platform cluster</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/creating-infrastructure-machinesets" id="sub-link-to-machine_management-creating-infrastructure-machinesets" data-v-b883c74f>Creating infrastructure machine sets</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/adding-rhel-compute" id="sub-link-to-machine_management-adding-rhel-compute" data-v-b883c74f>Adding RHEL compute machines to an OpenShift Container Platform cluster</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/more-rhel-compute" id="sub-link-to-machine_management-more-rhel-compute" data-v-b883c74f>Adding more RHEL compute machines to an OpenShift Container Platform cluster</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/user-provisioned-infrastructure-2" id="sub-link-to-machine_management-user-provisioned-infrastructure-2" data-v-b883c74f>User-provisioned infrastructure</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/machine_management/deploying-machine-health-checks" id="sub-link-to-machine_management-deploying-machine-health-checks" data-v-b883c74f>Deploying machine health checks</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Metering</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/metering/index" id="chapter-landing--metering-index" data-v-b883c74f>Metering</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/about-metering" id="sub-link-to-metering-about-metering" data-v-b883c74f>About Metering</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/installing-metering" id="sub-link-to-metering-installing-metering" data-v-b883c74f>Installing metering</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/upgrading-metering" id="sub-link-to-metering-upgrading-metering" data-v-b883c74f>Upgrading metering</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/configuring-metering" id="sub-link-to-metering-configuring-metering" data-v-b883c74f>Configuring metering</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/reports" id="sub-link-to-metering-reports" data-v-b883c74f>Reports</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/using-metering" id="sub-link-to-metering-using-metering" data-v-b883c74f>Using Metering</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/metering-usage-examples" id="sub-link-to-metering-metering-usage-examples" data-v-b883c74f>Examples of using metering</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/metering-troubleshooting-debugging" id="sub-link-to-metering-metering-troubleshooting-debugging" data-v-b883c74f>Troubleshooting and debugging metering</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/metering/metering-uninstall" id="sub-link-to-metering-metering-uninstall" data-v-b883c74f>Uninstalling metering</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Web console</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/web_console/index" id="chapter-landing--web_console-index" data-v-b883c74f>Web console</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/web-console-overview" id="sub-link-to-web_console-web-console-overview" data-v-b883c74f>Web Console Overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/web-console" id="sub-link-to-web_console-web-console" data-v-b883c74f>Accessing the web console</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/using-dashboard-to-get-cluster-info" id="sub-link-to-web_console-using-dashboard-to-get-cluster-info" data-v-b883c74f>Using the OpenShift Container Platform dashboard to get cluster information</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/configuring-web-console" id="sub-link-to-web_console-configuring-web-console" data-v-b883c74f>Configuring the web console in OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/customizing-web-console" id="sub-link-to-web_console-customizing-web-console" data-v-b883c74f>Customizing the web console in OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/odc-about-web-terminal" id="sub-link-to-web_console-odc-about-web-terminal" data-v-b883c74f>About the web terminal in the web console</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/disabling-web-console" id="sub-link-to-web_console-disabling-web-console" data-v-b883c74f>Disabling the web console in OpenShift Container Platform</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/web_console/creating-quick-start-tutorials" id="sub-link-to-web_console-creating-quick-start-tutorials" data-v-b883c74f>Creating quick start tutorials in the web console</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Reference</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>CLI tools</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/index" id="chapter-landing--cli_tools-index" data-v-b883c74f>CLI tools</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/cli-tools-overview" id="sub-link-to-cli_tools-cli-tools-overview" data-v-b883c74f>OpenShift Container Platform CLI tools overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/openshift-cli-oc" id="sub-link-to-cli_tools-openshift-cli-oc" data-v-b883c74f>OpenShift CLI (oc)</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/developer-cli-odo" id="sub-link-to-cli_tools-developer-cli-odo" data-v-b883c74f>Developer CLI (odo)</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/kn-cli-tools" id="sub-link-to-cli_tools-kn-cli-tools" data-v-b883c74f>Knative CLI for use with OpenShift Serverless</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/pipelines-cli-tkn" id="sub-link-to-cli_tools-pipelines-cli-tkn" data-v-b883c74f>Pipelines CLI (tkn)</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/opm-cli" id="sub-link-to-cli_tools-opm-cli" data-v-b883c74f>opm CLI</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cli_tools/operator-sdk" id="sub-link-to-cli_tools-operator-sdk" data-v-b883c74f>Operator SDK</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Develop</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Building Applications</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/index" id="chapter-landing--building_applications-index" data-v-b883c74f>Building Applications</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/building-applications-overview" id="sub-link-to-building_applications-building-applications-overview" data-v-b883c74f>Building applications overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/projects" id="sub-link-to-building_applications-projects" data-v-b883c74f>Projects</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/creating-applications" id="sub-link-to-building_applications-creating-applications" data-v-b883c74f>Creating Applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/odc-viewing-application-composition-using-topology-view" id="sub-link-to-building_applications-odc-viewing-application-composition-using-topology-view" data-v-b883c74f>Viewing application composition using the Topology view</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/working-with-helm-charts" id="sub-link-to-building_applications-working-with-helm-charts" data-v-b883c74f>Working with Helm charts</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/deployments" id="sub-link-to-building_applications-deployments" data-v-b883c74f>Deployments</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/quotas" id="sub-link-to-building_applications-quotas" data-v-b883c74f>Quotas</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/config-maps" id="sub-link-to-building_applications-config-maps" data-v-b883c74f>Using config maps with applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/odc-monitoring-project-and-application-metrics-using-developer-perspective" id="sub-link-to-building_applications-odc-monitoring-project-and-application-metrics-using-developer-perspective" data-v-b883c74f>Monitoring project and application metrics using the Developer perspective</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/application-health" id="sub-link-to-building_applications-application-health" data-v-b883c74f>Monitoring application health by using health checks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/odc-editing-applications" id="sub-link-to-building_applications-odc-editing-applications" data-v-b883c74f>Editing applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/pruning-objects" id="sub-link-to-building_applications-pruning-objects" data-v-b883c74f>Pruning objects to reclaim resources</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/idling-applications" id="sub-link-to-building_applications-idling-applications" data-v-b883c74f>Idling applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/odc-deleting-applications" id="sub-link-to-building_applications-odc-deleting-applications" data-v-b883c74f>Deleting applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/building_applications/red-hat-marketplace" id="sub-link-to-building_applications-red-hat-marketplace" data-v-b883c74f>Using the Red Hat Marketplace</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>CI/CD</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/cicd/index" id="chapter-landing--cicd-index" data-v-b883c74f>CI/CD</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cicd/ci-cd-overview" id="sub-link-to-cicd-ci-cd-overview" data-v-b883c74f>OpenShift Container Platform CI/CD overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cicd/builds" id="sub-link-to-cicd-builds" data-v-b883c74f>Builds</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cicd/migrating-from-jenkins-to-tekton" id="sub-link-to-cicd-migrating-from-jenkins-to-tekton" data-v-b883c74f>Migrating from Jenkins to Tekton</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cicd/pipelines" id="sub-link-to-cicd-pipelines" data-v-b883c74f>Pipelines</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/cicd/gitops" id="sub-link-to-cicd-gitops" data-v-b883c74f>GitOps</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Images</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/images/index" id="chapter-landing--images-index" data-v-b883c74f>Images</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/overview-of-images" id="sub-link-to-images-overview-of-images" data-v-b883c74f>Overview of images</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/configuring-samples-operator" id="sub-link-to-images-configuring-samples-operator" data-v-b883c74f>Configuring the Cluster Samples Operator</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/samples-operator-alt-registry" id="sub-link-to-images-samples-operator-alt-registry" data-v-b883c74f>Using the Cluster Samples Operator with an alternate registry</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/creating-images" id="sub-link-to-images-creating-images" data-v-b883c74f>Creating images</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/managing-images" id="sub-link-to-images-managing-images" data-v-b883c74f>Managing images</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/managing-image-streams" id="sub-link-to-images-managing-image-streams" data-v-b883c74f>Managing image streams</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/using-imagestreams-with-kube-resources" id="sub-link-to-images-using-imagestreams-with-kube-resources" data-v-b883c74f>Using image streams with Kubernetes resources</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/triggering-updates-on-imagestream-changes" id="sub-link-to-images-triggering-updates-on-imagestream-changes" data-v-b883c74f>Triggering updates on image stream changes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/image-configuration" id="sub-link-to-images-image-configuration" data-v-b883c74f>Image configuration resources</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/using-templates" id="sub-link-to-images-using-templates" data-v-b883c74f>Using templates</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/templates-using-ruby-on-rails" id="sub-link-to-images-templates-using-ruby-on-rails" data-v-b883c74f>Using Ruby on Rails</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/images/using-images" id="sub-link-to-images-using-images" data-v-b883c74f>Using images</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Nodes</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/nodes/index" id="chapter-landing--nodes-index" data-v-b883c74f>Nodes</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/overview-of-nodes" id="sub-link-to-nodes-overview-of-nodes" data-v-b883c74f>Overview of nodes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/working-with-pods" id="sub-link-to-nodes-working-with-pods" data-v-b883c74f>Working with pods</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/controlling-pod-placement-onto-nodes-scheduling" id="sub-link-to-nodes-controlling-pod-placement-onto-nodes-scheduling" data-v-b883c74f>Controlling pod placement onto nodes (scheduling)</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/using-jobs-and-daemonsets" id="sub-link-to-nodes-using-jobs-and-daemonsets" data-v-b883c74f>Using Jobs and DaemonSets</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/working-with-nodes" id="sub-link-to-nodes-working-with-nodes" data-v-b883c74f>Working with nodes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/working-with-containers" id="sub-link-to-nodes-working-with-containers" data-v-b883c74f>Working with containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/working-with-clusters" id="sub-link-to-nodes-working-with-clusters" data-v-b883c74f>Working with clusters</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/nodes/remote-worker-nodes-on-the-network-edge" id="sub-link-to-nodes-remote-worker-nodes-on-the-network-edge" data-v-b883c74f>Remote worker nodes on the network edge</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Sandboxed Containers Support for OpenShift</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/index" id="chapter-landing--sandboxed_containers_support_for_openshift-index" data-v-b883c74f>Sandboxed Containers Support for OpenShift</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/sandboxed-containers-4-8-release-notes" id="sub-link-to-sandboxed_containers_support_for_openshift-sandboxed-containers-4-8-release-notes" data-v-b883c74f>{sandboxed-containers-first} 1.0 release notes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/understanding-sandboxed-containers" id="sub-link-to-sandboxed_containers_support_for_openshift-understanding-sandboxed-containers" data-v-b883c74f>Understanding OpenShift sandboxed containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/deploying-sandboxed-containers-workloads" id="sub-link-to-sandboxed_containers_support_for_openshift-deploying-sandboxed-containers-workloads" data-v-b883c74f>Deploying OpenShift sandboxed containers workloads</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/uninstalling-sandboxed-containers" id="sub-link-to-sandboxed_containers_support_for_openshift-uninstalling-sandboxed-containers" data-v-b883c74f>Uninstalling OpenShift sandboxed containers</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/upgrade-sandboxed-containers" id="sub-link-to-sandboxed_containers_support_for_openshift-upgrade-sandboxed-containers" data-v-b883c74f>Upgrade OpenShift sandboxed containers</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Operators</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/operators/index" id="chapter-landing--operators-index" data-v-b883c74f>Operators</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/operators/operators-overview" id="sub-link-to-operators-operators-overview" data-v-b883c74f>Operators overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/operators/understanding-operators" id="sub-link-to-operators-understanding-operators" data-v-b883c74f>Understanding Operators</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/operators/user-tasks" id="sub-link-to-operators-user-tasks" data-v-b883c74f>User tasks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/operators/administrator-tasks" id="sub-link-to-operators-administrator-tasks" data-v-b883c74f>Administrator tasks</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title active" href="/en/documentation/openshift_container_platform/4.8/html/operators/developing-operators" id="sub-link-to-operators-developing-operators" data-v-b883c74f>Developing Operators</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/operators/cluster-operators-ref" id="sub-link-to-operators-cluster-operators-ref" data-v-b883c74f>Cluster Operators reference</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Monitor</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Logging</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/logging/index" id="chapter-landing--logging-index" data-v-b883c74f>Logging</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/release-notes" id="sub-link-to-logging-release-notes" data-v-b883c74f>Release notes for Logging</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging" id="sub-link-to-logging-cluster-logging" data-v-b883c74f>Understanding Red Hat OpenShift Logging</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-deploying" id="sub-link-to-logging-cluster-logging-deploying" data-v-b883c74f>Installing OpenShift Logging</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/configuring-your-logging-deployment" id="sub-link-to-logging-configuring-your-logging-deployment" data-v-b883c74f>Configuring your Logging deployment</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/vewing-resource-logs" id="sub-link-to-logging-vewing-resource-logs" data-v-b883c74f>Viewing logs for a resource</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-visualizer-using" id="sub-link-to-logging-cluster-logging-visualizer-using" data-v-b883c74f>Viewing cluster logs by using Kibana</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-external" id="sub-link-to-logging-cluster-logging-external" data-v-b883c74f>Forwarding logs to external third-party logging systems</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-enabling-json-logging" id="sub-link-to-logging-cluster-logging-enabling-json-logging" data-v-b883c74f>Enabling JSON logging</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-eventrouter" id="sub-link-to-logging-cluster-logging-eventrouter" data-v-b883c74f>Collecting and storing Kubernetes events</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-upgrading" id="sub-link-to-logging-cluster-logging-upgrading" data-v-b883c74f>Updating OpenShift Logging</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-dashboards" id="sub-link-to-logging-cluster-logging-dashboards" data-v-b883c74f>Viewing cluster dashboards</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/troubleshooting-logging" id="sub-link-to-logging-troubleshooting-logging" data-v-b883c74f>Troubleshooting Logging</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-uninstall" id="sub-link-to-logging-cluster-logging-uninstall" data-v-b883c74f>Uninstalling OpenShift Logging</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-exported-fields" id="sub-link-to-logging-cluster-logging-exported-fields" data-v-b883c74f>Log Record Fields</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/message" id="sub-link-to-logging-message" data-v-b883c74f>message</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/structured" id="sub-link-to-logging-structured" data-v-b883c74f>structured</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/timestamp" id="sub-link-to-logging-timestamp" data-v-b883c74f>@timestamp</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/hostname" id="sub-link-to-logging-hostname" data-v-b883c74f>hostname</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/ipaddr4" id="sub-link-to-logging-ipaddr4" data-v-b883c74f>ipaddr4</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/ipaddr6" id="sub-link-to-logging-ipaddr6" data-v-b883c74f>ipaddr6</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/level" id="sub-link-to-logging-level" data-v-b883c74f>level</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/pid" id="sub-link-to-logging-pid" data-v-b883c74f>pid</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/service" id="sub-link-to-logging-service" data-v-b883c74f>service</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/tags" id="sub-link-to-logging-tags" data-v-b883c74f>tags</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/file" id="sub-link-to-logging-file" data-v-b883c74f>file</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/offset" id="sub-link-to-logging-offset" data-v-b883c74f>offset</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-exported-fields-kubernetes_cluster-logging-exported-fields" id="sub-link-to-logging-cluster-logging-exported-fields-kubernetes_cluster-logging-exported-fields" data-v-b883c74f>kubernetes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/logging/openshift" id="sub-link-to-logging-openshift" data-v-b883c74f>OpenShift</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Monitoring</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/index" id="chapter-landing--monitoring-index" data-v-b883c74f>Monitoring</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/monitoring-overview" id="sub-link-to-monitoring-monitoring-overview" data-v-b883c74f>Monitoring overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/configuring-the-monitoring-stack" id="sub-link-to-monitoring-configuring-the-monitoring-stack" data-v-b883c74f>Configuring the monitoring stack</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/enabling-monitoring-for-user-defined-projects" id="sub-link-to-monitoring-enabling-monitoring-for-user-defined-projects" data-v-b883c74f>Enabling monitoring for user-defined projects</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/managing-metrics" id="sub-link-to-monitoring-managing-metrics" data-v-b883c74f>Managing metrics</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/managing-alerts" id="sub-link-to-monitoring-managing-alerts" data-v-b883c74f>Managing alerts</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/reviewing-monitoring-dashboards" id="sub-link-to-monitoring-reviewing-monitoring-dashboards" data-v-b883c74f>Reviewing monitoring dashboards</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/accessing-third-party-uis" id="sub-link-to-monitoring-accessing-third-party-uis" data-v-b883c74f>Accessing third-party UIs</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/monitoring/troubleshooting-monitoring-issues" id="sub-link-to-monitoring-troubleshooting-monitoring-issues" data-v-b883c74f>Troubleshooting monitoring issues</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Scalability and performance</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/index" id="chapter-landing--scalability_and_performance-index" data-v-b883c74f>Scalability and performance</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/recommended-host-practices" id="sub-link-to-scalability_and_performance-recommended-host-practices" data-v-b883c74f>Recommended host practices</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/ibm-z-recommended-host-practices" id="sub-link-to-scalability_and_performance-ibm-z-recommended-host-practices" data-v-b883c74f>Recommended host practices for IBM Z &amp; LinuxONE environments</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/recommended-cluster-scaling-practices" id="sub-link-to-scalability_and_performance-recommended-cluster-scaling-practices" data-v-b883c74f>Recommended cluster scaling practices</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using-node-tuning-operator" id="sub-link-to-scalability_and_performance-using-node-tuning-operator" data-v-b883c74f>Using the Node Tuning Operator</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using_cluster_loader_node-tuning-operator" id="sub-link-to-scalability_and_performance-using_cluster_loader_node-tuning-operator" data-v-b883c74f>Using Cluster Loader</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using-cpu-manager" id="sub-link-to-scalability_and_performance-using-cpu-manager" data-v-b883c74f>Using CPU Manager</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using-topology-manager" id="sub-link-to-scalability_and_performance-using-topology-manager" data-v-b883c74f>Using Topology Manager</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/scaling-cluster-monitoring-operator" id="sub-link-to-scalability_and_performance-scaling-cluster-monitoring-operator" data-v-b883c74f>Scaling the Cluster Monitoring Operator</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/node-feature-discovery-operator" id="sub-link-to-scalability_and_performance-node-feature-discovery-operator" data-v-b883c74f>The Node Feature Discovery Operator</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/driver-toolkit" id="sub-link-to-scalability_and_performance-driver-toolkit" data-v-b883c74f>The Driver Toolkit</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/planning-your-environment-according-to-object-maximums" id="sub-link-to-scalability_and_performance-planning-your-environment-according-to-object-maximums" data-v-b883c74f>Planning your environment according to object maximums</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/optimizing-storage" id="sub-link-to-scalability_and_performance-optimizing-storage" data-v-b883c74f>Optimizing storage</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/routing-optimization" id="sub-link-to-scalability_and_performance-routing-optimization" data-v-b883c74f>Optimizing routing</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/optimizing-networking" id="sub-link-to-scalability_and_performance-optimizing-networking" data-v-b883c74f>Optimizing networking</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/managing-bare-metal-hosts" id="sub-link-to-scalability_and_performance-managing-bare-metal-hosts" data-v-b883c74f>Managing bare metal hosts</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/what-huge-pages-do-and-how-they-are-consumed" id="sub-link-to-scalability_and_performance-what-huge-pages-do-and-how-they-are-consumed" data-v-b883c74f>What huge pages do and how they are consumed by applications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/cnf-performance-addon-operator-for-low-latency-nodes" id="sub-link-to-scalability_and_performance-cnf-performance-addon-operator-for-low-latency-nodes" data-v-b883c74f>Performance Addon Operator for low latency nodes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/cnf-performing-platform-verification-latency-tests" id="sub-link-to-scalability_and_performance-cnf-performing-platform-verification-latency-tests" data-v-b883c74f>Performing latency tests for platform verification</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/scalability_and_performance/cnf-create-performance-profiles" id="sub-link-to-scalability_and_performance-cnf-create-performance-profiles" data-v-b883c74f>Creating a performance profile</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Support</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/support/index" id="chapter-landing--support-index" data-v-b883c74f>Support</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/support/support-overview" id="sub-link-to-support-support-overview" data-v-b883c74f>Support overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/support/managing-cluster-resources" id="sub-link-to-support-managing-cluster-resources" data-v-b883c74f>Managing your cluster resources</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/support/getting-support" id="sub-link-to-support-getting-support" data-v-b883c74f>Getting support</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/support/remote-health-monitoring-with-connected-clusters" id="sub-link-to-support-remote-health-monitoring-with-connected-clusters" data-v-b883c74f>Remote health monitoring with connected clusters</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/support/gathering-cluster-data" id="sub-link-to-support-gathering-cluster-data" data-v-b883c74f>Gathering data about your cluster</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/support/summarizing-cluster-specifications" id="sub-link-to-support-summarizing-cluster-specifications" data-v-b883c74f>Summarizing cluster specifications</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/support/troubleshooting" id="sub-link-to-support-troubleshooting" data-v-b883c74f>Troubleshooting</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><details id="toc--undefined" data-v-fa0dae77><summary class="heading chapter-title" id="undefined--summary" data-v-fa0dae77>Integration</summary><ol class="sub-nav" data-v-fa0dae77><!----><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Service Mesh</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/service_mesh/index" id="chapter-landing--service_mesh-index" data-v-b883c74f>Service Mesh</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/service_mesh/service-mesh-2-x" id="sub-link-to-service_mesh-service-mesh-2-x" data-v-b883c74f>Service Mesh 2.x</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/service_mesh/service-mesh-1-x" id="sub-link-to-service_mesh-service-mesh-1-x" data-v-b883c74f>Service Mesh 1.x</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Distributed tracing</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/distributed_tracing/index" id="chapter-landing--distributed_tracing-index" data-v-b883c74f>Distributed tracing</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/distributed_tracing/distr-tracing-release-notes" id="sub-link-to-distributed_tracing-distr-tracing-release-notes" data-v-b883c74f>Distributed tracing release notes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/distributed_tracing/distributed-tracing-architecture" id="sub-link-to-distributed_tracing-distributed-tracing-architecture" data-v-b883c74f>Distributed tracing architecture</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/distributed_tracing/distributed-tracing-installation" id="sub-link-to-distributed_tracing-distributed-tracing-installation" data-v-b883c74f>Distributed tracing installation</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Serverless</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/serverless/index" id="chapter-landing--serverless-index" data-v-b883c74f>Serverless</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/serverless-release-notes" id="sub-link-to-serverless-serverless-release-notes" data-v-b883c74f>Release notes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/discover" id="sub-link-to-serverless-discover" data-v-b883c74f>Discover</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/install" id="sub-link-to-serverless-install" data-v-b883c74f>Install</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/knative-cli" id="sub-link-to-serverless-knative-cli" data-v-b883c74f>Knative CLI</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/develop" id="sub-link-to-serverless-develop" data-v-b883c74f>Develop</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/administer" id="sub-link-to-serverless-administer" data-v-b883c74f>Administer</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/monitor" id="sub-link-to-serverless-monitor" data-v-b883c74f>Monitor</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/serverless-tracing" id="sub-link-to-serverless-serverless-tracing" data-v-b883c74f>Tracing requests</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/serverless-support" id="sub-link-to-serverless-serverless-support" data-v-b883c74f>OpenShift Serverless support</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/security" id="sub-link-to-serverless-security" data-v-b883c74f>Security</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/functions" id="sub-link-to-serverless-functions" data-v-b883c74f>Functions</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/serverless/integrations" id="sub-link-to-serverless-integrations" data-v-b883c74f>Integrations</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>OpenShift Virtualization</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/index" id="chapter-landing--openshift_virtualization-index" data-v-b883c74f>OpenShift Virtualization</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/about-virt" id="sub-link-to-openshift_virtualization-about-virt" data-v-b883c74f>About OpenShift Virtualization</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/start-here-with-openshift-virtualization" id="sub-link-to-openshift_virtualization-start-here-with-openshift-virtualization" data-v-b883c74f>Start here with OpenShift Virtualization</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/openshift-virtualization-release-notes" id="sub-link-to-openshift_virtualization-openshift-virtualization-release-notes" data-v-b883c74f>OpenShift Virtualization release notes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/installing-openshift-virtualization" id="sub-link-to-openshift_virtualization-installing-openshift-virtualization" data-v-b883c74f>Installing OpenShift Virtualization</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/upgrading-openshift-virtualization" id="sub-link-to-openshift_virtualization-upgrading-openshift-virtualization" data-v-b883c74f>Updating OpenShift Virtualization</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virt-additional-security-privileges-controller-and-launcher" id="sub-link-to-openshift_virtualization-virt-additional-security-privileges-controller-and-launcher" data-v-b883c74f>Additional security privileges granted for kubevirt-controller and virt-launcher</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virt-using-the-cli-tools" id="sub-link-to-openshift_virtualization-virt-using-the-cli-tools" data-v-b883c74f>Using the CLI tools</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virtual-machines" id="sub-link-to-openshift_virtualization-virtual-machines" data-v-b883c74f>Virtual machines</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virtual-machine-templates" id="sub-link-to-openshift_virtualization-virtual-machine-templates" data-v-b883c74f>Virtual machine templates</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/live-migration" id="sub-link-to-openshift_virtualization-live-migration" data-v-b883c74f>Live migration</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/node-maintenance" id="sub-link-to-openshift_virtualization-node-maintenance" data-v-b883c74f>Node maintenance</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/node-networking" id="sub-link-to-openshift_virtualization-node-networking" data-v-b883c74f>Node networking</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/openshift_virtualization/logging-events-and-monitoring" id="sub-link-to-openshift_virtualization-logging-events-and-monitoring" data-v-b883c74f>Logging, events, and monitoring</a></li><!--]--><!--]--></ol></details></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><details id="nested-toc--null" data-v-b883c74f><summary class="heading sub-chapter-title" id="null--summary" data-v-b883c74f>Windows Container Support for OpenShift</summary><ol id="sub-nav--null" class="sub-nav" data-v-b883c74f><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title chapter-landing-page" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/index" id="chapter-landing--windows_container_support_for_openshift-index" data-v-b883c74f>Windows Container Support for OpenShift</a></li><!--[--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/windows-container-overview" id="sub-link-to-windows_container_support_for_openshift-windows-container-overview" data-v-b883c74f>Red Hat OpenShift support for Windows Containers overview</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/windows-containers-release-notes-3-x" id="sub-link-to-windows_container_support_for_openshift-windows-containers-release-notes-3-x" data-v-b883c74f>Windows Container Support for Red Hat OpenShift release notes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/understanding-windows-container-workloads" id="sub-link-to-windows_container_support_for_openshift-understanding-windows-container-workloads" data-v-b883c74f>Understanding Windows container workloads</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/enabling-windows-container-workloads" id="sub-link-to-windows_container_support_for_openshift-enabling-windows-container-workloads" data-v-b883c74f>Enabling Windows container workloads</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/creating-windows-machineset-objects" id="sub-link-to-windows_container_support_for_openshift-creating-windows-machineset-objects" data-v-b883c74f>Creating Windows MachineSet objects</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/scheduling-windows-workloads" id="sub-link-to-windows_container_support_for_openshift-scheduling-windows-workloads" data-v-b883c74f>Scheduling Windows container workloads</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/windows-node-upgrades" id="sub-link-to-windows_container_support_for_openshift-windows-node-upgrades" data-v-b883c74f>Windows node upgrades</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/byoh-windows-instance" id="sub-link-to-windows_container_support_for_openshift-byoh-windows-instance" data-v-b883c74f>Using Bring-Your-Own-Host (BYOH) Windows instances as nodes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/removing-windows-nodes" id="sub-link-to-windows_container_support_for_openshift-removing-windows-nodes" data-v-b883c74f>Removing Windows nodes</a></li><!--]--><!--[--><li class="item sub-chapter" data-v-b883c74f><a class="link sub-chapter-title" href="/en/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/disabling-windows-container-workloads" id="sub-link-to-windows_container_support_for_openshift-disabling-windows-container-workloads" data-v-b883c74f>Disabling Windows container workloads</a></li><!--]--><!--]--></ol></details></li><!--]--><!--]--></ol></details></li><li class="item chapter" data-v-fa0dae77><a class="link" href="/en/documentation/openshift_container_platform/4.8/html/operators/legal-notice" id="chapter-landing--operators-legal-notice" data-v-fa0dae77>Legal Notice</a></li><!--]--></ol></nav><!----></div></div></aside><article class="content span-xs-12 span-sm-6 span-md-12 span-lg-7" aria-live="polite" data-v-8589d091><!----><div lang="en-us" xml:lang="en-us" class="docs-ocp-content-container docs-content-container" data-v-8589d091><!----><!----><h1 data-id="content_chapter" class="chapter-title" data-v-8589d091>Chapter 5. Developing Operators</h1><hr class="line-below-chp" data-v-8589d091><section class="rhdocs" data-v-8589d091><body><section class="chapter" id="developing-operators"><section class="section" id="osdk-about"><div class="titlepage"><div><div><h2 class="title">5.1. About the Operator SDK</h2></div></div></div><p> The <a class="link" href="https://operatorframework.io/">Operator Framework</a> is an open source toolkit to manage Kubernetes native applications, called <span class="emphasis"><em>Operators</em></span>, in an effective, automated, and scalable way. Operators take advantage of Kubernetes extensibility to deliver the automation advantages of cloud services, like provisioning, scaling, and backup and restore, while being able to run anywhere that Kubernetes can run. </p><p> Operators make it easy to manage complex, stateful applications on top of Kubernetes. However, writing an Operator today can be difficult because of challenges such as using low-level APIs, writing boilerplate, and a lack of modularity, which leads to duplication. </p><p> The Operator SDK, a component of the Operator Framework, provides a command-line interface (CLI) tool that Operator developers can use to build, test, and deploy an Operator. </p><p> <span class="strong strong"><strong>Why use the Operator SDK?</strong></span> </p><p> The Operator SDK simplifies this process of building Kubernetes-native applications, which can require deep, application-specific operational knowledge. The Operator SDK not only lowers that barrier, but it also helps reduce the amount of boilerplate code required for many common management capabilities, such as metering or monitoring. </p><p> The Operator SDK is a framework that uses the <a class="link" href="https://github.com/kubernetes-sigs/controller-runtime">controller-runtime</a> library to make writing Operators easier by providing the following features: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> High-level APIs and abstractions to write the operational logic more intuitively </li><li class="listitem"> Tools for scaffolding and code generation to quickly bootstrap a new project </li><li class="listitem"> Integration with Operator Lifecycle Manager (OLM) to streamline packaging, installing, and running Operators on a cluster </li><li class="listitem"> Extensions to cover common Operator use cases </li><li class="listitem"> Metrics set up automatically in any generated Go-based Operator for use on clusters where the Prometheus Operator is deployed </li></ul></div><p> Operator authors with cluster administrator access to a Kubernetes-based cluster (such as OpenShift Container Platform) can use the Operator SDK CLI to develop their own Operators based on Go, Ansible, or Helm. <a class="link" href="https://kubebuilder.io/">Kubebuilder</a> is embedded into the Operator SDK as the scaffolding solution for Go-based Operators, which means existing Kubebuilder projects can be used as is with the Operator SDK and continue to work. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> OpenShift Container Platform 4.8 supports Operator SDK v1.8.0 or later. </p></div></rh-alert><section class="section" id="osdk-about-what-are-operators"><div class="titlepage"><div><div><h3 class="title">5.1.1. What are Operators?</h3></div></div></div><p> For an overview about basic Operator concepts and terminology, see <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-what-operators-are">Understanding Operators</a>. </p></section><section class="section" id="osdk-workflow_osdk-about"><div class="titlepage"><div><div><h3 class="title">5.1.2. Development workflow</h3></div></div></div><p> The Operator SDK provides the following workflow to develop a new Operator: </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> Create an Operator project by using the Operator SDK command-line interface (CLI). </li><li class="listitem"> Define new resource APIs by adding custom resource definitions (CRDs). </li><li class="listitem"> Specify resources to watch by using the Operator SDK API. </li><li class="listitem"> Define the Operator reconciling logic in a designated handler and use the Operator SDK API to interact with resources. </li><li class="listitem"> Use the Operator SDK CLI to build and generate the Operator deployment manifests. </li></ol></div><div class="figure" id="idm140209515070576"><p class="title"><strong>Figure 5.1. Operator SDK workflow</strong></p><div class="figure-contents"><div class="mediaobject"><img src="https://access.redhat.com/webassets/avalon/d/OpenShift_Container_Platform-4.8-Operators-en-US/images/455883d59723ffcc9b05b9a4d4d0503c/osdk-workflow.png" alt="osdk workflow"></div></div></div><p> At a high level, an Operator that uses the Operator SDK processes events for watched resources in an Operator author-defined handler and takes actions to reconcile the state of the application. </p></section><section class="section _additional-resources" id="osdk-about-addtl-resources"><div class="titlepage"><div><div><h3 class="title">5.1.3. Additional resources</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://redhat-connect.gitbook.io/certified-operator-guide/">Certified Operator Build Guide</a> </li></ul></div></section></section><section class="section" id="osdk-installing-cli"><div class="titlepage"><div><div><h2 class="title">5.2. Installing the Operator SDK CLI</h2></div></div></div><p> The Operator SDK provides a command-line interface (CLI) tool that Operator developers can use to build, test, and deploy an Operator. You can install the Operator SDK CLI on your workstation so that you are prepared to start authoring your own Operators. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> OpenShift Container Platform 4.8 supports Operator SDK v1.8.0. </p></div></rh-alert><section class="section" id="osdk-installing-cli-linux-macos_osdk-installing-cli"><div class="titlepage"><div><div><h3 class="title">5.2.1. Installing the Operator SDK CLI</h3></div></div></div><p> You can install the OpenShift SDK CLI tool on Linux. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://golang.org/dl/">Go</a> v1.16+ </li><li class="listitem"> <code class="literal">docker</code> v17.03+, <code class="literal">podman</code> v1.9.3+, or <code class="literal">buildah</code> v1.7+ </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"> Navigate to the <a class="link" href="https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/operator-sdk/4.8.4/">OpenShift mirror site</a>. </li><li class="listitem"> From the <code class="literal">4.8.4</code> directory, download the latest version of the tarball for Linux. </li><li class="listitem"><p class="simpara"> Unpack the archive: </p><pre class="programlisting language-terminal">$ tar xvf operator-sdk-v1.8.0-ocp-linux-x86_64.tar.gz</pre></li><li class="listitem"><p class="simpara"> Make the file executable: </p><pre class="programlisting language-terminal">$ chmod +x operator-sdk</pre></li><li class="listitem"><p class="simpara"> Move the extracted <code class="literal">operator-sdk</code> binary to a directory that is on your <code class="literal">PATH</code>. </p><rh-alert class="admonition tip" state="info"><div class="admonition_header" slot="header">Tip</div><div><p> To check your <code class="literal">PATH</code>: </p><pre class="programlisting language-terminal">$ echo $PATH</pre></div></rh-alert><pre class="programlisting language-terminal">$ sudo mv ./operator-sdk /usr/local/bin/operator-sdk</pre></li></ol></div><div class="itemizedlist"><p class="title"><strong>Verification</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> After you install the Operator SDK CLI, verify that it is available: </p><pre class="programlisting language-terminal">$ operator-sdk version</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">operator-sdk version: "v1.8.0-ocp", ...</pre> <p></p></div></li></ul></div></section></section><section class="section" id="osdk-upgrading-projects"><div class="titlepage"><div><div><h2 class="title">5.3. Upgrading projects for newer Operator SDK versions</h2></div></div></div><p> OpenShift Container Platform 4.8 supports Operator SDK v1.8.0. If you already have the v1.3.0 CLI installed on your workstation, you can upgrade the CLI to v1.8.0 by <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli">installing the latest version</a>. </p><p> However, to ensure your existing Operator projects maintain compatibility with Operator SDK v1.8.0, upgrade steps are required for the associated breaking changes introduced since v1.3.0. You must perform the upgrade steps manually in any of your Operator projects that were previously created or maintained with v1.3.0. </p><section class="section" id="osdk-upgrading-v130-to-v180_osdk-upgrading-projects"><div class="titlepage"><div><div><h3 class="title">5.3.1. Upgrading projects for Operator SDK v1.8.0</h3></div></div></div><p> The following upgrade steps must be performed to upgrade an existing Operator project for compatibility with v1.8.0. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK v1.8.0 installed </li><li class="listitem"> Operator project that was previously created or maintained with Operator SDK v1.3.0 </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Make the following changes to your <code class="literal">PROJECT</code> file: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Update the <code class="literal">PROJECT</code> file <code class="literal">plugins</code> object to use <code class="literal">manifests</code> and <code class="literal">scorecard</code> objects. </p><p class="simpara"> The <code class="literal">manifests</code> and <code class="literal">scorecard</code> plug-ins that create Operator Lifecycle Manager (OLM) and scorecard manifests now have plug-in objects for running <code class="literal">create</code> subcommands to create related files. </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> For Go-based Operator projects, an existing Go-based plug-in configuration object is already present. While the old configuration is still supported, these new objects will be useful in the future as configuration options are added to their respective plug-ins: </p><div class="formalpara"><p class="title"><strong>Old configuration</strong></p><p> </p><pre class="programlisting language-yaml">version: 3-alpha ... plugins: go.sdk.operatorframework.io/v2-alpha: {}</pre> <p></p></div><div class="formalpara"><p class="title"><strong>New configuration</strong></p><p> </p><pre class="programlisting language-yaml">version: 3-alpha ... plugins: manifests.sdk.operatorframework.io/v2: {} scorecard.sdk.operatorframework.io/v2: {}</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Optional: For Ansible- and Helm-based Operator projects, the plug-in configuration object previously did not exist. While you are not required to add the plug-in configuration objects, these new objects will be useful in the future as configuration options are added to their respective plug-ins: </p><pre class="programlisting language-yaml">version: 3-alpha ... plugins: manifests.sdk.operatorframework.io/v2: {} scorecard.sdk.operatorframework.io/v2: {}</pre></li></ul></div></li><li class="listitem"><p class="simpara"> The <code class="literal">PROJECT</code> config version <code class="literal">3-alpha</code> must be upgraded to <code class="literal">3</code>. The <code class="literal">version</code> key in your <code class="literal">PROJECT</code> file represents the <code class="literal">PROJECT</code> config version: </p><div class="formalpara"><p class="title"><strong>Old <code class="literal">PROJECT</code> file</strong></p><p> </p><pre class="programlisting language-yaml">version: 3-alpha resources: - crdVersion: v1 ...</pre> <p></p></div><p class="simpara"> Version <code class="literal">3-alpha</code> has been stabilized as <a class="link" href="https://book.kubebuilder.io/migration/v2vsv3.html">version 3</a> and contains a set of config fields sufficient to fully describe a project. While this change is not technically breaking because the spec at that version was alpha, it was used by default in <code class="literal">operator-sdk</code> commands, so it should be marked as breaking and have a convenient upgrade path. </p><div class="orderedlist"><ol class="orderedlist" type="i"><li class="listitem"><p class="simpara"> Run the <code class="literal">alpha config-3alpha-to-3</code> command to convert most of your <code class="literal">PROJECT</code> file from version <code class="literal">3-alpha</code> to <code class="literal">3</code>: </p><pre class="programlisting language-terminal">$ operator-sdk alpha config-3alpha-to-3</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">Your PROJECT config file has been converted from version 3-alpha to 3. Please make sure all config data is correct.</pre> <p></p></div><p class="simpara"> The command will also output comments with directions where automatic conversion is not possible. </p></li><li class="listitem"><p class="simpara"> Verify the change: </p><div class="formalpara"><p class="title"><strong>New <code class="literal">PROJECT</code> file</strong></p><p> </p><pre class="programlisting language-yaml">version: "3" resources: - api: crdVersion: v1 ...</pre> <p></p></div></li></ol></div></li></ol></div></li><li class="listitem"><p class="simpara"> Make the following changes to your <code class="literal">config/manager/manager.yaml</code> file: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> For Ansible- and Helm-based Operator projects, add liveness and readiness probes. </p><p class="simpara"> New projects built with the Operator SDK have the probes configured by default. The endpoints <code class="literal">/healthz</code> and <code class="literal">/readyz</code> are available now in the provided image base. You can update your existing projects to use the probes by updating the <code class="literal">Dockerfile</code> to use the latest base image, then add the following to the <code class="literal">manager</code> container in the <code class="literal">config/manager/manager.yaml</code> file: </p><div class="example" id="idm140209488226944"><p class="title"><strong>Example 5.1. Configuration for Ansible-based Operator projects</strong></p><div class="example-contents"><pre class="programlisting language-yaml"> livenessProbe: httpGet: path: /healthz port: 6789 initialDelaySeconds: 15 periodSeconds: 20 readinessProbe: httpGet: path: /readyz port: 6789 initialDelaySeconds: 5 periodSeconds: 10</pre></div></div><div class="example" id="idm140209488224640"><p class="title"><strong>Example 5.2. Configuration for Helm-based Operator projects</strong></p><div class="example-contents"><pre class="programlisting language-yaml"> livenessProbe: httpGet: path: /healthz port: 8081 initialDelaySeconds: 15 periodSeconds: 20 readinessProbe: httpGet: path: /readyz port: 8081 initialDelaySeconds: 5 periodSeconds: 10</pre></div></div></li><li class="listitem"><p class="simpara"> For Ansible- and Helm-based Operator projects, add security contexts to your manager’s deployment. </p><p class="simpara"> In the <code class="literal">config/manager/manager.yaml</code> file, add the following security contexts: </p><div class="example" id="idm140209488220144"><p class="title"><strong>Example 5.3. <code class="literal">config/manager/manager.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">spec: ... template: ... spec: securityContext: runAsNonRoot: true containers: - name: manager securityContext: allowPrivilegeEscalation: false</pre></div></div></li></ol></div></li><li class="listitem"><p class="simpara"> Make the following changes to your <code class="literal">Makefile</code>: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> For Ansible- and Helm-based Operator projects, update the <code class="literal">helm-operator</code> and <code class="literal">ansible-operator</code> URLs in the <code class="literal">Makefile</code>: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> For Ansible-based Operator projects, change: </p><pre class="programlisting language-terminal">https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/ansible-operator-v1.3.0-$(ARCHOPER)-$(OSOPER)</pre><p class="simpara"> to: </p><pre class="programlisting language-terminal">https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/ansible-operator_$(OS)_$(ARCH)</pre></li><li class="listitem"><p class="simpara"> For Helm-based Operator projects, change: </p><pre class="programlisting language-terminal">https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/helm-operator-v1.3.0-$(ARCHOPER)-$(OSOPER)</pre><p class="simpara"> to: </p><pre class="programlisting language-terminal">https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/helm-operator_$(OS)_$(ARCH)</pre></li></ul></div></li><li class="listitem"><p class="simpara"> For Ansible- and Helm-based Operator projects, update the <code class="literal">helm-operator</code>, <code class="literal">ansible-operator</code>, and <code class="literal">kustomize</code> rules in the <code class="literal">Makefile</code>. These rules download a local binary but do not use it if a global binary is present: </p><div class="example" id="idm140209488201648"><p class="title"><strong>Example 5.4. <code class="literal">Makefile</code> diff for Ansible-based Operator projects</strong></p><div class="example-contents"><pre class="programlisting language-diff"> PATH := $(PATH):$(PWD)/bin SHELL := env PATH=$(PATH) /bin/sh -OS := $(shell uname -s | tr '[:upper:]' '[:lower:]') -ARCH := $(shell uname -m | sed 's/x86_64/amd64/') +OS = $(shell uname -s | tr '[:upper:]' '[:lower:]') +ARCH = $(shell uname -m | sed 's/x86_64/amd64/') +OSOPER = $(shell uname -s | tr '[:upper:]' '[:lower:]' | sed 's/darwin/apple-darwin/' | sed 's/linux/linux-gnu/') +ARCHOPER = $(shell uname -m ) -# Download kustomize locally if necessary, preferring the $(pwd)/bin path over global if both exist. -.PHONY: kustomize -KUSTOMIZE = $(shell pwd)/bin/kustomize kustomize: -ifeq (,$(wildcard $(KUSTOMIZE))) -ifeq (,$(shell which kustomize 2&gt;/dev/null)) +ifeq (, $(shell which kustomize 2&gt;/dev/null)) @{ \ set -e ;\ - mkdir -p $(dir $(KUSTOMIZE)) ;\ - curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | \ - tar xzf - -C bin/ ;\ + mkdir -p bin ;\ + curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | tar xzf - -C bin/ ;\ } +KUSTOMIZE=$(realpath ./bin/kustomize) else -KUSTOMIZE = $(shell which kustomize) -endif +KUSTOMIZE=$(shell which kustomize) endif -# Download ansible-operator locally if necessary, preferring the $(pwd)/bin path over global if both exist. -.PHONY: ansible-operator -ANSIBLE_OPERATOR = $(shell pwd)/bin/ansible-operator ansible-operator: -ifeq (,$(wildcard $(ANSIBLE_OPERATOR))) -ifeq (,$(shell which ansible-operator 2&gt;/dev/null)) +ifeq (, $(shell which ansible-operator 2&gt;/dev/null)) @{ \ set -e ;\ - mkdir -p $(dir $(ANSIBLE_OPERATOR)) ;\ - curl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/ansible-operator_$(OS)_$(ARCH) ;\ - chmod +x $(ANSIBLE_OPERATOR) ;\ + mkdir -p bin ;\ + curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/ansible-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ;\ + mv ansible-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ./bin/ansible-operator ;\ + chmod +x ./bin/ansible-operator ;\ } +ANSIBLE_OPERATOR=$(realpath ./bin/ansible-operator) else -ANSIBLE_OPERATOR = $(shell which ansible-operator) -endif +ANSIBLE_OPERATOR=$(shell which ansible-operator) endif</pre></div></div><div class="example" id="idm140209488194944"><p class="title"><strong>Example 5.5. <code class="literal">Makefile</code> diff for Helm-based Operator projects</strong></p><div class="example-contents"><pre class="programlisting language-diff"> PATH := $(PATH):$(PWD)/bin SHELL := env PATH=$(PATH) /bin/sh -OS := $(shell uname -s | tr '[:upper:]' '[:lower:]') -ARCH := $(shell uname -m | sed 's/x86_64/amd64/') +OS = $(shell uname -s | tr '[:upper:]' '[:lower:]') +ARCH = $(shell uname -m | sed 's/x86_64/amd64/') +OSOPER = $(shell uname -s | tr '[:upper:]' '[:lower:]' | sed 's/darwin/apple-darwin/' | sed 's/linux/linux-gnu/') +ARCHOPER = $(shell uname -m ) -# Download kustomize locally if necessary, preferring the $(pwd)/bin path over global if both exist. -.PHONY: kustomize -KUSTOMIZE = $(shell pwd)/bin/kustomize kustomize: -ifeq (,$(wildcard $(KUSTOMIZE))) -ifeq (,$(shell which kustomize 2&gt;/dev/null)) +ifeq (, $(shell which kustomize 2&gt;/dev/null)) @{ \ set -e ;\ - mkdir -p $(dir $(KUSTOMIZE)) ;\ - curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | \ - tar xzf - -C bin/ ;\ + mkdir -p bin ;\ + curl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | tar xzf - -C bin/ ;\ } +KUSTOMIZE=$(realpath ./bin/kustomize) else -KUSTOMIZE = $(shell which kustomize) -endif +KUSTOMIZE=$(shell which kustomize) endif -# Download helm-operator locally if necessary, preferring the $(pwd)/bin path over global if both exist. -.PHONY: helm-operator -HELM_OPERATOR = $(shell pwd)/bin/helm-operator helm-operator: -ifeq (,$(wildcard $(HELM_OPERATOR))) -ifeq (,$(shell which helm-operator 2&gt;/dev/null)) +ifeq (, $(shell which helm-operator 2&gt;/dev/null)) @{ \ set -e ;\ - mkdir -p $(dir $(HELM_OPERATOR)) ;\ - curl -sSLo $(HELM_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/helm-operator_$(OS)_$(ARCH) ;\ - chmod +x $(HELM_OPERATOR) ;\ + mkdir -p bin ;\ + curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/helm-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ;\ + mv helm-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ./bin/helm-operator ;\ + chmod +x ./bin/helm-operator ;\ } +HELM_OPERATOR=$(realpath ./bin/helm-operator) else -HELM_OPERATOR = $(shell which helm-operator) -endif +HELM_OPERATOR=$(shell which helm-operator) endif</pre></div></div></li><li class="listitem"><p class="simpara"> Move the positional directory argument <code class="literal">.</code> in the <code class="literal">make</code> target for <code class="literal">docker-build</code>. </p><p class="simpara"> The directory argument <code class="literal">.</code> in the <code class="literal">docker-build</code> target was moved to the last positional argument to align with <code class="literal">podman</code> CLI expectations, which makes substitution cleaner: </p><div class="formalpara"><p class="title"><strong>Old target</strong></p><p> </p><pre class="programlisting language-terminal">docker-build: docker build . -t ${IMG}</pre> <p></p></div><div class="formalpara"><p class="title"><strong>New target</strong></p><p> </p><pre class="programlisting language-terminal">docker-build: docker build -t ${IMG} .</pre> <p></p></div><p class="simpara"> You can make this change by running the following command: </p><pre class="programlisting language-terminal">$ sed -i 's/docker build . -t ${IMG}/docker build -t ${IMG} ./' $(git grep -l 'docker.*build \. ')</pre></li><li class="listitem"><p class="simpara"> For Ansible- and Helm-based Operator projects, add a <code class="literal">help</code> target to the <code class="literal">Makefile</code>. </p><p class="simpara"> Ansible- and Helm-based projects now provide <code class="literal">help</code> target in the <code class="literal">Makefile</code> by default, similar to a <code class="literal">--help</code> flag. You can manually add this target to your <code class="literal">Makefile</code> using the following lines: </p><div class="example" id="idm140209488172544"><p class="title"><strong>Example 5.6. <code class="literal">help</code> target</strong></p><div class="example-contents"><pre class="programlisting language-make">##@ General # The help target prints out all targets with their descriptions organized # beneath their categories. The categories are represented by '##@' and the # target descriptions by '##'. The awk commands is responsible for reading the # entire set of makefiles included in this invocation, looking for lines of the # file as xyz: ## something, and then pretty-format the target and help. Then, # if there's a line with ##@ something, that gets pretty-printed as a category. # More info on the usage of ANSI control characters for terminal formatting: # https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters # More info on the awk command: # http://linuxcommand.org/lc3_adv_awk.php help: ## Display this help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m&lt;target&gt;\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)</pre></div></div></li><li class="listitem"><p class="simpara"> Add <code class="literal">opm</code> and <code class="literal">catalog-build</code> targets. You can use these targets to create your own catalogs for your Operator or add your Operator bundles to an existing catalog: </p><div class="orderedlist"><ol class="orderedlist" type="i"><li class="listitem"><p class="simpara"> Add the targets to your <code class="literal">Makefile</code> by adding the following lines: </p><div class="example" id="idm140209488164624"><p class="title"><strong>Example 5.7. <code class="literal">opm</code> and <code class="literal">catalog-build</code> targets</strong></p><div class="example-contents"><pre class="programlisting language-make">.PHONY: opm OPM = ./bin/opm opm: ifeq (,$(wildcard $(OPM))) ifeq (,$(shell which opm 2&gt;/dev/null)) @{ \ set -e ;\ mkdir -p $(dir $(OPM)) ;\ curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.15.1/$(OS)-$(ARCH)-opm ;\ chmod +x $(OPM) ;\ } else OPM = $(shell which opm) endif endif BUNDLE_IMGS ?= $(BUNDLE_IMG) CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:v$(VERSION) ifneq ($(origin CATALOG_BASE_IMG), undefined) FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) endif .PHONY: catalog-build catalog-build: opm $(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT) .PHONY: catalog-push catalog-push: ## Push the catalog image. $(MAKE) docker-push IMG=$(CATALOG_IMG)</pre></div></div></li><li class="listitem"><p class="simpara"> If you are updating a Go-based Operator project, also add the following <code class="literal">Makefile</code> variables: </p><div class="example" id="idm140209488158560"><p class="title"><strong>Example 5.8. <code class="literal">Makefile</code> variables</strong></p><div class="example-contents"><pre class="programlisting language-make">OS = $(shell go env GOOS) ARCH = $(shell go env GOARCH)</pre></div></div></li></ol></div></li><li class="listitem"><p class="simpara"> For Go-based Operator projects, set the <code class="literal">SHELL</code> variable in your <code class="literal">Makefile</code> to the system <code class="literal">bash</code> binary. </p><p class="simpara"> Importing the <code class="literal">setup-envtest.sh</code> script requires <code class="literal">bash</code>, so the <code class="literal">SHELL</code> variable must be set to <code class="literal">bash</code> with error options: </p><div class="example" id="idm140209488150960"><p class="title"><strong>Example 5.9. <code class="literal">Makefile</code> diff</strong></p><div class="example-contents"><pre class="programlisting language-diff">else GOBIN=$(shell go env GOBIN) endif +# Setting SHELL to bash allows bash commands to be executed by recipes. +# This is a requirement for 'setup-envtest.sh' in the test target. +# Options are set to exit when a recipe line exits non-zero or a piped command fails. +SHELL = /usr/bin/env bash -o pipefail +.SHELLFLAGS = -ec + all: build</pre></div></div></li></ol></div></li><li class="listitem"><p class="simpara"> For Go-based Operator projects, upgrade <code class="literal">controller-runtime</code> to v0.8.3 and Kubernetes dependencies to v0.20.2 by changing the following entries in your <code class="literal">go.mod</code> file, then rebuild your project: </p><div class="example" id="idm140209488145888"><p class="title"><strong>Example 5.10. <code class="literal">go.mod</code> file</strong></p><div class="example-contents"><pre class="programlisting language-go">... k8s.io/api v0.20.2 k8s.io/apimachinery v0.20.2 k8s.io/client-go v0.20.2 sigs.k8s.io/controller-runtime v0.8.3</pre></div></div></li><li class="listitem"><p class="simpara"> Add a <code class="literal">system:controller-manager</code> service account to your project. A non-default service account <code class="literal">controller-manager</code> is now generated by the <code class="literal">operator-sdk init</code> command to improve security for Operators installed in shared namespaces. To add this service account to your existing project, follow these steps: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Create the <code class="literal">ServiceAccount</code> definition in a file: </p><div class="example" id="idm140209488138880"><p class="title"><strong>Example 5.11. <code class="literal">config/rbac/service_account.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">apiVersion: v1 kind: ServiceAccount metadata: name: controller-manager namespace: system</pre></div></div></li><li class="listitem"><p class="simpara"> Add the service account to the list of RBAC resources: </p><pre class="programlisting language-terminal">$ echo "- service_account.yaml" &gt;&gt; config/rbac/kustomization.yaml</pre></li><li class="listitem"><p class="simpara"> Update all <code class="literal">RoleBinding</code> and <code class="literal">ClusterRoleBinding</code> objects that reference the Operator’s service account: </p><pre class="programlisting language-terminal">$ find config/rbac -name *_binding.yaml -exec sed -i -E 's/ name: default/ name: controller-manager/g' {} \;</pre></li><li class="listitem"><p class="simpara"> Add the service account name to the manager deployment’s <code class="literal">spec.template.spec.serviceAccountName</code> field: </p><pre class="programlisting language-terminal">$ sed -i -E 's/([ ]+)(terminationGracePeriodSeconds:)/\1serviceAccountName: controller-manager\n\1\2/g' config/manager/manager.yaml</pre></li><li class="listitem"><p class="simpara"> Verify the changes look like the following diffs: </p><div class="example" id="idm140209488127248"><p class="title"><strong>Example 5.12. <code class="literal">config/manager/manager.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff">... requests: cpu: 100m memory: 20Mi + serviceAccountName: controller-manager terminationGracePeriodSeconds: 10</pre></div></div><div class="example" id="idm140209488124720"><p class="title"><strong>Example 5.13. <code class="literal">config/rbac/auth_proxy_role_binding.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff">... name: proxy-role subjects: - kind: ServiceAccount - name: default + name: controller-manager namespace: system</pre></div></div><div class="example" id="idm140209488122208"><p class="title"><strong>Example 5.14. <code class="literal">config/rbac/kustomization.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff"> resources: +- service_account.yaml - role.yaml - role_binding.yaml - leader_election_role.yaml</pre></div></div><div class="example" id="idm140209488119744"><p class="title"><strong>Example 5.15. <code class="literal">config/rbac/leader_election_role_binding.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff">... name: leader-election-role subjects: - kind: ServiceAccount - name: default + name: controller-manager namespace: system</pre></div></div><div class="example" id="idm140209488117232"><p class="title"><strong>Example 5.16. <code class="literal">config/rbac/role_binding.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff">... name: manager-role subjects: - kind: ServiceAccount - name: default + name: controller-manager namespace: system</pre></div></div><div class="example" id="idm140209488114736"><p class="title"><strong>Example 5.17. <code class="literal">config/rbac/service_account.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff">+apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: system</pre></div></div></li></ol></div></li><li class="listitem"><p class="simpara"> Make the following changes to your <code class="literal">config/manifests/kustomization.yaml</code> file: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Add a <a class="link" href="https://kustomize.io/">Kustomize</a> patch to remove the <a class="link" href="https://cert-manager.io/">cert-manager</a> <code class="literal">volume</code> and <code class="literal">volumeMount</code> objects from your cluster service version (CSV). </p><p class="simpara"> Because Operator Lifecycle Manager (OLM) does not yet support cert-manager, a JSON patch was added to remove this volume and mount so OLM can create and manage certificates for your Operator. </p><p class="simpara"> In the <code class="literal">config/manifests/kustomization.yaml</code> file, add the following lines: </p><div class="example" id="idm140209488104768"><p class="title"><strong>Example 5.18. <code class="literal">config/manifests/kustomization.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">patchesJson6902: - target: group: apps version: v1 kind: Deployment name: controller-manager namespace: system patch: |- # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. - op: remove path: /spec/template/spec/containers/1/volumeMounts/0 # Remove the "cert" volume, since OLM will create and mount a set of certs. # Update the indices in this path if adding or removing volumes in the manager's Deployment. - op: remove path: /spec/template/spec/volumes/0</pre></div></div></li><li class="listitem"><p class="simpara"> Optional: For Ansible- and Helm-based Operator projects, configure <code class="literal">ansible-operator</code> and <code class="literal">helm-operator</code> with a component config. To add this option, follow these steps: </p><div class="orderedlist"><ol class="orderedlist" type="i"><li class="listitem"><p class="simpara"> Create the following file: </p><div class="example" id="idm140209488098224"><p class="title"><strong>Example 5.19. <code class="literal">config/default/manager_config_patch.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">apiVersion: apps/v1 kind: Deployment metadata: name: controller-manager namespace: system spec: template: spec: containers: - name: manager args: - "--config=controller_manager_config.yaml" volumeMounts: - name: manager-config mountPath: /controller_manager_config.yaml subPath: controller_manager_config.yaml volumes: - name: manager-config configMap: name: manager-config</pre></div></div></li><li class="listitem"><p class="simpara"> Create the following file: </p><div class="example" id="idm140209488094368"><p class="title"><strong>Example 5.20. <code class="literal">config/manager/controller_manager_config.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 kind: ControllerManagerConfig health: healthProbeBindAddress: :6789 metrics: bindAddress: 127.0.0.1:8080 leaderElection: leaderElect: true resourceName: &lt;resource_name&gt;</pre></div></div></li><li class="listitem"><p class="simpara"> Update the <code class="literal">config/default/kustomization.yaml</code> file by applying the following changes to <code class="literal">resources</code>: </p><div class="example" id="idm140209488089584"><p class="title"><strong>Example 5.21. <code class="literal">config/default/kustomization.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml"> resources: ... - manager_config_patch.yaml</pre></div></div></li><li class="listitem"><p class="simpara"> Update the <code class="literal">config/manager/kustomization.yaml</code> file by applying the following changes: </p><div class="example" id="idm140209488085680"><p class="title"><strong>Example 5.22. <code class="literal">config/manager/kustomization.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml"> generatorOptions: disableNameSuffixHash: true configMapGenerator: - files: - controller_manager_config.yaml name: manager-config apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller newName: quay.io/example/memcached-operator newTag: v0.0.1</pre></div></div></li></ol></div></li><li class="listitem"><p class="simpara"> Optional: Add a manager config patch to the <code class="literal">config/default/kustomization.yaml</code> file. </p><p class="simpara"> The generated <code class="literal">--config</code> flag was not added to either the <code class="literal">ansible-operator</code> or <code class="literal">helm-operator</code> binary when <a class="link" href="https://master.book.kubebuilder.io/component-config-tutorial/tutorial.html">config file</a> support was originally added, so it does not currently work. The <code class="literal">--config</code> flag supports configuration of both binaries by file; this method of configuration only applies to the underlying <a class="link" href="https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/manager#Manager">controller manager</a> and not the Operator as a whole. </p><p class="simpara"> To optionally configure the Operator’s deployment with a config file, make changes to the <code class="literal">config/default/kustomization.yaml</code> file as shown in the following diff: </p><div class="example" id="idm140209488075696"><p class="title"><strong>Example 5.23. <code class="literal">config/default/kustomization.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff"># If you want your controller-manager to expose the /metrics # endpoint w/o any authn/z, please comment the following line. \- manager_auth_proxy_patch.yaml +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +- manager_config_patch.yaml</pre></div></div><p class="simpara"> Flags can be used as is or to override config file values. </p></li></ol></div></li><li class="listitem"><p class="simpara"> For Ansible- and Helm-based Operator projects, add role rules for leader election by making the following changes to the <code class="literal">config/rbac/leader_election_role.yaml</code> file: </p><div class="example" id="idm140209488070608"><p class="title"><strong>Example 5.24. <code class="literal">config/rbac/leader_election_role.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">- apiGroups: - coordination.k8s.io resources: - leases verbs: - get - list - watch - create - update - patch - delete</pre></div></div></li><li class="listitem"><p class="simpara"> For Ansible-based Operator projects, update Ansible collections. </p><p class="simpara"> In your <code class="literal">requirements.yml</code> file, change the <code class="literal">version</code> field for <code class="literal">community.kubernetes</code> to <code class="literal">1.2.1</code>, and the <code class="literal">version</code> field for <code class="literal">operator_sdk.util</code> to <code class="literal">0.2.0</code>. </p></li><li class="listitem"><p class="simpara"> Make the following changes to your <code class="literal">config/default/manager_auth_proxy_patch.yaml</code> file: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> For Ansible-based Operator projects, add the <code class="literal">--health-probe-bind-address=:6789</code> argument to the <code class="literal">config/default/manager_auth_proxy_patch.yaml</code> file: </p><div class="example" id="idm140209488059568"><p class="title"><strong>Example 5.25. <code class="literal">config/default/manager_auth_proxy_patch.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">spec: template: spec: containers: - name: manager args: - "--health-probe-bind-address=:6789" ...</pre></div></div></li><li class="listitem"><p class="simpara"> For Helm-based Operator projects: </p><div class="orderedlist"><ol class="orderedlist" type="i"><li class="listitem"><p class="simpara"> Add the <code class="literal">--health-probe-bind-address=:8081</code> argument to the <code class="literal">config/default/manager_auth_proxy_patch.yaml</code> file: </p><div class="example" id="idm140209488053616"><p class="title"><strong>Example 5.26. <code class="literal">config/default/manager_auth_proxy_patch.yaml</code> file</strong></p><div class="example-contents"><pre class="programlisting language-yaml">spec: template: spec: containers: - name: manager args: - "--health-probe-bind-address=:8081" ...</pre></div></div></li><li class="listitem"> Replace the deprecated flag <code class="literal">--enable-leader-election</code> with <code class="literal">--leader-elect</code>, and the deprecated flag <code class="literal">--metrics-addr</code> with <code class="literal">--metrics-bind-address</code>. </li></ol></div></li></ul></div></li><li class="listitem"><p class="simpara"> Make the following changes to your <code class="literal">config/prometheus/monitor.yaml</code> file: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Add scheme, token, and TLS config to the Prometheus <code class="literal">ServiceMonitor</code> metrics endpoint. </p><p class="simpara"> The <code class="literal">/metrics</code> endpoint, while specifying the <code class="literal">https</code> port on the manager pod, was not actually configured to serve over HTTPS because no <code class="literal">tlsConfig</code> was set. Because <code class="literal">kube-rbac-proxy</code> secures this endpoint as a manager sidecar, using the service account token mounted into the pod by default corrects this problem. </p><p class="simpara"> Apply the changes to the <code class="literal">config/prometheus/monitor.yaml</code> file as shown in the following diff: </p><div class="example" id="idm140209488040416"><p class="title"><strong>Example 5.27. <code class="literal">config/prometheus/monitor.yaml</code> file diff</strong></p><div class="example-contents"><pre class="programlisting language-diff">spec: endpoints: - path: /metrics port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + insecureSkipVerify: true selector: matchLabels: control-plane: controller-manager</pre></div></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> If you removed <code class="literal">kube-rbac-proxy</code> from your project, ensure that you secure the <code class="literal">/metrics</code> endpoint using a proper <a class="link" href="https://prometheus.io/docs/guides/tls-encryption">TLS configuration</a>. </p></div></rh-alert></li></ol></div></li><li class="listitem"><p class="simpara"> Ensure that existing dependent resources have owner annotations. </p><p class="simpara"> For Ansible-based Operator projects, <a class="link" href="https://sdk.operatorframework.io/docs/building-operators/ansible/reference/retroactively-owned-resources/">owner reference annotations</a> on cluster-scoped dependent resources and dependent resources in other namespaces were not applied correctly. A workaround was to add these annotations manually, which is no longer required as this bug has been fixed. </p></li><li class="listitem"><p class="simpara"> Deprecate support for package manifests. </p><p class="simpara"> The <a class="link" href="https://operatorframework.io/">Operator Framework</a> is removing support for the Operator package manifest format in a future release. As part of the ongoing deprecation process, the <code class="literal">operator-sdk generate packagemanifests</code> and <code class="literal">operator-sdk run packagemanifests</code> commands are now deprecated. To migrate package manifests to bundles, the <code class="literal">operator-sdk pkgman-to-bundle</code> command can be used. </p><p class="simpara"> Run the <code class="literal">operator-sdk pkgman-to-bundle --help</code> command and see "Migrating package manifest projects to bundle format" for more details. </p></li><li class="listitem"><p class="simpara"> Update the finalizer names for your Operator. </p><p class="simpara"> The finalizer name format suggested by <a class="link" href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#finalizers">Kubernetes documentation</a> is: </p><pre class="programlisting language-terminal">&lt;qualified_group&gt;/&lt;finalizer_name&gt;</pre><p class="simpara"> while the format previously documented for Operator SDK was: </p><pre class="programlisting language-terminal">&lt;finalizer_name&gt;.&lt;qualified_group&gt;</pre><p class="simpara"> If your Operator uses any finalizers with names that match the incorrect format, change them to match the official format. For example, <code class="literal">finalizer.cache.example.com</code> must be changed to <code class="literal">cache.example.com/finalizer</code>. </p></li></ol></div><p> Your Operator project is now compatible with Operator SDK v1.8.0. </p></section><section class="section _additional-resources" id="additional-resources_osdk-upgrading-projects"><div class="titlepage"><div><div><h3 class="title">5.3.2. Additional resources</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-pkgman-to-bundle">Migrating package manifest projects to bundle format</a> </li></ul></div></section></section><section class="section" id="go-based-operators"><div class="titlepage"><div><div><h2 class="title">5.4. Go-based Operators</h2></div></div></div><section class="section" id="osdk-golang-quickstart"><div class="titlepage"><div><div><h3 class="title">5.4.1. Getting started with Operator SDK for Go-based Operators</h3></div></div></div><p> To demonstrate the basics of setting up and running a Go-based Operator using tools and libraries provided by the Operator SDK, Operator developers can build an example Go-based Operator for Memcached, a distributed key-value store, and deploy it to a cluster. </p><section class="section" id="osdk-common-prereqs_osdk-golang-quickstart"><div class="titlepage"><div><div><h4 class="title">5.4.1.1. Prerequisites</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli">Operator SDK CLI installed</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli">OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed</a> </li><li class="listitem"> Logged into an OpenShift Container Platform 4.8 cluster with <code class="literal">oc</code> with an account that has <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> To allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret </li></ul></div></section><section class="section" id="osdk-quickstart_osdk-golang-quickstart"><div class="titlepage"><div><div><h4 class="title">5.4.1.2. Creating and deploying Go-based Operators</h4></div></div></div><p> You can build and deploy a simple Go-based Operator for Memcached by using the Operator SDK. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create a project.</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Create your project directory: </p><pre class="programlisting language-terminal">$ mkdir memcached-operator</pre></li><li class="listitem"><p class="simpara"> Change into the project directory: </p><pre class="programlisting language-terminal">$ cd memcached-operator</pre></li><li class="listitem"><p class="simpara"> Run the <code class="literal">operator-sdk init</code> command to initialize the project: </p><pre class="programlisting language-terminal">$ operator-sdk init \ --domain=example.com \ --repo=github.com/example-inc/memcached-operator</pre><p class="simpara"> The command uses the Go plugin by default. </p></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create an API.</strong></span> </p><p class="simpara"> Create a simple Memcached API: </p><pre class="programlisting language-terminal">$ operator-sdk create api \ --resource=true \ --controller=true \ --group cache \ --version v1 \ --kind Memcached</pre></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Build and push the Operator image.</strong></span> </p><p class="simpara"> Use the default <code class="literal">Makefile</code> targets to build and push your Operator. Set <code class="literal">IMG</code> with a pull spec for your image that uses a registry you can push to: </p><pre class="programlisting language-terminal">$ make docker-build docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Run the Operator.</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Install the CRD: </p><pre class="programlisting language-terminal">$ make install</pre></li><li class="listitem"><p class="simpara"> Deploy the project to the cluster. Set <code class="literal">IMG</code> to the image that you pushed: </p><pre class="programlisting language-terminal">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create a sample custom resource (CR).</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Create a sample CR: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/cache_v1_memcached.yaml \ -n memcached-operator-system</pre></li><li class="listitem"><p class="simpara"> Watch for the CR to reconcile the Operator: </p><pre class="programlisting language-terminal">$ oc logs deployment.apps/memcached-operator-controller-manager \ -c manager \ -n memcached-operator-system</pre></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Clean up.</strong></span> </p><p class="simpara"> Run the following command to clean up the resources that have been created as part of this procedure: </p><pre class="programlisting language-terminal">$ make undeploy</pre></li></ol></div></section><section class="section" id="osdk-golang-quickstart-next-steps"><div class="titlepage"><div><div><h4 class="title">5.4.1.3. Next steps</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-golang-tutorial">Operator SDK tutorial for Go-based Operators</a> for a more in-depth walkthrough on building a Go-based Operator. </li></ul></div></section></section><section class="section" id="osdk-golang-tutorial"><div class="titlepage"><div><div><h3 class="title">5.4.2. Operator SDK tutorial for Go-based Operators</h3></div></div></div><p> Operator developers can take advantage of Go programming language support in the Operator SDK to build an example Go-based Operator for Memcached, a distributed key-value store, and manage its lifecycle. </p><p> This process is accomplished using two centerpieces of the Operator Framework: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Operator SDK</span></dt><dd> The <code class="literal">operator-sdk</code> CLI tool and <code class="literal">controller-runtime</code> library API </dd><dt><span class="term">Operator Lifecycle Manager (OLM)</span></dt><dd> Installation, upgrade, and role-based access control (RBAC) of Operators on a cluster </dd></dl></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> This tutorial goes into greater detail than <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-golang-quickstart">Getting started with Operator SDK for Go-based Operators</a>. </p></div></rh-alert><section class="section" id="osdk-common-prereqs_osdk-golang-tutorial"><div class="titlepage"><div><div><h4 class="title">5.4.2.1. Prerequisites</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli">Operator SDK CLI installed</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli">OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed</a> </li><li class="listitem"> Logged into an OpenShift Container Platform 4.8 cluster with <code class="literal">oc</code> with an account that has <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> To allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret </li></ul></div></section><section class="section" id="osdk-create-project_osdk-golang-tutorial"><div class="titlepage"><div><div><h4 class="title">5.4.2.2. Creating a project</h4></div></div></div><p> Use the Operator SDK CLI to create a project called <code class="literal">memcached-operator</code>. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Create a directory for the project: </p><pre class="programlisting language-terminal">$ mkdir -p $HOME/projects/memcached-operator</pre></li><li class="listitem"><p class="simpara"> Change to the directory: </p><pre class="programlisting language-terminal">$ cd $HOME/projects/memcached-operator</pre></li><li class="listitem"><p class="simpara"> Activate support for Go modules: </p><pre class="programlisting language-terminal">$ export GO111MODULE=on</pre></li><li class="listitem"><p class="simpara"> Run the <code class="literal">operator-sdk init</code> command to initialize the project: </p><pre class="programlisting language-terminal">$ operator-sdk init \ --domain=example.com \ --repo=github.com/example-inc/memcached-operator</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The <code class="literal">operator-sdk init</code> command uses the Go plugin by default. </p></div></rh-alert><p class="simpara"> The <code class="literal">operator-sdk init</code> command generates a <code class="literal">go.mod</code> file to be used with <a class="link" href="https://golang.org/ref/mod">Go modules</a>. The <code class="literal">--repo</code> flag is required when creating a project outside of <code class="literal">$GOPATH/src/</code>, because generated files require a valid module path. </p></li></ol></div><section class="section" id="osdk-project-file_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.2.1. PROJECT file</h5></div></div></div><p> Among the files generated by the <code class="literal">operator-sdk init</code> command is a Kubebuilder <code class="literal">PROJECT</code> file. Subsequent <code class="literal">operator-sdk</code> commands, as well as <code class="literal">help</code> output, that are run from the project root read this file and are aware that the project type is Go. For example: </p><pre class="programlisting language-yaml">domain: example.com layout: go.kubebuilder.io/v3 projectName: memcached-operator repo: github.com/example-inc/memcached-operator version: 3 plugins: manifests.sdk.operatorframework.io/v2: {} scorecard.sdk.operatorframework.io/v2: {}</pre></section><section class="section" id="osdk-golang-manager_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.2.2. About the Manager</h5></div></div></div><p> The main program for the Operator is the <code class="literal">main.go</code> file, which initializes and runs the <a class="link" href="https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/manager#Manager">Manager</a>. The Manager automatically registers the Scheme for all custom resource (CR) API definitions and sets up and runs controllers and webhooks. </p><p> The Manager can restrict the namespace that all controllers watch for resources: </p><pre class="programlisting language-go">mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: namespace})</pre><p> By default, the Manager watches the namespace where the Operator runs. To watch all namespaces, you can leave the <code class="literal">namespace</code> option empty: </p><pre class="programlisting language-go">mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: ""})</pre><p> You can also use the <a class="link" href="https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/cache#MultiNamespacedCacheBuilder"><code class="literal">MultiNamespacedCacheBuilder</code></a> function to watch a specific set of namespaces: </p><pre class="programlisting language-go">var namespaces []string <span id="CO38-1"><!--Empty--></span><span class="callout">1</span> mgr, err := ctrl.NewManager(cfg, manager.Options{ <span id="CO38-2"><!--Empty--></span><span class="callout">2</span> NewCache: cache.MultiNamespacedCacheBuilder(namespaces), })</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO38-1"><span class="callout">1</span></a> </dt><dd><div class="para"> List of namespaces. </div></dd><dt><a href="#CO38-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Creates a <code class="literal">Cmd</code> struct to provide shared dependencies and start components. </div></dd></dl></div></section><section class="section" id="osdk-golang-multi-group-apis_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.2.3. About multi-group APIs</h5></div></div></div><p> Before you create an API and controller, consider whether your Operator requires multiple API groups. This tutorial covers the default case of a single group API, but to change the layout of your project to support multi-group APIs, you can run the following command: </p><pre class="programlisting language-terminal">$ operator-sdk edit --multigroup=true</pre><p> This command updates the <code class="literal">PROJECT</code> file, which should look like the following example: </p><pre class="programlisting language-yaml">domain: example.com layout: go.kubebuilder.io/v3 multigroup: true ...</pre><p> For multi-group projects, the API Go type files are created in the <code class="literal">apis/&lt;group&gt;/&lt;version&gt;/</code> directory, and the controllers are created in the <code class="literal">controllers/&lt;group&gt;/</code> directory. The Dockerfile is then updated accordingly. </p><div class="itemizedlist"><p class="title"><strong>Additional resource</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> For more details on migrating to a multi-group project, see the <a class="link" href="https://book.kubebuilder.io/migration/multi-group.html">Kubebuilder documentation</a>. </li></ul></div></section></section><section class="section" id="osdk-golang-create-api-controller_osdk-golang-tutorial"><div class="titlepage"><div><div><h4 class="title">5.4.2.3. Creating an API and controller</h4></div></div></div><p> Use the Operator SDK CLI to create a custom resource definition (CRD) API and controller. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following command to create an API with group <code class="literal">cache</code>, version, <code class="literal">v1</code>, and kind <code class="literal">Memcached</code>: </p><pre class="programlisting language-terminal">$ operator-sdk create api \ --group=cache \ --version=v1 \ --kind=Memcached</pre></li><li class="listitem"><p class="simpara"> When prompted, enter <code class="literal">y</code> for creating both the resource and controller: </p><pre class="programlisting language-terminal">Create Resource [y/n] y Create Controller [y/n] y</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">Writing scaffold for you to edit... api/v1/memcached_types.go controllers/memcached_controller.go ...</pre> <p></p></div></li></ol></div><p> This process generates the <code class="literal">Memcached</code> resource API at <code class="literal">api/v1/memcached_types.go</code> and the controller at <code class="literal">controllers/memcached_controller.go</code>. </p><section class="section" id="osdk-golang-define-api_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.3.1. Defining the API</h5></div></div></div><p> Define the API for the <code class="literal">Memcached</code> custom resource (CR). </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Modify the Go type definitions at <code class="literal">api/v1/memcached_types.go</code> to have the following <code class="literal">spec</code> and <code class="literal">status</code>: </p><pre class="programlisting language-go">// MemcachedSpec defines the desired state of Memcached type MemcachedSpec struct { // +kubebuilder:validation:Minimum=0 // Size is the size of the memcached deployment Size int32 `json:"size"` } // MemcachedStatus defines the observed state of Memcached type MemcachedStatus struct { // Nodes are the names of the memcached pods Nodes []string `json:"nodes"` }</pre></li><li class="listitem"><p class="simpara"> Update the generated code for the resource type: </p><pre class="programlisting language-terminal">$ make generate</pre><rh-alert class="admonition tip" state="info"><div class="admonition_header" slot="header">Tip</div><div><p> After you modify a <code class="literal">*_types.go</code> file, you must run the <code class="literal">make generate</code> command to update the generated code for that resource type. </p></div></rh-alert><p class="simpara"> The above Makefile target invokes the <code class="literal">controller-gen</code> utility to update the <code class="literal">api/v1/zz_generated.deepcopy.go</code> file. This ensures your API Go type definitions implement the <code class="literal">runtime.Object</code> interface that all Kind types must implement. </p></li></ol></div></section><section class="section" id="osdk-golang-generate-crd_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.3.2. Generating CRD manifests</h5></div></div></div><p> After the API is defined with <code class="literal">spec</code> and <code class="literal">status</code> fields and custom resource definition (CRD) validation markers, you can generate CRD manifests. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Run the following command to generate and update CRD manifests: </p><pre class="programlisting language-terminal">$ make manifests</pre><p class="simpara"> This Makefile target invokes the <code class="literal">controller-gen</code> utility to generate the CRD manifests in the <code class="literal">config/crd/bases/cache.example.com_memcacheds.yaml</code> file. </p></li></ul></div><section class="section" id="osdk-about-openapi-validation_osdk-golang-tutorial"><div class="titlepage"><div><div><h6 class="title">5.4.2.3.2.1. About OpenAPI validation</h6></div></div></div><p> OpenAPIv3 schemas are added to CRD manifests in the <code class="literal">spec.validation</code> block when the manifests are generated. This validation block allows Kubernetes to validate the properties in a Memcached custom resource (CR) when it is created or updated. </p><p> Markers, or annotations, are available to configure validations for your API. These markers always have a <code class="literal">+kubebuilder:validation</code> prefix. </p><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"><p class="simpara"> For more details on the usage of markers in API code, see the following Kubebuilder documentation: </p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem"> <a class="link" href="https://book.kubebuilder.io/reference/generating-crd.html">CRD generation</a> </li><li class="listitem"> <a class="link" href="https://book.kubebuilder.io/reference/markers.html">Markers</a> </li><li class="listitem"> <a class="link" href="https://book.kubebuilder.io/reference/markers/crd-validation.html">List of OpenAPIv3 validation markers</a> </li></ul></div></li><li class="listitem"> For more details about OpenAPIv3 validation schemas in CRDs, see the <a class="link" href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema">Kubernetes documentation</a>. </li></ul></div></section></section></section><section class="section" id="osdk-golang-implement-controller_osdk-golang-tutorial"><div class="titlepage"><div><div><h4 class="title">5.4.2.4. Implementing the controller</h4></div></div></div><p> After creating a new API and controller, you can implement the controller logic. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> For this example, replace the generated controller file <code class="literal">controllers/memcached_controller.go</code> with following example implementation: </p><div class="example" id="idm140209515967600"><p class="title"><strong>Example 5.28. Example <code class="literal">memcached_controller.go</code></strong></p><div class="example-contents"><pre class="programlisting language-golang">/* Copyright 2020. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package controllers import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "reflect" "context" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" cachev1alpha1 "github.com/example/memcached-operator/api/v1alpha1" ) // MemcachedReconciler reconciles a Memcached object type MemcachedReconciler struct { client.Client Log logr.Logger Scheme *runtime.Scheme } // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list; // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. // TODO(user): Modify the Reconcile function to compare the state specified by // the Memcached object against the actual cluster state, and then // perform operations to make the cluster state reflect the state specified by // the user. // // For more details, check Reconcile and its Result here: // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.7.0/pkg/reconcile func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := r.Log.WithValues("memcached", req.NamespacedName) // Fetch the Memcached instance memcached := &amp;cachev1alpha1.Memcached{} err := r.Get(ctx, req.NamespacedName, memcached) if err != nil { if errors.IsNotFound(err) { // Request object not found, could have been deleted after reconcile request. // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. // Return and don't requeue log.Info("Memcached resource not found. Ignoring since object must be deleted") return ctrl.Result{}, nil } // Error reading the object - requeue the request. log.Error(err, "Failed to get Memcached") return ctrl.Result{}, err } // Check if the deployment already exists, if not create a new one found := &amp;appsv1.Deployment{} err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found) if err != nil &amp;&amp; errors.IsNotFound(err) { // Define a new deployment dep := r.deploymentForMemcached(memcached) log.Info("Creating a new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) err = r.Create(ctx, dep) if err != nil { log.Error(err, "Failed to create new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) return ctrl.Result{}, err } // Deployment created successfully - return and requeue return ctrl.Result{Requeue: true}, nil } else if err != nil { log.Error(err, "Failed to get Deployment") return ctrl.Result{}, err } // Ensure the deployment size is the same as the spec size := memcached.Spec.Size if *found.Spec.Replicas != size { found.Spec.Replicas = &amp;size err = r.Update(ctx, found) if err != nil { log.Error(err, "Failed to update Deployment", "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name) return ctrl.Result{}, err } // Spec updated - return and requeue return ctrl.Result{Requeue: true}, nil } // Update the Memcached status with the pod names // List the pods for this memcached's deployment podList := &amp;corev1.PodList{} listOpts := []client.ListOption{ client.InNamespace(memcached.Namespace), client.MatchingLabels(labelsForMemcached(memcached.Name)), } if err = r.List(ctx, podList, listOpts...); err != nil { log.Error(err, "Failed to list pods", "Memcached.Namespace", memcached.Namespace, "Memcached.Name", memcached.Name) return ctrl.Result{}, err } podNames := getPodNames(podList.Items) // Update status.Nodes if needed if !reflect.DeepEqual(podNames, memcached.Status.Nodes) { memcached.Status.Nodes = podNames err := r.Status().Update(ctx, memcached) if err != nil { log.Error(err, "Failed to update Memcached status") return ctrl.Result{}, err } } return ctrl.Result{}, nil } // deploymentForMemcached returns a memcached Deployment object func (r *MemcachedReconciler) deploymentForMemcached(m *cachev1alpha1.Memcached) *appsv1.Deployment { ls := labelsForMemcached(m.Name) replicas := m.Spec.Size dep := &amp;appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: m.Name, Namespace: m.Namespace, }, Spec: appsv1.DeploymentSpec{ Replicas: &amp;replicas, Selector: &amp;metav1.LabelSelector{ MatchLabels: ls, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: ls, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{{ Image: "memcached:1.4.36-alpine", Name: "memcached", Command: []string{"memcached", "-m=64", "-o", "modern", "-v"}, Ports: []corev1.ContainerPort{{ ContainerPort: 11211, Name: "memcached", }}, }}, }, }, }, } // Set Memcached instance as the owner and controller ctrl.SetControllerReference(m, dep, r.Scheme) return dep } // labelsForMemcached returns the labels for selecting the resources // belonging to the given memcached CR name. func labelsForMemcached(name string) map[string]string { return map[string]string{"app": "memcached", "memcached_cr": name} } // getPodNames returns the pod names of the array of pods passed in func getPodNames(pods []corev1.Pod) []string { var podNames []string for _, pod := range pods { podNames = append(podNames, pod.Name) } return podNames } // SetupWithManager sets up the controller with the Manager. func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&amp;cachev1alpha1.Memcached{}). Owns(&amp;appsv1.Deployment{}). Complete(r) }</pre></div></div><p class="simpara"> The example controller runs the following reconciliation logic for each <code class="literal">Memcached</code> custom resource (CR): </p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem"> Create a Memcached deployment if it does not exist. </li><li class="listitem"> Ensure that the deployment size is the same as specified by the <code class="literal">Memcached</code> CR spec. </li><li class="listitem"> Update the <code class="literal">Memcached</code> CR status with the names of the <code class="literal">memcached</code> pods. </li></ul></div></li></ul></div><p> The next subsections explain how the controller in the example implementation watches resources and how the reconcile loop is triggered. You can skip these subsections to go directly to <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-run-operator_osdk-golang-tutorial">Running the Operator</a>. </p><section class="section" id="osdk-golang-controller-resources_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.4.1. Resources watched by the controller</h5></div></div></div><p> The <code class="literal">SetupWithManager()</code> function in <code class="literal">controllers/memcached_controller.go</code> specifies how the controller is built to watch a CR and other resources that are owned and managed by that controller. </p><pre class="programlisting language-go">import ( ... appsv1 "k8s.io/api/apps/v1" ... ) func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&amp;cachev1.Memcached{}). Owns(&amp;appsv1.Deployment{}). Complete(r) }</pre><p> <code class="literal">NewControllerManagedBy()</code> provides a controller builder that allows various controller configurations. </p><p> <code class="literal">For(&amp;cachev1.Memcached{})</code> specifies the <code class="literal">Memcached</code> type as the primary resource to watch. For each Add, Update, or Delete event for a <code class="literal">Memcached</code> type, the reconcile loop is sent a reconcile <code class="literal">Request</code> argument, which consists of a namespace and name key, for that <code class="literal">Memcached</code> object. </p><p> <code class="literal">Owns(&amp;appsv1.Deployment{})</code> specifies the <code class="literal">Deployment</code> type as the secondary resource to watch. For each <code class="literal">Deployment</code> type Add, Update, or Delete event, the event handler maps each event to a reconcile request for the owner of the deployment. In this case, the owner is the <code class="literal">Memcached</code> object for which the deployment was created. </p></section><section class="section" id="osdk-golang-controller-configs_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.4.2. Controller configurations</h5></div></div></div><p> You can initialize a controller by using many other useful configurations. For example: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Set the maximum number of concurrent reconciles for the controller by using the <code class="literal">MaxConcurrentReconciles</code> option, which defaults to <code class="literal">1</code>: </p><pre class="programlisting language-go">func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&amp;cachev1.Memcached{}). Owns(&amp;appsv1.Deployment{}). WithOptions(controller.Options{ MaxConcurrentReconciles: 2, }). Complete(r) }</pre></li><li class="listitem"> Filter watch events using predicates. </li><li class="listitem"> Choose the type of <a class="link" href="https://godoc.org/sigs.k8s.io/controller-runtime/pkg/handler#hdr-EventHandlers">EventHandler</a> to change how a watch event translates to reconcile requests for the reconcile loop. For Operator relationships that are more complex than primary and secondary resources, you can use the <code class="literal">EnqueueRequestsFromMapFunc</code> handler to transform a watch event into an arbitrary set of reconcile requests. </li></ul></div><p> For more details on these and other configurations, see the upstream <a class="link" href="https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/builder#example-Builder">Builder</a> and <a class="link" href="https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/controller">Controller</a> GoDocs. </p></section><section class="section" id="osdk-golang-controller-reconcile-loop_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.4.3. Reconcile loop</h5></div></div></div><p> Every controller has a reconciler object with a <code class="literal">Reconcile()</code> method that implements the reconcile loop. The reconcile loop is passed the <code class="literal">Request</code> argument, which is a namespace and name key used to find the primary resource object, <code class="literal">Memcached</code>, from the cache: </p><pre class="programlisting language-go">import ( ctrl "sigs.k8s.io/controller-runtime" cachev1 "github.com/example-inc/memcached-operator/api/v1" ... ) func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { // Lookup the Memcached instance for this reconcile request memcached := &amp;cachev1.Memcached{} err := r.Get(ctx, req.NamespacedName, memcached) ... }</pre><p> Based on the return values, result, and error, the request might be requeued and the reconcile loop might be triggered again: </p><pre class="programlisting language-go">// Reconcile successful - don't requeue return ctrl.Result{}, nil // Reconcile failed due to error - requeue return ctrl.Result{}, err // Requeue for any reason other than an error return ctrl.Result{Requeue: true}, nil</pre><p> You can set the <code class="literal">Result.RequeueAfter</code> to requeue the request after a grace period as well: </p><pre class="programlisting language-go">import "time" // Reconcile for any reason other than an error after 5 seconds return ctrl.Result{RequeueAfter: time.Second*5}, nil</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> You can return <code class="literal">Result</code> with <code class="literal">RequeueAfter</code> set to periodically reconcile a CR. </p></div></rh-alert><p> For more on reconcilers, clients, and interacting with resource events, see the <a class="link" href="https://sdk.operatorframework.io/docs/building-operators/golang/references/client/">Controller Runtime Client API</a> documentation. </p></section><section class="section" id="osdk-golang-controller-rbac-markers_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.4.4. Permissions and RBAC manifests</h5></div></div></div><p> The controller requires certain RBAC permissions to interact with the resources it manages. These are specified using RBAC markers, such as the following: </p><pre class="programlisting language-go">// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch // +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list; func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { ... }</pre><p> The <code class="literal">ClusterRole</code> object manifest at <code class="literal">config/rbac/role.yaml</code> is generated from the previous markers by using the <code class="literal">controller-gen</code> utility whenever the <code class="literal">make manifests</code> command is run. </p></section></section><section class="section" id="osdk-run-operator_osdk-golang-tutorial"><div class="titlepage"><div><div><h4 class="title">5.4.2.5. Running the Operator</h4></div></div></div><p> There are three ways you can use the Operator SDK CLI to build and run your Operator: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Run locally outside the cluster as a Go program. </li><li class="listitem"> Run as a deployment on the cluster. </li><li class="listitem"> Bundle your Operator and use Operator Lifecycle Manager (OLM) to deploy on the cluster. </li></ul></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> Before running your Go-based Operator as either a deployment on OpenShift Container Platform or as a bundle that uses OLM, ensure that your project has been updated to use supported images. </p></div></rh-alert><section class="section" id="osdk-run-locally_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.5.1. Running locally outside the cluster</h5></div></div></div><p> You can run your Operator project as a Go program outside of the cluster. This is useful for development purposes to speed up deployment and testing. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Run the following command to install the custom resource definitions (CRDs) in the cluster configured in your <code class="literal">~/.kube/config</code> file and run the Operator locally: </p><pre class="programlisting language-terminal">$ make install run</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">... 2021-01-10T21:09:29.016-0700 INFO controller-runtime.metrics metrics server is starting to listen {"addr": ":8080"} 2021-01-10T21:09:29.017-0700 INFO setup starting manager 2021-01-10T21:09:29.017-0700 INFO controller-runtime.manager starting metrics server {"path": "/metrics"} 2021-01-10T21:09:29.018-0700 INFO controller-runtime.manager.controller.memcached Starting EventSource {"reconciler group": "cache.example.com", "reconciler kind": "Memcached", "source": "kind source: /, Kind="} 2021-01-10T21:09:29.218-0700 INFO controller-runtime.manager.controller.memcached Starting Controller {"reconciler group": "cache.example.com", "reconciler kind": "Memcached"} 2021-01-10T21:09:29.218-0700 INFO controller-runtime.manager.controller.memcached Starting workers {"reconciler group": "cache.example.com", "reconciler kind": "Memcached", "worker count": 1}</pre> <p></p></div></li></ul></div></section><section class="section" id="osdk-run-deployment_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.5.2. Running as a deployment on the cluster</h5></div></div></div><p> You can run your Operator project as a deployment on your cluster. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Prepared your Go-based Operator to run on OpenShift Container Platform by updating the project to use supported images </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands to build and push the Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The name and tag of the image, for example <code class="literal">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</code>, in both the commands can also be set in your Makefile. Modify the <code class="literal">IMG ?= controller:latest</code> value to set your default image name. </p></div></rh-alert></li></ol></div></li><li class="listitem"><p class="simpara"> Run the following command to deploy the Operator: </p><pre class="programlisting language-terminal">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> By default, this command creates a namespace with the name of your Operator project in the form <code class="literal">&lt;project_name&gt;-system</code> and is used for the deployment. This command also installs the RBAC manifests from <code class="literal">config/rbac</code>. </p></li><li class="listitem"><p class="simpara"> Verify that the Operator is running: </p><pre class="programlisting language-terminal">$ oc get deployment -n &lt;project_name&gt;-system</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE &lt;project_name&gt;-controller-manager 1/1 1 1 8m</pre> <p></p></div></li></ol></div></section><section class="section" id="osdk-bundle-deploy-olm_osdk-golang-tutorial"><div class="titlepage"><div><div><h5 class="title">5.4.2.5.3. Bundling an Operator and deploying with Operator Lifecycle Manager</h5></div></div></div><section class="section" id="osdk-bundle-operator_osdk-golang-tutorial"><div class="titlepage"><div><div><h6 class="title">5.4.2.5.3.1. Bundling an Operator</h6></div></div></div><p> The Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed </li><li class="listitem"> Operator project initialized by using the Operator SDK </li><li class="listitem"> If your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands in your Operator project directory to build and push your Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li><li class="listitem"><p class="simpara"> Create your Operator bundle manifest by running the <code class="literal">make bundle</code> command, which invokes several commands, including the Operator SDK <code class="literal">generate bundle</code> and <code class="literal">bundle validate</code> subcommands: </p><pre class="programlisting language-terminal">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> Bundle manifests for an Operator describe how to display, create, and manage an application. The <code class="literal">make bundle</code> command creates the following files and directories in your Operator project: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> A bundle manifests directory named <code class="literal">bundle/manifests</code> that contains a <code class="literal">ClusterServiceVersion</code> object </li><li class="listitem"> A bundle metadata directory named <code class="literal">bundle/metadata</code> </li><li class="listitem"> All custom resource definitions (CRDs) in a <code class="literal">config/crd</code> directory </li><li class="listitem"> A Dockerfile <code class="literal">bundle.Dockerfile</code> </li></ul></div><p class="simpara"> These files are then automatically validated by using <code class="literal">operator-sdk bundle validate</code> to ensure the on-disk bundle representation is correct. </p></li><li class="listitem"><p class="simpara"> Build and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the bundle image. Set <code class="literal">BUNDLE_IMG</code> with the details for the registry, user namespace, and image tag where you intend to push the image: </p><pre class="programlisting language-terminal">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li><li class="listitem"><p class="simpara"> Push the bundle image: </p><pre class="programlisting language-terminal">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li></ol></div></section><section class="section" id="osdk-deploy-olm_osdk-golang-tutorial"><div class="titlepage"><div><div><h6 class="title">5.4.2.5.3.2. Deploying an Operator with Operator Lifecycle Manager</h6></div></div></div><p> Operator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (<code class="literal">oc</code>) for all Operator lifecycle management functions without any additional tools. </p><p> The Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> Operator bundle image built and pushed to a registry </li><li class="listitem"> OLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use <code class="literal">apiextensions.k8s.io/v1</code> CRDs, for example OpenShift Container Platform 4.8) </li><li class="listitem"> Logged in to the cluster with <code class="literal">oc</code> using an account with <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> If your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Enter the following command to run the Operator on the cluster: </p><pre class="programlisting language-terminal">$ operator-sdk run bundle \ [-n &lt;namespace&gt;] \<span id="CO39-1"><!--Empty--></span><span class="callout">1</span> &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO39-1"><span class="callout">1</span></a> </dt><dd><div class="para"> By default, the command installs the Operator in the currently active project in your <code class="literal">~/.kube/config</code> file. You can add the <code class="literal">-n</code> flag to set a different namespace scope for the installation. </div></dd></dl></div><p class="simpara"> This command performs the following actions: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Create an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production. </li><li class="listitem"> Create a catalog source that points to your new index image, which enables OperatorHub to discover your Operator. </li><li class="listitem"> Deploy your Operator to your cluster by creating an <code class="literal">OperatorGroup</code>, <code class="literal">Subscription</code>, <code class="literal">InstallPlan</code>, and all other required objects, including RBAC. </li></ul></div></li></ol></div></section></section></section><section class="section" id="osdk-create-cr_osdk-golang-tutorial"><div class="titlepage"><div><div><h4 class="title">5.4.2.6. Creating a custom resource</h4></div></div></div><p> After your Operator is installed, you can test it by creating a custom resource (CR) that is now provided on the cluster by the Operator. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Example Memcached Operator, which provides the <code class="literal">Memcached</code> CR, installed on a cluster </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Change to the namespace where your Operator is installed. For example, if you deployed the Operator using the <code class="literal">make deploy</code> command: </p><pre class="programlisting language-terminal">$ oc project memcached-operator-system</pre></li><li class="listitem"><p class="simpara"> Edit the sample <code class="literal">Memcached</code> CR manifest at <code class="literal">config/samples/cache_v1_memcached.yaml</code> to contain the following specification: </p><pre class="programlisting language-yaml">apiVersion: cache.example.com/v1 kind: Memcached metadata: name: memcached-sample ... spec: ... size: 3</pre></li><li class="listitem"><p class="simpara"> Create the CR: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/cache_v1_memcached.yaml</pre></li><li class="listitem"><p class="simpara"> Ensure that the <code class="literal">Memcached</code> Operator creates the deployment for the sample CR with the correct size: </p><pre class="programlisting language-terminal">$ oc get deployments</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE memcached-operator-controller-manager 1/1 1 1 8m memcached-sample 3/3 3 3 1m</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the pods and CR status to confirm the status is updated with the Memcached pod names. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Check the pods: </p><pre class="programlisting language-terminal">$ oc get pods</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY STATUS RESTARTS AGE memcached-sample-6fd7c98d8-7dqdr 1/1 Running 0 1m memcached-sample-6fd7c98d8-g5k7v 1/1 Running 0 1m memcached-sample-6fd7c98d8-m7vn7 1/1 Running 0 1m</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the CR status: </p><pre class="programlisting language-terminal">$ oc get memcached/memcached-sample -o yaml</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: cache.example.com/v1 kind: Memcached metadata: ... name: memcached-sample ... spec: size: 3 status: nodes: - memcached-sample-6fd7c98d8-7dqdr - memcached-sample-6fd7c98d8-g5k7v - memcached-sample-6fd7c98d8-m7vn7</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> Update the deployment size. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Update <code class="literal">config/samples/cache_v1_memcached.yaml</code> file to change the <code class="literal">spec.size</code> field in the <code class="literal">Memcached</code> CR from <code class="literal">3</code> to <code class="literal">5</code>: </p><pre class="programlisting language-terminal">$ oc patch memcached memcached-sample \ -p '{"spec":{"size": 5}}' \ --type=merge</pre></li><li class="listitem"><p class="simpara"> Confirm that the Operator changes the deployment size: </p><pre class="programlisting language-terminal">$ oc get deployments</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE memcached-operator-controller-manager 1/1 1 1 10m memcached-sample 5/5 5 5 3m</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> Clean up the resources that have been created as part of this tutorial. </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> If you used the <code class="literal">make deploy</code> command to test the Operator, run the following command: </p><pre class="programlisting language-terminal">$ make undeploy</pre></li><li class="listitem"><p class="simpara"> If you used the <code class="literal">operator-sdk run bundle</code> command to test the Operator, run the following command: </p><pre class="programlisting language-terminal">$ operator-sdk cleanup &lt;project_name&gt;</pre></li></ul></div></li></ol></div></section><section class="section _additional-resources" id="osdk-golang-tutorial-addtl-resources"><div class="titlepage"><div><div><h4 class="title">5.4.2.7. Additional resources</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-golang-project-layout">Project layout for Go-based Operators</a> to learn about the directory structures created by the Operator SDK. </li></ul></div></section></section><section class="section" id="osdk-golang-project-layout"><div class="titlepage"><div><div><h3 class="title">5.4.3. Project layout for Go-based Operators</h3></div></div></div><p> The <code class="literal">operator-sdk</code> CLI can generate, or <span class="emphasis"><em>scaffold</em></span>, a number of packages and files for each Operator project. </p><section class="section" id="osdk-golang-project-layout_osdk-golang-project-layout"><div class="titlepage"><div><div><h4 class="title">5.4.3.1. Go-based project layout</h4></div></div></div><p> Go-based Operator projects, the default type, generated using the <code class="literal">operator-sdk init</code> command contain the following files and directories: </p><rh-table><table class="lt-4-cols lt-7-rows"><colgroup><col style="width: 20%; " class="col_1"><!--Empty--><col style="width: 80%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209515730048" scope="col">File or directory</th><th align="left" valign="top" id="idm140209515728960" scope="col">Purpose</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209515730048"> <p> <code class="literal">main.go</code> </p> </td><td align="left" valign="top" headers="idm140209515728960"> <p> Main program of the Operator. This instantiates a new manager that registers all custom resource definitions (CRDs) in the <code class="literal">apis/</code> directory and starts all controllers in the <code class="literal">controllers/</code> directory. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515730048"> <p> <code class="literal">apis/</code> </p> </td><td align="left" valign="top" headers="idm140209515728960"> <p> Directory tree that defines the APIs of the CRDs. You must edit the <code class="literal">apis/&lt;version&gt;/&lt;kind&gt;_types.go</code> files to define the API for each resource type and import these packages in your controllers to watch for these resource types. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515730048"> <p> <code class="literal">controllers/</code> </p> </td><td align="left" valign="top" headers="idm140209515728960"> <p> Controller implementations. Edit the <code class="literal">controller/&lt;kind&gt;_controller.go</code> files to define the reconcile logic of the controller for handling a resource type of the specified kind. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515730048"> <p> <code class="literal">config/</code> </p> </td><td align="left" valign="top" headers="idm140209515728960"> <p> Kubernetes manifests used to deploy your controller on a cluster, including CRDs, RBAC, and certificates. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515730048"> <p> <code class="literal">Makefile</code> </p> </td><td align="left" valign="top" headers="idm140209515728960"> <p> Targets used to build and deploy your controller. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515730048"> <p> <code class="literal">Dockerfile</code> </p> </td><td align="left" valign="top" headers="idm140209515728960"> <p> Instructions used by a container engine to build your Operator. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515730048"> <p> <code class="literal">manifests/</code> </p> </td><td align="left" valign="top" headers="idm140209515728960"> <p> Kubernetes manifests for registering CRDs, setting up RBAC, and deploying the Operator as a deployment. </p> </td></tr></tbody></table></rh-table></section></section></section><section class="section" id="ansible-based-operators"><div class="titlepage"><div><div><h2 class="title">5.5. Ansible-based Operators</h2></div></div></div><section class="section" id="osdk-ansible-quickstart"><div class="titlepage"><div><div><h3 class="title">5.5.1. Getting started with Operator SDK for Ansible-based Operators</h3></div></div></div><p> The Operator SDK includes options for generating an Operator project that leverages existing Ansible playbooks and modules to deploy Kubernetes resources as a unified application, without having to write any Go code. </p><p> To demonstrate the basics of setting up and running an <a class="link" href="https://docs.ansible.com/ansible/latest/index.html">Ansible</a>-based Operator using tools and libraries provided by the Operator SDK, Operator developers can build an example Ansible-based Operator for Memcached, a distributed key-value store, and deploy it to a cluster. </p><section class="section" id="osdk-common-prereqs_osdk-ansible-quickstart"><div class="titlepage"><div><div><h4 class="title">5.5.1.1. Prerequisites</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli">Operator SDK CLI installed</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli">OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed</a> </li><li class="listitem"> <a class="link" href="https://docs.ansible.com/ansible/2.9/index.html">Ansible</a> version v2.9.0 </li><li class="listitem"> <a class="link" href="https://ansible-runner.readthedocs.io/en/latest/install.html">Ansible Runner</a> version v1.1.0+ </li><li class="listitem"> <a class="link" href="https://github.com/ansible/ansible-runner-http">Ansible Runner HTTP Event Emitter plugin</a> version v1.0.0+ </li><li class="listitem"> <a class="link" href="https://pypi.org/project/openshift/">OpenShift Python client</a> version v0.11.2+ </li><li class="listitem"> Logged into an OpenShift Container Platform 4.8 cluster with <code class="literal">oc</code> with an account that has <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> To allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret </li></ul></div></section><section class="section" id="osdk-quickstart_osdk-ansible-quickstart"><div class="titlepage"><div><div><h4 class="title">5.5.1.2. Creating and deploying Ansible-based Operators</h4></div></div></div><p> You can build and deploy a simple Ansible-based Operator for Memcached by using the Operator SDK. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create a project.</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Create your project directory: </p><pre class="programlisting language-terminal">$ mkdir memcached-operator</pre></li><li class="listitem"><p class="simpara"> Change into the project directory: </p><pre class="programlisting language-terminal">$ cd memcached-operator</pre></li><li class="listitem"><p class="simpara"> Run the <code class="literal">operator-sdk init</code> command with the <code class="literal">ansible</code> plugin to initialize the project: </p><pre class="programlisting language-terminal">$ operator-sdk init \ --plugins=ansible \ --domain=example.com</pre></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create an API.</strong></span> </p><p class="simpara"> Create a simple Memcached API: </p><pre class="programlisting language-terminal">$ operator-sdk create api \ --group cache \ --version v1 \ --kind Memcached \ --generate-role <span id="CO40-1"><!--Empty--></span><span class="callout">1</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO40-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Generates an Ansible role for the API. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Build and push the Operator image.</strong></span> </p><p class="simpara"> Use the default <code class="literal">Makefile</code> targets to build and push your Operator. Set <code class="literal">IMG</code> with a pull spec for your image that uses a registry you can push to: </p><pre class="programlisting language-terminal">$ make docker-build docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Run the Operator.</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Install the CRD: </p><pre class="programlisting language-terminal">$ make install</pre></li><li class="listitem"><p class="simpara"> Deploy the project to the cluster. Set <code class="literal">IMG</code> to the image that you pushed: </p><pre class="programlisting language-terminal">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create a sample custom resource (CR).</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Create a sample CR: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/cache_v1_memcached.yaml \ -n memcached-operator-system</pre></li><li class="listitem"><p class="simpara"> Watch for the CR to reconcile the Operator: </p><pre class="programlisting language-terminal">$ oc logs deployment.apps/memcached-operator-controller-manager \ -c manager \ -n memcached-operator-system</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">... I0205 17:48:45.881666 7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator {"level":"info","ts":1612547325.8819902,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"} {"level":"info","ts":1612547325.98242,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"} {"level":"info","ts":1612547325.9824686,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":4} {"level":"info","ts":1612547348.8311093,"logger":"runner","msg":"Ansible-runner exited successfully","job":"4037200794235010051","name":"memcached-sample","namespace":"memcached-operator-system"}</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Clean up.</strong></span> </p><p class="simpara"> Run the following command to clean up the resources that have been created as part of this procedure: </p><pre class="programlisting language-terminal">$ make undeploy</pre></li></ol></div></section><section class="section" id="osdk-ansible-quickstart-next-steps"><div class="titlepage"><div><div><h4 class="title">5.5.1.3. Next steps</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-tutorial">Operator SDK tutorial for Ansible-based Operators</a> for a more in-depth walkthrough on building an Ansible-based Operator. </li></ul></div></section></section><section class="section" id="osdk-ansible-tutorial"><div class="titlepage"><div><div><h3 class="title">5.5.2. Operator SDK tutorial for Ansible-based Operators</h3></div></div></div><p> Operator developers can take advantage of <a class="link" href="https://docs.ansible.com/ansible/latest/index.html">Ansible</a> support in the Operator SDK to build an example Ansible-based Operator for Memcached, a distributed key-value store, and manage its lifecycle. This tutorial walks through the following process: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Create a Memcached deployment </li><li class="listitem"> Ensure that the deployment size is the same as specified by the <code class="literal">Memcached</code> custom resource (CR) spec </li><li class="listitem"> Update the <code class="literal">Memcached</code> CR status using the status writer with the names of the <code class="literal">memcached</code> pods </li></ul></div><p> This process is accomplished by using two centerpieces of the Operator Framework: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Operator SDK</span></dt><dd> The <code class="literal">operator-sdk</code> CLI tool and <code class="literal">controller-runtime</code> library API </dd><dt><span class="term">Operator Lifecycle Manager (OLM)</span></dt><dd> Installation, upgrade, and role-based access control (RBAC) of Operators on a cluster </dd></dl></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> This tutorial goes into greater detail than <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-quickstart">Getting started with Operator SDK for Ansible-based Operators</a>. </p></div></rh-alert><section class="section" id="osdk-common-prereqs_osdk-ansible-tutorial"><div class="titlepage"><div><div><h4 class="title">5.5.2.1. Prerequisites</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli">Operator SDK CLI installed</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli">OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed</a> </li><li class="listitem"> <a class="link" href="https://docs.ansible.com/ansible/2.9/index.html">Ansible</a> version v2.9.0 </li><li class="listitem"> <a class="link" href="https://ansible-runner.readthedocs.io/en/latest/install.html">Ansible Runner</a> version v1.1.0+ </li><li class="listitem"> <a class="link" href="https://github.com/ansible/ansible-runner-http">Ansible Runner HTTP Event Emitter plugin</a> version v1.0.0+ </li><li class="listitem"> <a class="link" href="https://pypi.org/project/openshift/">OpenShift Python client</a> version v0.11.2+ </li><li class="listitem"> Logged into an OpenShift Container Platform 4.8 cluster with <code class="literal">oc</code> with an account that has <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> To allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret </li></ul></div></section><section class="section" id="osdk-create-project_osdk-ansible-tutorial"><div class="titlepage"><div><div><h4 class="title">5.5.2.2. Creating a project</h4></div></div></div><p> Use the Operator SDK CLI to create a project called <code class="literal">memcached-operator</code>. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Create a directory for the project: </p><pre class="programlisting language-terminal">$ mkdir -p $HOME/projects/memcached-operator</pre></li><li class="listitem"><p class="simpara"> Change to the directory: </p><pre class="programlisting language-terminal">$ cd $HOME/projects/memcached-operator</pre></li><li class="listitem"><p class="simpara"> Run the <code class="literal">operator-sdk init</code> command with the <code class="literal">ansible</code> plugin to initialize the project: </p><pre class="programlisting language-terminal">$ operator-sdk init \ --plugins=ansible \ --domain=example.com</pre></li></ol></div><section class="section" id="osdk-project-file_osdk-ansible-tutorial"><div class="titlepage"><div><div><h5 class="title">5.5.2.2.1. PROJECT file</h5></div></div></div><p> Among the files generated by the <code class="literal">operator-sdk init</code> command is a Kubebuilder <code class="literal">PROJECT</code> file. Subsequent <code class="literal">operator-sdk</code> commands, as well as <code class="literal">help</code> output, that are run from the project root read this file and are aware that the project type is Ansible. For example: </p><pre class="programlisting language-yaml">domain: example.com layout: ansible.sdk.operatorframework.io/v1 projectName: memcached-operator version: 3</pre></section></section><section class="section" id="osdk-ansible-create-api-controller_osdk-ansible-tutorial"><div class="titlepage"><div><div><h4 class="title">5.5.2.3. Creating an API</h4></div></div></div><p> Use the Operator SDK CLI to create a Memcached API. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Run the following command to create an API with group <code class="literal">cache</code>, version, <code class="literal">v1</code>, and kind <code class="literal">Memcached</code>: </p><pre class="programlisting language-terminal">$ operator-sdk create api \ --group cache \ --version v1 \ --kind Memcached \ --generate-role <span id="CO41-1"><!--Empty--></span><span class="callout">1</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO41-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Generates an Ansible role for the API. </div></dd></dl></div></li></ul></div><p> After creating the API, your Operator project updates with the following structure: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Memcached CRD</span></dt><dd> Includes a sample <code class="literal">Memcached</code> resource </dd><dt><span class="term">Manager</span></dt><dd><p class="simpara"> Program that reconciles the state of the cluster to the desired state by using: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> A reconciler, either an Ansible role or playbook </li><li class="listitem"> A <code class="literal">watches.yaml</code> file, which connects the <code class="literal">Memcached</code> resource to the <code class="literal">memcached</code> Ansible role </li></ul></div></dd></dl></div></section><section class="section" id="osdk-ansible-modify-manager_osdk-ansible-tutorial"><div class="titlepage"><div><div><h4 class="title">5.5.2.4. Modifying the manager</h4></div></div></div><p> Update your Operator project to provide the reconcile logic, in the form of an Ansible role, which runs every time a <code class="literal">Memcached</code> resource is created, updated, or deleted. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Update the <code class="literal">roles/memcached/tasks/main.yml</code> file with the following structure: </p><pre class="programlisting language-yaml">--- - name: start memcached community.kubernetes.k8s: definition: kind: Deployment apiVersion: apps/v1 metadata: name: '{{ ansible_operator_meta.name }}-memcached' namespace: '{{ ansible_operator_meta.namespace }}' spec: replicas: "{{size}}" selector: matchLabels: app: memcached template: metadata: labels: app: memcached spec: containers: - name: memcached command: - memcached - -m=64 - -o - modern - -v image: "docker.io/memcached:1.4.36-alpine" ports: - containerPort: 11211</pre><p class="simpara"> This <code class="literal">memcached</code> role ensures a <code class="literal">memcached</code> deployment exist and sets the deployment size. </p></li><li class="listitem"><p class="simpara"> Set default values for variables used in your Ansible role by editing the <code class="literal">roles/memcached/defaults/main.yml</code> file: </p><pre class="programlisting language-yaml">--- # defaults file for Memcached size: 1</pre></li><li class="listitem"><p class="simpara"> Update the <code class="literal">Memcached</code> sample resource in the <code class="literal">config/samples/cache_v1_memcached.yaml</code> file with the following structure: </p><pre class="programlisting language-yaml">apiVersion: cache.example.com/v1 kind: Memcached metadata: name: memcached-sample spec: size: 3</pre><p class="simpara"> The key-value pairs in the custom resource (CR) spec are passed to Ansible as extra variables. </p></li></ol></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The names of all variables in the <code class="literal">spec</code> field are converted to snake case, meaning lowercase with an underscore, by the Operator before running Ansible. For example, <code class="literal">serviceAccount</code> in the spec becomes <code class="literal">service_account</code> in Ansible. </p><p> You can disable this case conversion by setting the <code class="literal">snakeCaseParameters</code> option to <code class="literal">false</code> in your <code class="literal">watches.yaml</code> file. It is recommended that you perform some type validation in Ansible on the variables to ensure that your application is receiving expected input. </p></div></rh-alert></section><section class="section" id="osdk-run-operator_osdk-ansible-tutorial"><div class="titlepage"><div><div><h4 class="title">5.5.2.5. Running the Operator</h4></div></div></div><p> There are three ways you can use the Operator SDK CLI to build and run your Operator: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Run locally outside the cluster as a Go program. </li><li class="listitem"> Run as a deployment on the cluster. </li><li class="listitem"> Bundle your Operator and use Operator Lifecycle Manager (OLM) to deploy on the cluster. </li></ul></div><section class="section" id="osdk-run-locally_osdk-ansible-tutorial"><div class="titlepage"><div><div><h5 class="title">5.5.2.5.1. Running locally outside the cluster</h5></div></div></div><p> You can run your Operator project as a Go program outside of the cluster. This is useful for development purposes to speed up deployment and testing. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Run the following command to install the custom resource definitions (CRDs) in the cluster configured in your <code class="literal">~/.kube/config</code> file and run the Operator locally: </p><pre class="programlisting language-terminal">$ make install run</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">... {"level":"info","ts":1612589622.7888272,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"} {"level":"info","ts":1612589622.7897573,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"} {"level":"info","ts":1612589622.789971,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"} {"level":"info","ts":1612589622.7899997,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"} {"level":"info","ts":1612589622.8904517,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"} {"level":"info","ts":1612589622.8905244,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}</pre> <p></p></div></li></ul></div></section><section class="section" id="osdk-run-deployment_osdk-ansible-tutorial"><div class="titlepage"><div><div><h5 class="title">5.5.2.5.2. Running as a deployment on the cluster</h5></div></div></div><p> You can run your Operator project as a deployment on your cluster. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands to build and push the Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The name and tag of the image, for example <code class="literal">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</code>, in both the commands can also be set in your Makefile. Modify the <code class="literal">IMG ?= controller:latest</code> value to set your default image name. </p></div></rh-alert></li></ol></div></li><li class="listitem"><p class="simpara"> Run the following command to deploy the Operator: </p><pre class="programlisting language-terminal">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> By default, this command creates a namespace with the name of your Operator project in the form <code class="literal">&lt;project_name&gt;-system</code> and is used for the deployment. This command also installs the RBAC manifests from <code class="literal">config/rbac</code>. </p></li><li class="listitem"><p class="simpara"> Verify that the Operator is running: </p><pre class="programlisting language-terminal">$ oc get deployment -n &lt;project_name&gt;-system</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE &lt;project_name&gt;-controller-manager 1/1 1 1 8m</pre> <p></p></div></li></ol></div></section><section class="section" id="osdk-bundle-deploy-olm_osdk-ansible-tutorial"><div class="titlepage"><div><div><h5 class="title">5.5.2.5.3. Bundling an Operator and deploying with Operator Lifecycle Manager</h5></div></div></div><section class="section" id="osdk-bundle-operator_osdk-ansible-tutorial"><div class="titlepage"><div><div><h6 class="title">5.5.2.5.3.1. Bundling an Operator</h6></div></div></div><p> The Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed </li><li class="listitem"> Operator project initialized by using the Operator SDK </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands in your Operator project directory to build and push your Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li><li class="listitem"><p class="simpara"> Create your Operator bundle manifest by running the <code class="literal">make bundle</code> command, which invokes several commands, including the Operator SDK <code class="literal">generate bundle</code> and <code class="literal">bundle validate</code> subcommands: </p><pre class="programlisting language-terminal">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> Bundle manifests for an Operator describe how to display, create, and manage an application. The <code class="literal">make bundle</code> command creates the following files and directories in your Operator project: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> A bundle manifests directory named <code class="literal">bundle/manifests</code> that contains a <code class="literal">ClusterServiceVersion</code> object </li><li class="listitem"> A bundle metadata directory named <code class="literal">bundle/metadata</code> </li><li class="listitem"> All custom resource definitions (CRDs) in a <code class="literal">config/crd</code> directory </li><li class="listitem"> A Dockerfile <code class="literal">bundle.Dockerfile</code> </li></ul></div><p class="simpara"> These files are then automatically validated by using <code class="literal">operator-sdk bundle validate</code> to ensure the on-disk bundle representation is correct. </p></li><li class="listitem"><p class="simpara"> Build and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the bundle image. Set <code class="literal">BUNDLE_IMG</code> with the details for the registry, user namespace, and image tag where you intend to push the image: </p><pre class="programlisting language-terminal">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li><li class="listitem"><p class="simpara"> Push the bundle image: </p><pre class="programlisting language-terminal">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li></ol></div></section><section class="section" id="osdk-deploy-olm_osdk-ansible-tutorial"><div class="titlepage"><div><div><h6 class="title">5.5.2.5.3.2. Deploying an Operator with Operator Lifecycle Manager</h6></div></div></div><p> Operator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (<code class="literal">oc</code>) for all Operator lifecycle management functions without any additional tools. </p><p> The Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> Operator bundle image built and pushed to a registry </li><li class="listitem"> OLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use <code class="literal">apiextensions.k8s.io/v1</code> CRDs, for example OpenShift Container Platform 4.8) </li><li class="listitem"> Logged in to the cluster with <code class="literal">oc</code> using an account with <code class="literal">cluster-admin</code> permissions </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Enter the following command to run the Operator on the cluster: </p><pre class="programlisting language-terminal">$ operator-sdk run bundle \ [-n &lt;namespace&gt;] \<span id="CO42-1"><!--Empty--></span><span class="callout">1</span> &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO42-1"><span class="callout">1</span></a> </dt><dd><div class="para"> By default, the command installs the Operator in the currently active project in your <code class="literal">~/.kube/config</code> file. You can add the <code class="literal">-n</code> flag to set a different namespace scope for the installation. </div></dd></dl></div><p class="simpara"> This command performs the following actions: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Create an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production. </li><li class="listitem"> Create a catalog source that points to your new index image, which enables OperatorHub to discover your Operator. </li><li class="listitem"> Deploy your Operator to your cluster by creating an <code class="literal">OperatorGroup</code>, <code class="literal">Subscription</code>, <code class="literal">InstallPlan</code>, and all other required objects, including RBAC. </li></ul></div></li></ol></div></section></section></section><section class="section" id="osdk-create-cr_osdk-ansible-tutorial"><div class="titlepage"><div><div><h4 class="title">5.5.2.6. Creating a custom resource</h4></div></div></div><p> After your Operator is installed, you can test it by creating a custom resource (CR) that is now provided on the cluster by the Operator. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Example Memcached Operator, which provides the <code class="literal">Memcached</code> CR, installed on a cluster </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Change to the namespace where your Operator is installed. For example, if you deployed the Operator using the <code class="literal">make deploy</code> command: </p><pre class="programlisting language-terminal">$ oc project memcached-operator-system</pre></li><li class="listitem"><p class="simpara"> Edit the sample <code class="literal">Memcached</code> CR manifest at <code class="literal">config/samples/cache_v1_memcached.yaml</code> to contain the following specification: </p><pre class="programlisting language-yaml">apiVersion: cache.example.com/v1 kind: Memcached metadata: name: memcached-sample ... spec: ... size: 3</pre></li><li class="listitem"><p class="simpara"> Create the CR: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/cache_v1_memcached.yaml</pre></li><li class="listitem"><p class="simpara"> Ensure that the <code class="literal">Memcached</code> Operator creates the deployment for the sample CR with the correct size: </p><pre class="programlisting language-terminal">$ oc get deployments</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE memcached-operator-controller-manager 1/1 1 1 8m memcached-sample 3/3 3 3 1m</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the pods and CR status to confirm the status is updated with the Memcached pod names. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Check the pods: </p><pre class="programlisting language-terminal">$ oc get pods</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY STATUS RESTARTS AGE memcached-sample-6fd7c98d8-7dqdr 1/1 Running 0 1m memcached-sample-6fd7c98d8-g5k7v 1/1 Running 0 1m memcached-sample-6fd7c98d8-m7vn7 1/1 Running 0 1m</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the CR status: </p><pre class="programlisting language-terminal">$ oc get memcached/memcached-sample -o yaml</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: cache.example.com/v1 kind: Memcached metadata: ... name: memcached-sample ... spec: size: 3 status: nodes: - memcached-sample-6fd7c98d8-7dqdr - memcached-sample-6fd7c98d8-g5k7v - memcached-sample-6fd7c98d8-m7vn7</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> Update the deployment size. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Update <code class="literal">config/samples/cache_v1_memcached.yaml</code> file to change the <code class="literal">spec.size</code> field in the <code class="literal">Memcached</code> CR from <code class="literal">3</code> to <code class="literal">5</code>: </p><pre class="programlisting language-terminal">$ oc patch memcached memcached-sample \ -p '{"spec":{"size": 5}}' \ --type=merge</pre></li><li class="listitem"><p class="simpara"> Confirm that the Operator changes the deployment size: </p><pre class="programlisting language-terminal">$ oc get deployments</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE memcached-operator-controller-manager 1/1 1 1 10m memcached-sample 5/5 5 5 3m</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> Clean up the resources that have been created as part of this tutorial. </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> If you used the <code class="literal">make deploy</code> command to test the Operator, run the following command: </p><pre class="programlisting language-terminal">$ make undeploy</pre></li><li class="listitem"><p class="simpara"> If you used the <code class="literal">operator-sdk run bundle</code> command to test the Operator, run the following command: </p><pre class="programlisting language-terminal">$ operator-sdk cleanup &lt;project_name&gt;</pre></li></ul></div></li></ol></div></section><section class="section _additional-resources" id="osdk-ansible-tutorial-addtl-resources"><div class="titlepage"><div><div><h4 class="title">5.5.2.7. Additional resources</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-project-layout">Project layout for Ansible-based Operators</a> to learn about the directory structures created by the Operator SDK. </li></ul></div></section></section><section class="section" id="osdk-ansible-project-layout"><div class="titlepage"><div><div><h3 class="title">5.5.3. Project layout for Ansible-based Operators</h3></div></div></div><p> The <code class="literal">operator-sdk</code> CLI can generate, or <span class="emphasis"><em>scaffold</em></span>, a number of packages and files for each Operator project. </p><section class="section" id="osdk-ansible-project-layout_osdk-ansible-project-layout"><div class="titlepage"><div><div><h4 class="title">5.5.3.1. Ansible-based project layout</h4></div></div></div><p> Ansible-based Operator projects generated using the <code class="literal">operator-sdk init --plugins ansible</code> command contain the following directories and files: </p><rh-table><table class="lt-4-cols lt-7-rows"><colgroup><col style="width: 20%; " class="col_1"><!--Empty--><col style="width: 80%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209515370688" scope="col">File or directory</th><th align="left" valign="top" id="idm140209515369600" scope="col">Purpose</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">Dockerfile</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Dockerfile for building the container image for the Operator. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">Makefile</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Targets for building, publishing, deploying the container image that wraps the Operator binary, and targets for installing and uninstalling the custom resource definition (CRD). </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">PROJECT</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> YAML file containing metadata information for the Operator. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">config/crd</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Base CRD files and the <code class="literal">kustomization.yaml</code> file settings. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">config/default</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Collects all Operator manifests for deployment. Use by the <code class="literal">make deploy</code> command. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">config/manager</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Controller manager deployment. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">config/prometheus</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> <code class="literal">ServiceMonitor</code> resource for monitoring the Operator. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">config/rbac</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Role and role binding for leader election and authentication proxy. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">config/samples</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Sample resources created for the CRDs. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">config/testing</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Sample configurations for testing. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">playbooks/</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> A subdirectory for the playbooks to run. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">roles/</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Subdirectory for the roles tree to run. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">watches.yaml</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Group/version/kind (GVK) of the resources to watch, and the Ansible invocation method. New entries are added by using the <code class="literal">create api</code> command. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">requirements.yml</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> YAML file containing the Ansible collections and role dependencies to install during a build. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209515370688"> <p> <code class="literal">molecule/</code> </p> </td><td align="left" valign="top" headers="idm140209515369600"> <p> Molecule scenarios for end-to-end testing of your role and Operator. </p> </td></tr></tbody></table></rh-table></section></section><section class="section" id="osdk-ansible-support"><div class="titlepage"><div><div><h3 class="title">5.5.4. Ansible support in Operator SDK</h3></div></div></div><section class="section" id="osdk-ansible-custom-resource-files_osdk-ansible-support"><div class="titlepage"><div><div><h4 class="title">5.5.4.1. Custom resource files</h4></div></div></div><p> Operators use the Kubernetes extension mechanism, custom resource definitions (CRDs), so your custom resource (CR) looks and acts just like the built-in, native Kubernetes objects. </p><p> The CR file format is a Kubernetes resource file. The object has mandatory and optional fields: </p><rh-table id="idm140209487797264"><table class="lt-4-cols lt-7-rows"><caption>Table 5.1. Custom resource fields</caption><colgroup><col style="width: 30%; " class="col_1"><!--Empty--><col style="width: 70%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487792432" scope="col">Field</th><th align="left" valign="top" id="idm140209487791344" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487792432"> <p> <code class="literal">apiVersion</code> </p> </td><td align="left" valign="top" headers="idm140209487791344"> <p> Version of the CR to be created. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487792432"> <p> <code class="literal">kind</code> </p> </td><td align="left" valign="top" headers="idm140209487791344"> <p> Kind of the CR to be created. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487792432"> <p> <code class="literal">metadata</code> </p> </td><td align="left" valign="top" headers="idm140209487791344"> <p> Kubernetes-specific metadata to be created. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487792432"> <p> <code class="literal">spec</code> (optional) </p> </td><td align="left" valign="top" headers="idm140209487791344"> <p> Key-value list of variables which are passed to Ansible. This field is empty by default. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487792432"> <p> <code class="literal">status</code> </p> </td><td align="left" valign="top" headers="idm140209487791344"> <p> Summarizes the current state of the object. For Ansible-based Operators, the <a class="link" href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource"><code class="literal">status</code> subresource</a> is enabled for CRDs and managed by the <code class="literal">operator_sdk.util.k8s_status</code> Ansible module by default, which includes <code class="literal">condition</code> information to the CR <code class="literal">status</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487792432"> <p> <code class="literal">annotations</code> </p> </td><td align="left" valign="top" headers="idm140209487791344"> <p> Kubernetes-specific annotations to be appended to the CR. </p> </td></tr></tbody></table></rh-table><p> The following list of CR annotations modify the behavior of the Operator: </p><rh-table id="idm140209487761008"><table class="lt-4-cols lt-7-rows"><caption>Table 5.2. Ansible-based Operator annotations</caption><colgroup><col style="width: 30%; " class="col_1"><!--Empty--><col style="width: 70%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487756160" scope="col">Annotation</th><th align="left" valign="top" id="idm140209487755072" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487756160"> <p> <code class="literal">ansible.operator-sdk/reconcile-period</code> </p> </td><td align="left" valign="top" headers="idm140209487755072"> <p> Specifies the reconciliation interval for the CR. This value is parsed using the standard Golang package <a class="link" href="https://golang.org/pkg/time/"><code class="literal">time</code></a>. Specifically, <a class="link" href="https://golang.org/pkg/time/#ParseDuration"><code class="literal">ParseDuration</code></a> is used which applies the default suffix of <code class="literal">s</code>, giving the value in seconds. </p> </td></tr></tbody></table></rh-table><div class="formalpara"><p class="title"><strong>Example Ansible-based Operator annotation</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: "test1.example.com/v1alpha1" kind: "Test1" metadata: name: "example" annotations: ansible.operator-sdk/reconcile-period: "30s"</pre> <p></p></div></section><section class="section" id="osdk-ansible-watches-file_osdk-ansible-support"><div class="titlepage"><div><div><h4 class="title">5.5.4.2. watches.yaml file</h4></div></div></div><p> A <span class="emphasis"><em>group/version/kind (GVK)</em></span> is a unique identifier for a Kubernetes API. The <code class="literal">watches.yaml</code> file contains a list of mappings from custom resources (CRs), identified by its GVK, to an Ansible role or playbook. The Operator expects this mapping file in a predefined location at <code class="literal">/opt/ansible/watches.yaml</code>. </p><rh-table id="idm140209487739776"><table class="lt-4-cols lt-7-rows"><caption>Table 5.3. watches.yaml file mappings</caption><colgroup><col style="width: 30%; " class="col_1"><!--Empty--><col style="width: 70%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487734624" scope="col">Field</th><th align="left" valign="top" id="idm140209487733536" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487734624"> <p> <code class="literal">group</code> </p> </td><td align="left" valign="top" headers="idm140209487733536"> <p> Group of CR to watch. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487734624"> <p> <code class="literal">version</code> </p> </td><td align="left" valign="top" headers="idm140209487733536"> <p> Version of CR to watch. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487734624"> <p> <code class="literal">kind</code> </p> </td><td align="left" valign="top" headers="idm140209487733536"> <p> Kind of CR to watch </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487734624"> <p> <code class="literal">role</code> (default) </p> </td><td align="left" valign="top" headers="idm140209487733536"> <p> Path to the Ansible role added to the container. For example, if your <code class="literal">roles</code> directory is at <code class="literal">/opt/ansible/roles/</code> and your role is named <code class="literal">busybox</code>, this value would be <code class="literal">/opt/ansible/roles/busybox</code>. This field is mutually exclusive with the <code class="literal">playbook</code> field. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487734624"> <p> <code class="literal">playbook</code> </p> </td><td align="left" valign="top" headers="idm140209487733536"> <p> Path to the Ansible playbook added to the container. This playbook is expected to be a way to call roles. This field is mutually exclusive with the <code class="literal">role</code> field. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487734624"> <p> <code class="literal">reconcilePeriod</code> (optional) </p> </td><td align="left" valign="top" headers="idm140209487733536"> <p> The reconciliation interval, how often the role or playbook is run, for a given CR. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487734624"> <p> <code class="literal">manageStatus</code> (optional) </p> </td><td align="left" valign="top" headers="idm140209487733536"> <p> When set to <code class="literal">true</code> (default), the Operator manages the status of the CR generically. When set to <code class="literal">false</code>, the status of the CR is managed elsewhere, by the specified role or playbook or in a separate controller. </p> </td></tr></tbody></table></rh-table><div class="formalpara"><p class="title"><strong>Example <code class="literal">watches.yaml</code> file</strong></p><p> </p><pre class="programlisting language-yaml">- version: v1alpha1 <span id="CO43-1"><!--Empty--></span><span class="callout">1</span> group: test1.example.com kind: Test1 role: /opt/ansible/roles/Test1 - version: v1alpha1 <span id="CO43-2"><!--Empty--></span><span class="callout">2</span> group: test2.example.com kind: Test2 playbook: /opt/ansible/playbook.yml - version: v1alpha1 <span id="CO43-3"><!--Empty--></span><span class="callout">3</span> group: test3.example.com kind: Test3 playbook: /opt/ansible/test3.yml reconcilePeriod: 0 manageStatus: false</pre> <p></p></div><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO43-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Simple example mapping <code class="literal">Test1</code> to the <code class="literal">test1</code> role. </div></dd><dt><a href="#CO43-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Simple example mapping <code class="literal">Test2</code> to a playbook. </div></dd><dt><a href="#CO43-3"><span class="callout">3</span></a> </dt><dd><div class="para"> More complex example for the <code class="literal">Test3</code> kind. Disables re-queuing and managing the CR status in the playbook. </div></dd></dl></div><section class="section" id="osdk-ansible-watches-file-advanced_osdk-ansible-support"><div class="titlepage"><div><div><h5 class="title">5.5.4.2.1. Advanced options</h5></div></div></div><p> Advanced features can be enabled by adding them to your <code class="literal">watches.yaml</code> file per GVK. They can go below the <code class="literal">group</code>, <code class="literal">version</code>, <code class="literal">kind</code> and <code class="literal">playbook</code> or <code class="literal">role</code> fields. </p><p> Some features can be overridden per resource using an annotation on that CR. The options that can be overridden have the annotation specified below. </p><rh-table id="idm140209487680800"><table class="gt-4-cols lt-7-rows"><caption>Table 5.4. Advanced watches.yaml file options</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 17%; " class="col_2"><!--Empty--><col style="width: 33%; " class="col_3"><!--Empty--><col style="width: 17%; " class="col_4"><!--Empty--><col style="width: 8%; " class="col_5"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487673168" scope="col">Feature</th><th align="left" valign="top" id="idm140209487672080" scope="col">YAML key</th><th align="left" valign="top" id="idm140209487670992" scope="col">Description</th><th align="left" valign="top" id="idm140209487669904" scope="col">Annotation for override</th><th align="left" valign="top" id="idm140209487668816" scope="col">Default value</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487673168"> <p> Reconcile period </p> </td><td align="left" valign="top" headers="idm140209487672080"> <p> <code class="literal">reconcilePeriod</code> </p> </td><td align="left" valign="top" headers="idm140209487670992"> <p> Time between reconcile runs for a particular CR. </p> </td><td align="left" valign="top" headers="idm140209487669904"> <p> <code class="literal">ansible.operator-sdk/reconcile-period</code> </p> </td><td align="left" valign="top" headers="idm140209487668816"> <p> <code class="literal">1m</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487673168"> <p> Manage status </p> </td><td align="left" valign="top" headers="idm140209487672080"> <p> <code class="literal">manageStatus</code> </p> </td><td align="left" valign="top" headers="idm140209487670992"> <p> Allows the Operator to manage the <code class="literal">conditions</code> section of each CR <code class="literal">status</code> section. </p> </td><td align="left" valign="top" headers="idm140209487669904"> </td><td align="left" valign="top" headers="idm140209487668816"> <p> <code class="literal">true</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487673168"> <p> Watch dependent resources </p> </td><td align="left" valign="top" headers="idm140209487672080"> <p> <code class="literal">watchDependentResources</code> </p> </td><td align="left" valign="top" headers="idm140209487670992"> <p> Allows the Operator to dynamically watch resources that are created by Ansible. </p> </td><td align="left" valign="top" headers="idm140209487669904"> </td><td align="left" valign="top" headers="idm140209487668816"> <p> <code class="literal">true</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487673168"> <p> Watch cluster-scoped resources </p> </td><td align="left" valign="top" headers="idm140209487672080"> <p> <code class="literal">watchClusterScopedResources</code> </p> </td><td align="left" valign="top" headers="idm140209487670992"> <p> Allows the Operator to watch cluster-scoped resources that are created by Ansible. </p> </td><td align="left" valign="top" headers="idm140209487669904"> </td><td align="left" valign="top" headers="idm140209487668816"> <p> <code class="literal">false</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487673168"> <p> Max runner artifacts </p> </td><td align="left" valign="top" headers="idm140209487672080"> <p> <code class="literal">maxRunnerArtifacts</code> </p> </td><td align="left" valign="top" headers="idm140209487670992"> <p> Manages the number of <a class="link" href="https://ansible-runner.readthedocs.io/en/latest/intro.html#runner-artifacts-directory-hierarchy">artifact directories</a> that Ansible Runner keeps in the Operator container for each individual resource. </p> </td><td align="left" valign="top" headers="idm140209487669904"> <p> <code class="literal">ansible.operator-sdk/max-runner-artifacts</code> </p> </td><td align="left" valign="top" headers="idm140209487668816"> <p> <code class="literal">20</code> </p> </td></tr></tbody></table></rh-table><div class="formalpara"><p class="title"><strong>Example watches.yml file with advanced options</strong></p><p> </p><pre class="programlisting language-yaml">- version: v1alpha1 group: app.example.com kind: AppService playbook: /opt/ansible/playbook.yml maxRunnerArtifacts: 30 reconcilePeriod: 5s manageStatus: False watchDependentResources: False</pre> <p></p></div></section></section><section class="section" id="osdk-ansible-extra-variables_osdk-ansible-support"><div class="titlepage"><div><div><h4 class="title">5.5.4.3. Extra variables sent to Ansible</h4></div></div></div><p> Extra variables can be sent to Ansible, which are then managed by the Operator. The <code class="literal">spec</code> section of the custom resource (CR) passes along the key-value pairs as extra variables. This is equivalent to extra variables passed in to the <code class="literal">ansible-playbook</code> command. </p><p> The Operator also passes along additional variables under the <code class="literal">meta</code> field for the name of the CR and the namespace of the CR. </p><p> For the following CR example: </p><pre class="programlisting language-yaml">apiVersion: "app.example.com/v1alpha1" kind: "Database" metadata: name: "example" spec: message: "Hello world 2" newParameter: "newParam"</pre><p> The structure passed to Ansible as extra variables is: </p><pre class="programlisting language-json">{ "meta": { "name": "&lt;cr_name&gt;", "namespace": "&lt;cr_namespace&gt;", }, "message": "Hello world 2", "new_parameter": "newParam", "_app_example_com_database": { &lt;full_crd&gt; }, }</pre><p> The <code class="literal">message</code> and <code class="literal">newParameter</code> fields are set in the top level as extra variables, and <code class="literal">meta</code> provides the relevant metadata for the CR as defined in the Operator. The <code class="literal">meta</code> fields can be accessed using dot notation in Ansible, for example: </p><pre class="programlisting language-yaml">--- - debug: msg: "name: {{ ansible_operator_meta.name }}, {{ ansible_operator_meta.namespace }}"</pre></section><section class="section" id="osdk-ansible-runner-directory_osdk-ansible-support"><div class="titlepage"><div><div><h4 class="title">5.5.4.4. Ansible Runner directory</h4></div></div></div><p> Ansible Runner keeps information about Ansible runs in the container. This is located at <code class="literal">/tmp/ansible-operator/runner/&lt;group&gt;/&lt;version&gt;/&lt;kind&gt;/&lt;namespace&gt;/&lt;name&gt;</code>. </p><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> To learn more about the <code class="literal">runner</code> directory, see the <a class="link" href="https://ansible-runner.readthedocs.io/en/latest/index.html">Ansible Runner documentation</a>. </li></ul></div></section></section><section class="section" id="osdk-ansible-k8s-collection"><div class="titlepage"><div><div><h3 class="title">5.5.5. Kubernetes Collection for Ansible</h3></div></div></div><p> To manage the lifecycle of your application on Kubernetes using Ansible, you can use the <a class="link" href="https://galaxy.ansible.com/community/kubernetes">Kubernetes Collection for Ansible</a>. This collection of Ansible modules allows a developer to either leverage their existing Kubernetes resource files written in YAML or express the lifecycle management in native Ansible. </p><p> One of the biggest benefits of using Ansible in conjunction with existing Kubernetes resource files is the ability to use Jinja templating so that you can customize resources with the simplicity of a few variables in Ansible. </p><p> This section goes into detail on usage of the Kubernetes Collection. To get started, install the collection on your local workstation and test it using a playbook before moving on to using it within an Operator. </p><section class="section" id="osdk-ansible-installing-k8s-collection_osdk-ansible-k8s-collection"><div class="titlepage"><div><div><h4 class="title">5.5.5.1. Installing the Kubernetes Collection for Ansible</h4></div></div></div><p> You can install the Kubernetes Collection for Ansible on your local workstation. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Install Ansible 2.9+: </p><pre class="programlisting language-terminal">$ sudo dnf install ansible</pre></li><li class="listitem"><p class="simpara"> Install the <a class="link" href="https://github.com/openshift/openshift-restclient-python">OpenShift python client</a> package: </p><pre class="programlisting language-terminal">$ pip3 install openshift</pre></li><li class="listitem"><p class="simpara"> Install the Kubernetes Collection using one of the following methods: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> You can install the collection directly from Ansible Galaxy: </p><pre class="programlisting language-terminal">$ ansible-galaxy collection install community.kubernetes</pre></li><li class="listitem"><p class="simpara"> If you have already initialized your Operator, you might have a <code class="literal">requirements.yml</code> file at the top level of your project. This file specifies Ansible dependencies that must be installed for your Operator to function. By default, this file installs the <code class="literal">community.kubernetes</code> collection as well as the <code class="literal">operator_sdk.util</code> collection, which provides modules and plugins for Operator-specific fuctions. </p><p class="simpara"> To install the dependent modules from the <code class="literal">requirements.yml</code> file: </p><pre class="programlisting language-terminal">$ ansible-galaxy collection install -r requirements.yml</pre></li></ul></div></li></ol></div></section><section class="section" id="osdk-ansible-k8s-local_osdk-ansible-k8s-collection"><div class="titlepage"><div><div><h4 class="title">5.5.5.2. Testing the Kubernetes Collection locally</h4></div></div></div><p> Operator developers can run the Ansible code from their local machine as opposed to running and rebuilding the Operator each time. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Initialize an Ansible-based Operator project and create an API that has a generated Ansible role by using the Operator SDK </li><li class="listitem"> Install the Kubernetes Collection for Ansible </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> In your Ansible-based Operator project directory, modify the <code class="literal">roles/&lt;kind&gt;/tasks/main.yml</code> file with the Ansible logic that you want. The <code class="literal">roles/&lt;kind&gt;/</code> directory is created when you use the <code class="literal">--generate-role</code> flag while creating an API. The <code class="literal">&lt;kind&gt;</code> replaceable matches the kind that you specified for the API. </p><p class="simpara"> The following example creates and deletes a config map based on the value of a variable named <code class="literal">state</code>: </p><pre class="programlisting language-yaml">--- - name: set ConfigMap example-config to {{ state }} community.kubernetes.k8s: api_version: v1 kind: ConfigMap name: example-config namespace: default <span id="CO44-1"><!--Empty--></span><span class="callout">1</span> state: "{{ state }}" ignore_errors: true <span id="CO44-2"><!--Empty--></span><span class="callout">2</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO44-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Change this value if you want the config map to be created in a different namespace from <code class="literal">default</code>. </div></dd><dt><a href="#CO44-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Setting <code class="literal">ignore_errors: true</code> ensures that deleting a nonexistent config map does not fail. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> Modify the <code class="literal">roles/&lt;kind&gt;/defaults/main.yml</code> file to set <code class="literal">state</code> to <code class="literal">present</code> by default: </p><pre class="programlisting language-yaml">--- state: present</pre></li><li class="listitem"><p class="simpara"> Create an Ansible playbook by creating a <code class="literal">playbook.yml</code> file in the top-level of your project directory, and include your <code class="literal">&lt;kind&gt;</code> role: </p><pre class="programlisting language-yaml">--- - hosts: localhost roles: - &lt;kind&gt;</pre></li><li class="listitem"><p class="simpara"> Run the playbook: </p><pre class="programlisting language-terminal">$ ansible-playbook playbook.yml</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] ******************************************************************************** TASK [Gathering Facts] ******************************************************************************** ok: [localhost] TASK [memcached : set ConfigMap example-config to present] ******************************************************************************** changed: [localhost] PLAY RECAP ******************************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Verify that the config map was created: </p><pre class="programlisting language-terminal">$ oc get configmaps</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME DATA AGE example-config 0 2m1s</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Rerun the playbook setting <code class="literal">state</code> to <code class="literal">absent</code>: </p><pre class="programlisting language-terminal">$ ansible-playbook playbook.yml --extra-vars state=absent</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] ******************************************************************************** TASK [Gathering Facts] ******************************************************************************** ok: [localhost] TASK [memcached : set ConfigMap example-config to absent] ******************************************************************************** changed: [localhost] PLAY RECAP ******************************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Verify that the config map was deleted: </p><pre class="programlisting language-terminal">$ oc get configmaps</pre></li></ol></div></section><section class="section" id="osdk-ansible-k8s-collection-next-steps"><div class="titlepage"><div><div><h4 class="title">5.5.5.3. Next steps</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-inside-operator">Using Ansible inside an Operator</a> for details on triggering your custom Ansible logic inside of an Operator when a custom resource (CR) changes. </li></ul></div></section></section><section class="section" id="osdk-ansible-inside-operator"><div class="titlepage"><div><div><h3 class="title">5.5.6. Using Ansible inside an Operator</h3></div></div></div><p> After you are familiar with <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-k8s-collection">using the Kubernetes Collection for Ansible locally</a>, you can trigger the same Ansible logic inside of an Operator when a custom resource (CR) changes. This example maps an Ansible role to a specific Kubernetes resource that the Operator watches. This mapping is done in the <code class="literal">watches.yaml</code> file. </p><section class="section" id="osdk-ansible-custom-resource-files_osdk-ansible-inside-operator"><div class="titlepage"><div><div><h4 class="title">5.5.6.1. Custom resource files</h4></div></div></div><p> Operators use the Kubernetes extension mechanism, custom resource definitions (CRDs), so your custom resource (CR) looks and acts just like the built-in, native Kubernetes objects. </p><p> The CR file format is a Kubernetes resource file. The object has mandatory and optional fields: </p><rh-table id="idm140209487522880"><table class="lt-4-cols lt-7-rows"><caption>Table 5.5. Custom resource fields</caption><colgroup><col style="width: 30%; " class="col_1"><!--Empty--><col style="width: 70%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487518048" scope="col">Field</th><th align="left" valign="top" id="idm140209487516960" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487518048"> <p> <code class="literal">apiVersion</code> </p> </td><td align="left" valign="top" headers="idm140209487516960"> <p> Version of the CR to be created. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487518048"> <p> <code class="literal">kind</code> </p> </td><td align="left" valign="top" headers="idm140209487516960"> <p> Kind of the CR to be created. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487518048"> <p> <code class="literal">metadata</code> </p> </td><td align="left" valign="top" headers="idm140209487516960"> <p> Kubernetes-specific metadata to be created. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487518048"> <p> <code class="literal">spec</code> (optional) </p> </td><td align="left" valign="top" headers="idm140209487516960"> <p> Key-value list of variables which are passed to Ansible. This field is empty by default. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487518048"> <p> <code class="literal">status</code> </p> </td><td align="left" valign="top" headers="idm140209487516960"> <p> Summarizes the current state of the object. For Ansible-based Operators, the <a class="link" href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource"><code class="literal">status</code> subresource</a> is enabled for CRDs and managed by the <code class="literal">operator_sdk.util.k8s_status</code> Ansible module by default, which includes <code class="literal">condition</code> information to the CR <code class="literal">status</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487518048"> <p> <code class="literal">annotations</code> </p> </td><td align="left" valign="top" headers="idm140209487516960"> <p> Kubernetes-specific annotations to be appended to the CR. </p> </td></tr></tbody></table></rh-table><p> The following list of CR annotations modify the behavior of the Operator: </p><rh-table id="idm140209487486640"><table class="lt-4-cols lt-7-rows"><caption>Table 5.6. Ansible-based Operator annotations</caption><colgroup><col style="width: 30%; " class="col_1"><!--Empty--><col style="width: 70%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487481792" scope="col">Annotation</th><th align="left" valign="top" id="idm140209487480704" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487481792"> <p> <code class="literal">ansible.operator-sdk/reconcile-period</code> </p> </td><td align="left" valign="top" headers="idm140209487480704"> <p> Specifies the reconciliation interval for the CR. This value is parsed using the standard Golang package <a class="link" href="https://golang.org/pkg/time/"><code class="literal">time</code></a>. Specifically, <a class="link" href="https://golang.org/pkg/time/#ParseDuration"><code class="literal">ParseDuration</code></a> is used which applies the default suffix of <code class="literal">s</code>, giving the value in seconds. </p> </td></tr></tbody></table></rh-table><div class="formalpara"><p class="title"><strong>Example Ansible-based Operator annotation</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: "test1.example.com/v1alpha1" kind: "Test1" metadata: name: "example" annotations: ansible.operator-sdk/reconcile-period: "30s"</pre> <p></p></div></section><section class="section" id="osdk-ansible-inside-operator-local_osdk-ansible-inside-operator"><div class="titlepage"><div><div><h4 class="title">5.5.6.2. Testing an Ansible-based Operator locally</h4></div></div></div><p> You can test the logic inside of an Ansible-based Operator running locally by using the <code class="literal">make run</code> command from the top-level directory of your Operator project. The <code class="literal">make run</code> Makefile target runs the <code class="literal">ansible-operator</code> binary locally, which reads from the <code class="literal">watches.yaml</code> file and uses your <code class="literal">~/.kube/config</code> file to communicate with a Kubernetes cluster just as the <code class="literal">k8s</code> modules do. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> You can customize the roles path by setting the environment variable <code class="literal">ANSIBLE_ROLES_PATH</code> or by using the <code class="literal">ansible-roles-path</code> flag. If the role is not found in the <code class="literal">ANSIBLE_ROLES_PATH</code> value, the Operator looks for it in <code class="literal">{{current directory}}/roles</code>. </p></div></rh-alert><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://ansible-runner.readthedocs.io/en/latest/install.html">Ansible Runner</a> version v1.1.0+ </li><li class="listitem"> <a class="link" href="https://github.com/ansible/ansible-runner-http">Ansible Runner HTTP Event Emitter plugin</a> version v1.0.0+ </li><li class="listitem"> Performed the previous steps for testing the Kubernetes Collection locally </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Install your custom resource definition (CRD) and proper role-based access control (RBAC) definitions for your custom resource (CR): </p><pre class="programlisting language-terminal">$ make install</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">/usr/bin/kustomize build config/crd | kubectl apply -f - customresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Run the <code class="literal">make run</code> command: </p><pre class="programlisting language-terminal">$ make run</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">/home/user/memcached-operator/bin/ansible-operator run {"level":"info","ts":1612739145.2871568,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.8.0","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"} ... {"level":"info","ts":1612739148.347306,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"} {"level":"info","ts":1612739148.3488882,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2} {"level":"info","ts":1612739148.3490262,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false} {"level":"info","ts":1612739148.3490646,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"} {"level":"info","ts":1612739148.350217,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"} {"level":"info","ts":1612739148.3506632,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"} {"level":"info","ts":1612739148.350784,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"} {"level":"info","ts":1612739148.5511978,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"} {"level":"info","ts":1612739148.5512562,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8}</pre> <p></p></div><p class="simpara"> With the Operator now watching your CR for events, the creation of a CR will trigger your Ansible role to run. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> Consider an example <code class="literal">config/samples/&lt;gvk&gt;.yaml</code> CR manifest: </p><pre class="programlisting language-yaml">apiVersion: &lt;group&gt;.example.com/v1alpha1 kind: &lt;kind&gt; metadata: name: "&lt;kind&gt;-sample"</pre><p> Because the <code class="literal">spec</code> field is not set, Ansible is invoked with no extra variables. Passing extra variables from a CR to Ansible is covered in another section. It is important to set reasonable defaults for the Operator. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Create an instance of your CR with the default variable <code class="literal">state</code> set to <code class="literal">present</code>: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/&lt;gvk&gt;.yaml</pre></li><li class="listitem"><p class="simpara"> Check that the <code class="literal">example-config</code> config map was created: </p><pre class="programlisting language-terminal">$ oc get configmaps</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME STATUS AGE example-config Active 3s</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Modify your <code class="literal">config/samples/&lt;gvk&gt;.yaml</code> file to set the <code class="literal">state</code> field to <code class="literal">absent</code>. For example: </p><pre class="programlisting language-yaml">apiVersion: cache.example.com/v1 kind: Memcached metadata: name: memcached-sample spec: state: absent</pre></li><li class="listitem"><p class="simpara"> Apply the changes: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/&lt;gvk&gt;.yaml</pre></li><li class="listitem"><p class="simpara"> Confirm that the config map is deleted: </p><pre class="programlisting language-terminal">$ oc get configmap</pre></li></ol></div></section><section class="section" id="osdk-run-deployment_osdk-ansible-inside-operator"><div class="titlepage"><div><div><h4 class="title">5.5.6.3. Testing an Ansible-based Operator on the cluster</h4></div></div></div><p> After you have tested your custom Ansible logic locally inside of an Operator, you can test the Operator inside of a pod on an OpenShift Container Platform cluster, which is prefered for production use. </p><p> You can run your Operator project as a deployment on your cluster. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands to build and push the Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The name and tag of the image, for example <code class="literal">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</code>, in both the commands can also be set in your Makefile. Modify the <code class="literal">IMG ?= controller:latest</code> value to set your default image name. </p></div></rh-alert></li></ol></div></li><li class="listitem"><p class="simpara"> Run the following command to deploy the Operator: </p><pre class="programlisting language-terminal">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> By default, this command creates a namespace with the name of your Operator project in the form <code class="literal">&lt;project_name&gt;-system</code> and is used for the deployment. This command also installs the RBAC manifests from <code class="literal">config/rbac</code>. </p></li><li class="listitem"><p class="simpara"> Verify that the Operator is running: </p><pre class="programlisting language-terminal">$ oc get deployment -n &lt;project_name&gt;-system</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE &lt;project_name&gt;-controller-manager 1/1 1 1 8m</pre> <p></p></div></li></ol></div></section><section class="section" id="osdk-ansible-inside-operator-logs_osdk-ansible-inside-operator"><div class="titlepage"><div><div><h4 class="title">5.5.6.4. Ansible logs</h4></div></div></div><p> Ansible-based Operators provide logs about the Ansible run, which can be useful for debugging your Ansible tasks. The logs can also contain detailed information about the internals of the Operator and its interactions with Kubernetes. </p><section class="section" id="osdk-ansible-inside-operator-logs-view_osdk-ansible-inside-operator"><div class="titlepage"><div><div><h5 class="title">5.5.6.4.1. Viewing Ansible logs</h5></div></div></div><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Ansible-based Operator running as a deployment on a cluster </li></ul></div><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> To view logs from an Ansible-based Operator, run the following command: </p><pre class="programlisting language-terminal">$ oc logs deployment/&lt;project_name&gt;-controller-manager \ -c manager \<span id="CO45-1"><!--Empty--></span><span class="callout">1</span> -n &lt;namespace&gt; <span id="CO45-2"><!--Empty--></span><span class="callout">2</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO45-1"><span class="callout">1</span></a> </dt><dd><div class="para"> View logs from the <code class="literal">manager</code> container. </div></dd><dt><a href="#CO45-2"><span class="callout">2</span></a> </dt><dd><div class="para"> If you used the <code class="literal">make deploy</code> command to run the Operator as a deployment, use the <code class="literal">&lt;project_name&gt;-system</code> namespace. </div></dd></dl></div><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">{"level":"info","ts":1612732105.0579333,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.8.0","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"} {"level":"info","ts":1612732105.0587437,"logger":"cmd","msg":"WATCH_NAMESPACE environment variable not set. Watching all namespaces.","Namespace":""} I0207 21:08:26.110949 7 request.go:645] Throttling request took 1.035521578s, request: GET:https://172.30.0.1:443/apis/flowcontrol.apiserver.k8s.io/v1alpha1?timeout=32s {"level":"info","ts":1612732107.768025,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":"127.0.0.1:8080"} {"level":"info","ts":1612732107.768796,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2} {"level":"info","ts":1612732107.7688773,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false} {"level":"info","ts":1612732107.7688901,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"} {"level":"info","ts":1612732107.770032,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"} I0207 21:08:27.770185 7 leaderelection.go:243] attempting to acquire leader lease memcached-operator-system/memcached-operator... {"level":"info","ts":1612732107.770202,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"} I0207 21:08:27.784854 7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator {"level":"info","ts":1612732107.7850506,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"} {"level":"info","ts":1612732107.8853772,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"} {"level":"info","ts":1612732107.8854098,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":4}</pre> <p></p></div></li></ul></div></section><section class="section" id="osdk-ansible-inside-operator-logs-full-result_osdk-ansible-inside-operator"><div class="titlepage"><div><div><h5 class="title">5.5.6.4.2. Enabling full Ansible results in logs</h5></div></div></div><p> You can set the environment variable <code class="literal">ANSIBLE_DEBUG_LOGS</code> to <code class="literal">True</code> to enable checking the full Ansible result in logs, which can be helpful when debugging. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Edit the <code class="literal">config/manager/manager.yaml</code> and <code class="literal">config/default/manager_auth_proxy_patch.yaml</code> files to include the following configuration: </p><pre class="programlisting language-terminal"> containers: - name: manager env: - name: ANSIBLE_DEBUG_LOGS value: "True"</pre></li></ul></div></section><section class="section" id="osdk-ansible-inside-operator-logs-verbose_osdk-ansible-inside-operator"><div class="titlepage"><div><div><h5 class="title">5.5.6.4.3. Enabling verbose debugging in logs</h5></div></div></div><p> While developing an Ansible-based Operator, it can be helpful to enable additional debugging in logs. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Add the <code class="literal">ansible.sdk.operatorframework.io/verbosity</code> annotation to your custom resource to enable the verbosity level that you want. For example: </p><pre class="programlisting language-terminal">apiVersion: "cache.example.com/v1alpha1" kind: "Memcached" metadata: name: "example-memcached" annotations: "ansible.sdk.operatorframework.io/verbosity": "4" spec: size: 4</pre></li></ul></div></section></section></section><section class="section" id="osdk-ansible-cr-status"><div class="titlepage"><div><div><h3 class="title">5.5.7. Custom resource status management</h3></div></div></div><section class="section" id="osdk-ansible-cr-status-about_osdk-ansible-cr-mgmt"><div class="titlepage"><div><div><h4 class="title">5.5.7.1. About custom resource status in Ansible-based Operators</h4></div></div></div><p> Ansible-based Operators automatically update custom resource (CR) <a class="link" href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource"><code class="literal">status</code> subresources</a> with generic information about the previous Ansible run. This includes the number of successful and failed tasks and relevant error messages as shown: </p><pre class="programlisting language-yaml">status: conditions: - ansibleResult: changed: 3 completion: 2018-12-03T13:45:57.13329 failures: 1 ok: 6 skipped: 0 lastTransitionTime: 2018-12-03T13:45:57Z message: 'Status code was -1 and not [200]: Request failed: &lt;urlopen error [Errno 113] No route to host&gt;' reason: Failed status: "True" type: Failure - lastTransitionTime: 2018-12-03T13:46:13Z message: Running reconciliation reason: Running status: "True" type: Running</pre><p> Ansible-based Operators also allow Operator authors to supply custom status values with the <code class="literal">k8s_status</code> Ansible module, which is included in the <a class="link" href="https://galaxy.ansible.com/operator_sdk/util"><code class="literal">operator_sdk.util</code> collection</a>. This allows the author to update the <code class="literal">status</code> from within Ansible with any key-value pair as desired. </p><p> By default, Ansible-based Operators always include the generic Ansible run output as shown above. If you would prefer your application did <span class="emphasis"><em>not</em></span> update the status with Ansible output, you can track the status manually from your application. </p></section><section class="section" id="osdk-ansible-cr-status-manual_osdk-ansible-cr-mgmt"><div class="titlepage"><div><div><h4 class="title">5.5.7.2. Tracking custom resource status manually</h4></div></div></div><p> You can use the <code class="literal">operator_sdk.util</code> collection to modify your Ansible-based Operator to track custom resource (CR) status manually from your application. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Ansible-based Operator project created by using the Operator SDK </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Update the <code class="literal">watches.yaml</code> file with a <code class="literal">manageStatus</code> field set to <code class="literal">false</code>: </p><pre class="programlisting language-yaml">- version: v1 group: api.example.com kind: &lt;kind&gt; role: &lt;role&gt; manageStatus: false</pre></li><li class="listitem"><p class="simpara"> Use the <code class="literal">operator_sdk.util.k8s_status</code> Ansible module to update the subresource. For example, to update with key <code class="literal">test</code> and value <code class="literal">data</code>, <code class="literal">operator_sdk.util</code> can be used as shown: </p><pre class="programlisting language-yaml">- operator_sdk.util.k8s_status: api_version: app.example.com/v1 kind: &lt;kind&gt; name: "{{ ansible_operator_meta.name }}" namespace: "{{ ansible_operator_meta.namespace }}" status: test: data</pre></li><li class="listitem"><p class="simpara"> You can declare collections in the <code class="literal">meta/main.yml</code> file for the role, which is included for scaffolded Ansible-based Operators: </p><pre class="programlisting language-yaml">collections: - operator_sdk.util</pre></li><li class="listitem"><p class="simpara"> After declaring collections in the role meta, you can invoke the <code class="literal">k8s_status</code> module directly: </p><pre class="programlisting language-yaml">k8s_status: ... status: key1: value1</pre></li></ol></div></section></section></section><section class="section" id="helm-based-operators"><div class="titlepage"><div><div><h2 class="title">5.6. Helm-based Operators</h2></div></div></div><section class="section" id="osdk-helm-quickstart"><div class="titlepage"><div><div><h3 class="title">5.6.1. Getting started with Operator SDK for Helm-based Operators</h3></div></div></div><p> The Operator SDK includes options for generating an Operator project that leverages existing <a class="link" href="https://helm.sh/docs/">Helm</a> charts to deploy Kubernetes resources as a unified application, without having to write any Go code. </p><p> To demonstrate the basics of setting up and running an <a class="link" href="https://helm.sh/docs/">Helm</a>-based Operator using tools and libraries provided by the Operator SDK, Operator developers can build an example Helm-based Operator for Nginx and deploy it to a cluster. </p><section class="section" id="osdk-common-prereqs_osdk-helm-quickstart"><div class="titlepage"><div><div><h4 class="title">5.6.1.1. Prerequisites</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli">Operator SDK CLI installed</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli">OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed</a> </li><li class="listitem"> Logged into an OpenShift Container Platform 4.8 cluster with <code class="literal">oc</code> with an account that has <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> To allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret </li></ul></div></section><section class="section" id="osdk-quickstart_osdk-helm-quickstart"><div class="titlepage"><div><div><h4 class="title">5.6.1.2. Creating and deploying Helm-based Operators</h4></div></div></div><p> You can build and deploy a simple Helm-based Operator for Nginx by using the Operator SDK. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create a project.</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Create your project directory: </p><pre class="programlisting language-terminal">$ mkdir nginx-operator</pre></li><li class="listitem"><p class="simpara"> Change into the project directory: </p><pre class="programlisting language-terminal">$ cd nginx-operator</pre></li><li class="listitem"><p class="simpara"> Run the <code class="literal">operator-sdk init</code> command with the <code class="literal">helm</code> plugin to initialize the project: </p><pre class="programlisting language-terminal">$ operator-sdk init \ --plugins=helm</pre></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create an API.</strong></span> </p><p class="simpara"> Create a simple Nginx API: </p><pre class="programlisting language-terminal">$ operator-sdk create api \ --group demo \ --version v1 \ --kind Nginx</pre><p class="simpara"> This API uses the built-in Helm chart boilerplate from the <code class="literal">helm create</code> command. </p></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Build and push the Operator image.</strong></span> </p><p class="simpara"> Use the default <code class="literal">Makefile</code> targets to build and push your Operator. Set <code class="literal">IMG</code> with a pull spec for your image that uses a registry you can push to: </p><pre class="programlisting language-terminal">$ make docker-build docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Run the Operator.</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Install the CRD: </p><pre class="programlisting language-terminal">$ make install</pre></li><li class="listitem"><p class="simpara"> Deploy the project to the cluster. Set <code class="literal">IMG</code> to the image that you pushed: </p><pre class="programlisting language-terminal">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Add a security context constraint (SCC).</strong></span> </p><p class="simpara"> The Nginx service account requires privileged access to run in OpenShift Container Platform. Add the following SCC to the service account for the <code class="literal">nginx-sample</code> pod: </p><pre class="programlisting language-terminal">$ oc adm policy add-scc-to-user \ anyuid system:serviceaccount:nginx-operator-system:nginx-sample</pre></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Create a sample custom resource (CR).</strong></span> </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Create a sample CR: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/demo_v1_nginx.yaml \ -n nginx-operator-system</pre></li><li class="listitem"><p class="simpara"> Watch for the CR to reconcile the Operator: </p><pre class="programlisting language-terminal">$ oc logs deployment.apps/nginx-operator-controller-manager \ -c manager \ -n nginx-operator-system</pre></li></ol></div></li><li class="listitem"><p class="simpara"> <span class="strong strong"><strong>Clean up.</strong></span> </p><p class="simpara"> Run the following command to clean up the resources that have been created as part of this procedure: </p><pre class="programlisting language-terminal">$ make undeploy</pre></li></ol></div></section><section class="section" id="osdk-helm-quickstart-next-steps"><div class="titlepage"><div><div><h4 class="title">5.6.1.3. Next steps</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-helm-tutorial">Operator SDK tutorial for Helm-based Operators</a> for a more in-depth walkthrough on building a Helm-based Operator. </li></ul></div></section></section><section class="section" id="osdk-helm-tutorial"><div class="titlepage"><div><div><h3 class="title">5.6.2. Operator SDK tutorial for Helm-based Operators</h3></div></div></div><p> Operator developers can take advantage of <a class="link" href="https://helm.sh/docs/">Helm</a> support in the Operator SDK to build an example Helm-based Operator for Nginx and manage its lifecycle. This tutorial walks through the following process: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Create a Nginx deployment </li><li class="listitem"> Ensure that the deployment size is the same as specified by the <code class="literal">Nginx</code> custom resource (CR) spec </li><li class="listitem"> Update the <code class="literal">Nginx</code> CR status using the status writer with the names of the <code class="literal">nginx</code> pods </li></ul></div><p> This process is accomplished using two centerpieces of the Operator Framework: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Operator SDK</span></dt><dd> The <code class="literal">operator-sdk</code> CLI tool and <code class="literal">controller-runtime</code> library API </dd><dt><span class="term">Operator Lifecycle Manager (OLM)</span></dt><dd> Installation, upgrade, and role-based access control (RBAC) of Operators on a cluster </dd></dl></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> This tutorial goes into greater detail than <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-helm-quickstart">Getting started with Operator SDK for Helm-based Operators</a>. </p></div></rh-alert><section class="section" id="osdk-common-prereqs_osdk-helm-tutorial"><div class="titlepage"><div><div><h4 class="title">5.6.2.1. Prerequisites</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli">Operator SDK CLI installed</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli">OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed</a> </li><li class="listitem"> Logged into an OpenShift Container Platform 4.8 cluster with <code class="literal">oc</code> with an account that has <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> To allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret </li></ul></div></section><section class="section" id="osdk-create-project_osdk-helm-tutorial"><div class="titlepage"><div><div><h4 class="title">5.6.2.2. Creating a project</h4></div></div></div><p> Use the Operator SDK CLI to create a project called <code class="literal">nginx-operator</code>. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Create a directory for the project: </p><pre class="programlisting language-terminal">$ mkdir -p $HOME/projects/nginx-operator</pre></li><li class="listitem"><p class="simpara"> Change to the directory: </p><pre class="programlisting language-terminal">$ cd $HOME/projects/nginx-operator</pre></li><li class="listitem"><p class="simpara"> Run the <code class="literal">operator-sdk init</code> command with the <code class="literal">helm</code> plugin to initialize the project: </p><pre class="programlisting language-terminal">$ operator-sdk init \ --plugins=helm \ --domain=example.com \ --group=demo \ --version=v1 \ --kind=Nginx</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> By default, the <code class="literal">helm</code> plugin initializes a project using a boilerplate Helm chart. You can use additional flags, such as the <code class="literal">--helm-chart</code> flag, to initialize a project using an existing Helm chart. </p></div></rh-alert><p class="simpara"> The <code class="literal">init</code> command creates the <code class="literal">nginx-operator</code> project specifically for watching a resource with API version <code class="literal">example.com/v1</code> and kind <code class="literal">Nginx</code>. </p></li><li class="listitem"> For Helm-based projects, the <code class="literal">init</code> command generates the RBAC rules in the <code class="literal">config/rbac/role.yaml</code> file based on the resources that would be deployed by the default manifest for the chart. Verify that the rules generated in this file meet the permission requirements of the Operator. </li></ol></div><section class="section" id="osdk-helm-existing-chart_osdk-helm-tutorial"><div class="titlepage"><div><div><h5 class="title">5.6.2.2.1. Existing Helm charts</h5></div></div></div><p> Instead of creating your project with a boilerplate Helm chart, you can alternatively use an existing chart, either from your local file system or a remote chart repository, by using the following flags: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <code class="literal">--helm-chart</code> </li><li class="listitem"> <code class="literal">--helm-chart-repo</code> </li><li class="listitem"> <code class="literal">--helm-chart-version</code> </li></ul></div><p> If the <code class="literal">--helm-chart</code> flag is specified, the <code class="literal">--group</code>, <code class="literal">--version</code>, and <code class="literal">--kind</code> flags become optional. If left unset, the following default values are used: </p><rh-table><table class="lt-4-cols lt-7-rows"><colgroup><col style="width: 50%; " class="col_1"><!--Empty--><col style="width: 50%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487210848" scope="col">Flag</th><th align="left" valign="top" id="idm140209487209760" scope="col">Value</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487210848"> <p> <code class="literal">--domain</code> </p> </td><td align="left" valign="top" headers="idm140209487209760"> <p> <code class="literal">my.domain</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487210848"> <p> <code class="literal">--group</code> </p> </td><td align="left" valign="top" headers="idm140209487209760"> <p> <code class="literal">charts</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487210848"> <p> <code class="literal">--version</code> </p> </td><td align="left" valign="top" headers="idm140209487209760"> <p> <code class="literal">v1</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487210848"> <p> <code class="literal">--kind</code> </p> </td><td align="left" valign="top" headers="idm140209487209760"> <p> Deduced from the specified chart </p> </td></tr></tbody></table></rh-table><p> If the <code class="literal">--helm-chart</code> flag specifies a local chart archive, for example <code class="literal">example-chart-1.2.0.tgz</code>, or directory, the chart is validated and unpacked or copied into the project. Otherwise, the Operator SDK attempts to fetch the chart from a remote repository. </p><p> If a custom repository URL is not specified by the <code class="literal">--helm-chart-repo</code> flag, the following chart reference formats are supported: </p><rh-table><table class="lt-4-cols lt-7-rows"><colgroup><col style="width: 20%; " class="col_1"><!--Empty--><col style="width: 80%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487182720" scope="col">Format</th><th align="left" valign="top" id="idm140209487181632" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487182720"> <p> <code class="literal">&lt;repo_name&gt;/&lt;chart_name&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209487181632"> <p> Fetch the Helm chart named <code class="literal">&lt;chart_name&gt;</code> from the helm chart repository named <code class="literal">&lt;repo_name&gt;</code>, as specified in the <code class="literal">$HELM_HOME/repositories/repositories.yaml</code> file. Use the <code class="literal">helm repo add</code> command to configure this file. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209487182720"> <p> <code class="literal">&lt;url&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209487181632"> <p> Fetch the Helm chart archive at the specified URL. </p> </td></tr></tbody></table></rh-table><p> If a custom repository URL is specified by <code class="literal">--helm-chart-repo</code>, the following chart reference format is supported: </p><rh-table><table class="lt-4-cols lt-7-rows"><colgroup><col style="width: 20%; " class="col_1"><!--Empty--><col style="width: 80%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209487163712" scope="col">Format</th><th align="left" valign="top" id="idm140209487162624" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209487163712"> <p> <code class="literal">&lt;chart_name&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209487162624"> <p> Fetch the Helm chart named <code class="literal">&lt;chart_name&gt;</code> in the Helm chart repository specified by the <code class="literal">--helm-chart-repo</code> URL value. </p> </td></tr></tbody></table></rh-table><p> If the <code class="literal">--helm-chart-version</code> flag is unset, the Operator SDK fetches the latest available version of the Helm chart. Otherwise, it fetches the specified version. The optional <code class="literal">--helm-chart-version</code> flag is not used when the chart specified with the <code class="literal">--helm-chart</code> flag refers to a specific version, for example when it is a local path or a URL. </p><p> For more details and examples, run: </p><pre class="programlisting language-terminal">$ operator-sdk init --plugins helm --help</pre></section><section class="section" id="osdk-project-file_osdk-helm-tutorial"><div class="titlepage"><div><div><h5 class="title">5.6.2.2.2. PROJECT file</h5></div></div></div><p> Among the files generated by the <code class="literal">operator-sdk init</code> command is a Kubebuilder <code class="literal">PROJECT</code> file. Subsequent <code class="literal">operator-sdk</code> commands, as well as <code class="literal">help</code> output, that are run from the project root read this file and are aware that the project type is Helm. For example: </p><pre class="programlisting language-yaml">domain: example.com layout: helm.sdk.operatorframework.io/v1 projectName: helm-operator resources: - group: demo kind: Nginx version: v1 version: 3</pre></section></section><section class="section" id="osdk-helm-logic_osdk-helm-tutorial"><div class="titlepage"><div><div><h4 class="title">5.6.2.3. Understanding the Operator logic</h4></div></div></div><p> For this example, the <code class="literal">nginx-operator</code> project executes the following reconciliation logic for each <code class="literal">Nginx</code> custom resource (CR): </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Create an Nginx deployment if it does not exist. </li><li class="listitem"> Create an Nginx service if it does not exist. </li><li class="listitem"> Create an Nginx ingress if it is enabled and does not exist. </li><li class="listitem"> Ensure that the deployment, service, and optional ingress match the desired configuration as specified by the <code class="literal">Nginx</code> CR, for example the replica count, image, and service type. </li></ul></div><p> By default, the <code class="literal">nginx-operator</code> project watches <code class="literal">Nginx</code> resource events as shown in the <code class="literal">watches.yaml</code> file and executes Helm releases using the specified chart: </p><pre class="programlisting language-yaml"># Use the 'create api' subcommand to add watches to this file. - group: demo version: v1 kind: Nginx chart: helm-charts/nginx # +kubebuilder:scaffold:watch</pre><section class="section" id="osdk-helm-sample-chart_osdk-helm-tutorial"><div class="titlepage"><div><div><h5 class="title">5.6.2.3.1. Sample Helm chart</h5></div></div></div><p> When a Helm Operator project is created, the Operator SDK creates a sample Helm chart that contains a set of templates for a simple Nginx release. </p><p> For this example, templates are available for deployment, service, and ingress resources, along with a <code class="literal">NOTES.txt</code> template, which Helm chart developers use to convey helpful information about a release. </p><p> If you are not already familiar with Helm charts, review the <a class="link" href="https://docs.helm.sh/developing_charts/">Helm developer documentation</a>. </p></section><section class="section" id="osdk-helm-modify-cr_osdk-helm-tutorial"><div class="titlepage"><div><div><h5 class="title">5.6.2.3.2. Modifying the custom resource spec</h5></div></div></div><p> Helm uses a concept called <a class="link" href="https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing">values</a> to provide customizations to the defaults of a Helm chart, which are defined in the <code class="literal">values.yaml</code> file. </p><p> You can override these defaults by setting the desired values in the custom resource (CR) spec. You can use the number of replicas as an example. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> The <code class="literal">helm-charts/nginx/values.yaml</code> file has a value called <code class="literal">replicaCount</code> set to <code class="literal">1</code> by default. To have two Nginx instances in your deployment, your CR spec must contain <code class="literal">replicaCount: 2</code>. </p><p class="simpara"> Edit the <code class="literal">config/samples/demo_v1_nginx.yaml</code> file to set <code class="literal">replicaCount: 2</code>: </p><pre class="programlisting language-yaml">apiVersion: demo.example.com/v1 kind: Nginx metadata: name: nginx-sample ... spec: ... replicaCount: 2</pre></li><li class="listitem"><p class="simpara"> Similarly, the default service port is set to <code class="literal">80</code>. To use <code class="literal">8080</code>, edit the <code class="literal">config/samples/demo_v1_nginx.yaml</code> file to set <code class="literal">spec.port: 8080</code>,which adds the service port override: </p><pre class="programlisting language-yaml">apiVersion: demo.example.com/v1 kind: Nginx metadata: name: nginx-sample spec: replicaCount: 2 service: port: 8080</pre></li></ol></div><p> The Helm Operator applies the entire spec as if it was the contents of a values file, just like the <code class="literal">helm install -f ./overrides.yaml</code> command. </p></section></section><section class="section" id="osdk-run-operator_osdk-helm-tutorial"><div class="titlepage"><div><div><h4 class="title">5.6.2.4. Running the Operator</h4></div></div></div><p> There are three ways you can use the Operator SDK CLI to build and run your Operator: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Run locally outside the cluster as a Go program. </li><li class="listitem"> Run as a deployment on the cluster. </li><li class="listitem"> Bundle your Operator and use Operator Lifecycle Manager (OLM) to deploy on the cluster. </li></ul></div><section class="section" id="osdk-run-locally_osdk-helm-tutorial"><div class="titlepage"><div><div><h5 class="title">5.6.2.4.1. Running locally outside the cluster</h5></div></div></div><p> You can run your Operator project as a Go program outside of the cluster. This is useful for development purposes to speed up deployment and testing. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Run the following command to install the custom resource definitions (CRDs) in the cluster configured in your <code class="literal">~/.kube/config</code> file and run the Operator locally: </p><pre class="programlisting language-terminal">$ make install run</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">... {"level":"info","ts":1612652419.9289865,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"} {"level":"info","ts":1612652419.9296563,"logger":"helm.controller","msg":"Watching resource","apiVersion":"demo.example.com/v1","kind":"Nginx","namespace":"","reconcilePeriod":"1m0s"} {"level":"info","ts":1612652419.929983,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"} {"level":"info","ts":1612652419.930015,"logger":"controller-runtime.manager.controller.nginx-controller","msg":"Starting EventSource","source":"kind source: demo.example.com/v1, Kind=Nginx"} {"level":"info","ts":1612652420.2307851,"logger":"controller-runtime.manager.controller.nginx-controller","msg":"Starting Controller"} {"level":"info","ts":1612652420.2309358,"logger":"controller-runtime.manager.controller.nginx-controller","msg":"Starting workers","worker count":8}</pre> <p></p></div></li></ul></div></section><section class="section" id="osdk-run-deployment_osdk-helm-tutorial"><div class="titlepage"><div><div><h5 class="title">5.6.2.4.2. Running as a deployment on the cluster</h5></div></div></div><p> You can run your Operator project as a deployment on your cluster. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands to build and push the Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The name and tag of the image, for example <code class="literal">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</code>, in both the commands can also be set in your Makefile. Modify the <code class="literal">IMG ?= controller:latest</code> value to set your default image name. </p></div></rh-alert></li></ol></div></li><li class="listitem"><p class="simpara"> Run the following command to deploy the Operator: </p><pre class="programlisting language-terminal">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> By default, this command creates a namespace with the name of your Operator project in the form <code class="literal">&lt;project_name&gt;-system</code> and is used for the deployment. This command also installs the RBAC manifests from <code class="literal">config/rbac</code>. </p></li><li class="listitem"><p class="simpara"> Verify that the Operator is running: </p><pre class="programlisting language-terminal">$ oc get deployment -n &lt;project_name&gt;-system</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE &lt;project_name&gt;-controller-manager 1/1 1 1 8m</pre> <p></p></div></li></ol></div></section><section class="section" id="osdk-bundle-deploy-olm_osdk-helm-tutorial"><div class="titlepage"><div><div><h5 class="title">5.6.2.4.3. Bundling an Operator and deploying with Operator Lifecycle Manager</h5></div></div></div><section class="section" id="osdk-bundle-operator_osdk-helm-tutorial"><div class="titlepage"><div><div><h6 class="title">5.6.2.4.3.1. Bundling an Operator</h6></div></div></div><p> The Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed </li><li class="listitem"> Operator project initialized by using the Operator SDK </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands in your Operator project directory to build and push your Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li><li class="listitem"><p class="simpara"> Create your Operator bundle manifest by running the <code class="literal">make bundle</code> command, which invokes several commands, including the Operator SDK <code class="literal">generate bundle</code> and <code class="literal">bundle validate</code> subcommands: </p><pre class="programlisting language-terminal">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> Bundle manifests for an Operator describe how to display, create, and manage an application. The <code class="literal">make bundle</code> command creates the following files and directories in your Operator project: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> A bundle manifests directory named <code class="literal">bundle/manifests</code> that contains a <code class="literal">ClusterServiceVersion</code> object </li><li class="listitem"> A bundle metadata directory named <code class="literal">bundle/metadata</code> </li><li class="listitem"> All custom resource definitions (CRDs) in a <code class="literal">config/crd</code> directory </li><li class="listitem"> A Dockerfile <code class="literal">bundle.Dockerfile</code> </li></ul></div><p class="simpara"> These files are then automatically validated by using <code class="literal">operator-sdk bundle validate</code> to ensure the on-disk bundle representation is correct. </p></li><li class="listitem"><p class="simpara"> Build and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the bundle image. Set <code class="literal">BUNDLE_IMG</code> with the details for the registry, user namespace, and image tag where you intend to push the image: </p><pre class="programlisting language-terminal">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li><li class="listitem"><p class="simpara"> Push the bundle image: </p><pre class="programlisting language-terminal">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li></ol></div></section><section class="section" id="osdk-deploy-olm_osdk-helm-tutorial"><div class="titlepage"><div><div><h6 class="title">5.6.2.4.3.2. Deploying an Operator with Operator Lifecycle Manager</h6></div></div></div><p> Operator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (<code class="literal">oc</code>) for all Operator lifecycle management functions without any additional tools. </p><p> The Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> Operator bundle image built and pushed to a registry </li><li class="listitem"> OLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use <code class="literal">apiextensions.k8s.io/v1</code> CRDs, for example OpenShift Container Platform 4.8) </li><li class="listitem"> Logged in to the cluster with <code class="literal">oc</code> using an account with <code class="literal">cluster-admin</code> permissions </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Enter the following command to run the Operator on the cluster: </p><pre class="programlisting language-terminal">$ operator-sdk run bundle \ [-n &lt;namespace&gt;] \<span id="CO46-1"><!--Empty--></span><span class="callout">1</span> &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO46-1"><span class="callout">1</span></a> </dt><dd><div class="para"> By default, the command installs the Operator in the currently active project in your <code class="literal">~/.kube/config</code> file. You can add the <code class="literal">-n</code> flag to set a different namespace scope for the installation. </div></dd></dl></div><p class="simpara"> This command performs the following actions: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Create an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production. </li><li class="listitem"> Create a catalog source that points to your new index image, which enables OperatorHub to discover your Operator. </li><li class="listitem"> Deploy your Operator to your cluster by creating an <code class="literal">OperatorGroup</code>, <code class="literal">Subscription</code>, <code class="literal">InstallPlan</code>, and all other required objects, including RBAC. </li></ul></div></li></ol></div></section></section></section><section class="section" id="osdk-create-cr_osdk-helm-tutorial"><div class="titlepage"><div><div><h4 class="title">5.6.2.5. Creating a custom resource</h4></div></div></div><p> After your Operator is installed, you can test it by creating a custom resource (CR) that is now provided on the cluster by the Operator. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Example Nginx Operator, which provides the <code class="literal">Nginx</code> CR, installed on a cluster </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Change to the namespace where your Operator is installed. For example, if you deployed the Operator using the <code class="literal">make deploy</code> command: </p><pre class="programlisting language-terminal">$ oc project nginx-operator-system</pre></li><li class="listitem"><p class="simpara"> Edit the sample <code class="literal">Nginx</code> CR manifest at <code class="literal">config/samples/demo_v1_nginx.yaml</code> to contain the following specification: </p><pre class="programlisting language-yaml">apiVersion: demo.example.com/v1 kind: Nginx metadata: name: nginx-sample ... spec: ... replicaCount: 3</pre></li><li class="listitem"><p class="simpara"> The Nginx service account requires privileged access to run in OpenShift Container Platform. Add the following security context constraint (SCC) to the service account for the <code class="literal">nginx-sample</code> pod: </p><pre class="programlisting language-terminal">$ oc adm policy add-scc-to-user \ anyuid system:serviceaccount:nginx-operator-system:nginx-sample</pre></li><li class="listitem"><p class="simpara"> Create the CR: </p><pre class="programlisting language-terminal">$ oc apply -f config/samples/demo_v1_nginx.yaml</pre></li><li class="listitem"><p class="simpara"> Ensure that the <code class="literal">Nginx</code> Operator creates the deployment for the sample CR with the correct size: </p><pre class="programlisting language-terminal">$ oc get deployments</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE nginx-operator-controller-manager 1/1 1 1 8m nginx-sample 3/3 3 3 1m</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the pods and CR status to confirm the status is updated with the Nginx pod names. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Check the pods: </p><pre class="programlisting language-terminal">$ oc get pods</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY STATUS RESTARTS AGE nginx-sample-6fd7c98d8-7dqdr 1/1 Running 0 1m nginx-sample-6fd7c98d8-g5k7v 1/1 Running 0 1m nginx-sample-6fd7c98d8-m7vn7 1/1 Running 0 1m</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the CR status: </p><pre class="programlisting language-terminal">$ oc get nginx/nginx-sample -o yaml</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: demo.example.com/v1 kind: Nginx metadata: ... name: nginx-sample ... spec: replicaCount: 3 status: nodes: - nginx-sample-6fd7c98d8-7dqdr - nginx-sample-6fd7c98d8-g5k7v - nginx-sample-6fd7c98d8-m7vn7</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> Update the deployment size. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Update <code class="literal">config/samples/demo_v1_nginx.yaml</code> file to change the <code class="literal">spec.size</code> field in the <code class="literal">Nginx</code> CR from <code class="literal">3</code> to <code class="literal">5</code>: </p><pre class="programlisting language-terminal">$ oc patch nginx nginx-sample \ -p '{"spec":{"replicaCount": 5}}' \ --type=merge</pre></li><li class="listitem"><p class="simpara"> Confirm that the Operator changes the deployment size: </p><pre class="programlisting language-terminal">$ oc get deployments</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY UP-TO-DATE AVAILABLE AGE nginx-operator-controller-manager 1/1 1 1 10m nginx-sample 5/5 5 5 3m</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> Clean up the resources that have been created as part of this tutorial. </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> If you used the <code class="literal">make deploy</code> command to test the Operator, run the following command: </p><pre class="programlisting language-terminal">$ make undeploy</pre></li><li class="listitem"><p class="simpara"> If you used the <code class="literal">operator-sdk run bundle</code> command to test the Operator, run the following command: </p><pre class="programlisting language-terminal">$ operator-sdk cleanup &lt;project_name&gt;</pre></li></ul></div></li></ol></div></section><section class="section _additional-resources" id="osdk-helm-tutorial-addtl-resources"><div class="titlepage"><div><div><h4 class="title">5.6.2.6. Additional resources</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-helm-project-layout">Project layout for Helm-based Operators</a> to learn about the directory structures created by the Operator SDK. </li></ul></div></section></section><section class="section" id="osdk-helm-project-layout"><div class="titlepage"><div><div><h3 class="title">5.6.3. Project layout for Helm-based Operators</h3></div></div></div><p> The <code class="literal">operator-sdk</code> CLI can generate, or <span class="emphasis"><em>scaffold</em></span>, a number of packages and files for each Operator project. </p><section class="section" id="osdk-helm-project-layout_osdk-helm-project-layout"><div class="titlepage"><div><div><h4 class="title">5.6.3.1. Helm-based project layout</h4></div></div></div><p> Helm-based Operator projects generated using the <code class="literal">operator-sdk init --plugins helm</code> command contain the following directories and files: </p><rh-table><table class="lt-4-cols lt-7-rows"><colgroup><col style="width: 20%; " class="col_1"><!--Empty--><col style="width: 80%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209486943952" scope="col">File/folders</th><th align="left" valign="top" id="idm140209486942864" scope="col">Purpose</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209486943952"> <p> <code class="literal">config</code> </p> </td><td align="left" valign="top" headers="idm140209486942864"> <p> <a class="link" href="https://kustomize.io/">Kustomize</a> manifests for deploying the Operator on a Kubernetes cluster. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486943952"> <p> <code class="literal">helm-charts/</code> </p> </td><td align="left" valign="top" headers="idm140209486942864"> <p> Helm chart initialized with the <code class="literal">operator-sdk create api</code> command. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486943952"> <p> <code class="literal">Dockerfile</code> </p> </td><td align="left" valign="top" headers="idm140209486942864"> <p> Used to build the Operator image with the <code class="literal">make docker-build</code> command. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486943952"> <p> <code class="literal">watches.yaml</code> </p> </td><td align="left" valign="top" headers="idm140209486942864"> <p> Group/version/kind (GVK) and Helm chart location. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486943952"> <p> <code class="literal">Makefile</code> </p> </td><td align="left" valign="top" headers="idm140209486942864"> <p> Targets used to manage the project. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486943952"> <p> <code class="literal">PROJECT</code> </p> </td><td align="left" valign="top" headers="idm140209486942864"> <p> YAML file containing metadata information for the Operator. </p> </td></tr></tbody></table></rh-table></section></section><section class="section" id="osdk-helm-support"><div class="titlepage"><div><div><h3 class="title">5.6.4. Helm support in Operator SDK</h3></div></div></div><section class="section" id="osdk-helm-charts_osdk-helm-support"><div class="titlepage"><div><div><h4 class="title">5.6.4.1. Helm charts</h4></div></div></div><p> One of the Operator SDK options for generating an Operator project includes leveraging an existing Helm chart to deploy Kubernetes resources as a unified application, without having to write any Go code. Such Helm-based Operators are designed to excel at stateless applications that require very little logic when rolled out, because changes should be applied to the Kubernetes objects that are generated as part of the chart. This may sound limiting, but can be sufficient for a surprising amount of use-cases as shown by the proliferation of Helm charts built by the Kubernetes community. </p><p> The main function of an Operator is to read from a custom object that represents your application instance and have its desired state match what is running. In the case of a Helm-based Operator, the <code class="literal">spec</code> field of the object is a list of configuration options that are typically described in the Helm <code class="literal">values.yaml</code> file. Instead of setting these values with flags using the Helm CLI (for example, <code class="literal">helm install -f values.yaml</code>), you can express them within a custom resource (CR), which, as a native Kubernetes object, enables the benefits of RBAC applied to it and an audit trail. </p><p> For an example of a simple CR called <code class="literal">Tomcat</code>: </p><pre class="programlisting language-yaml">apiVersion: apache.org/v1alpha1 kind: Tomcat metadata: name: example-app spec: replicaCount: 2</pre><p> The <code class="literal">replicaCount</code> value, <code class="literal">2</code> in this case, is propagated into the template of the chart where the following is used: </p><pre class="programlisting language-yaml">{{ .Values.replicaCount }}</pre><p> After an Operator is built and deployed, you can deploy a new instance of an app by creating a new instance of a CR, or list the different instances running in all environments using the <code class="literal">oc</code> command: </p><pre class="programlisting language-terminal">$ oc get Tomcats --all-namespaces</pre><p> There is no requirement use the Helm CLI or install Tiller; Helm-based Operators import code from the Helm project. All you have to do is have an instance of the Operator running and register the CR with a custom resource definition (CRD). Because it obeys RBAC, you can more easily prevent production changes. </p></section></section></section><section class="section" id="osdk-generating-csvs"><div class="titlepage"><div><div><h2 class="title">5.7. Defining cluster service versions (CSVs)</h2></div></div></div><p> A <span class="emphasis"><em>cluster service version</em></span> (CSV), defined by a <code class="literal">ClusterServiceVersion</code> object, is a YAML manifest created from Operator metadata that assists Operator Lifecycle Manager (OLM) in running the Operator in a cluster. It is the metadata that accompanies an Operator container image, used to populate user interfaces with information such as its logo, description, and version. It is also a source of technical information that is required to run the Operator, like the RBAC rules it requires and which custom resources (CRs) it manages or depends on. </p><p> The Operator SDK includes the CSV generator to generate a CSV for the current Operator project, customized using information contained in YAML manifests and Operator source files. </p><p> A CSV-generating command removes the responsibility of Operator authors having in-depth OLM knowledge in order for their Operator to interact with OLM or publish metadata to the Catalog Registry. Further, because the CSV spec will likely change over time as new Kubernetes and OLM features are implemented, the Operator SDK is equipped to easily extend its update system to handle new CSV features going forward. </p><section class="section" id="osdk-how-csv-gen-works_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.1. How CSV generation works</h3></div></div></div><p> Operator bundle manifests, which include cluster service versions (CSVs), describe how to display, create, and manage an application with Operator Lifecycle Manager (OLM). The CSV generator in the Operator SDK, called by the <code class="literal">generate bundle</code> subcommand, is the first step towards publishing your Operator to a catalog and deploying it with OLM. The subcommand requires certain input manifests to construct a CSV manifest; all inputs are read when the command is invoked, along with a CSV base, to idempotently generate or regenerate a CSV. </p><p> Typically, the <code class="literal">generate kustomize manifests</code> subcommand would be run first to generate the input <a class="link" href="https://kustomize.io/">Kustomize</a> bases that are consumed by the <code class="literal">generate bundle</code> subcommand. However, the Operator SDK provides the <code class="literal">make bundle</code> command, which automates several tasks, including running the following subcommands in order: </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> <code class="literal">generate kustomize manifests</code> </li><li class="listitem"> <code class="literal">generate bundle</code> </li><li class="listitem"> <code class="literal">bundle validate</code> </li></ol></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-bundle-operator_osdk-working-bundle-images">Bundling an Operator</a> for a full procedure that includes generating a bundle and CSV. </li></ul></div><section class="section" id="osdk-csv-bundle-files_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.1.1. Generated files and resources</h4></div></div></div><p> The <code class="literal">make bundle</code> command creates the following files and directories in your Operator project: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> A bundle manifests directory named <code class="literal">bundle/manifests</code> that contains a <code class="literal">ClusterServiceVersion</code> (CSV) object </li><li class="listitem"> A bundle metadata directory named <code class="literal">bundle/metadata</code> </li><li class="listitem"> All custom resource definitions (CRDs) in a <code class="literal">config/crd</code> directory </li><li class="listitem"> A Dockerfile <code class="literal">bundle.Dockerfile</code> </li></ul></div><p> The following resources are typically included in a CSV: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Role</span></dt><dd> Defines Operator permissions within a namespace. </dd><dt><span class="term">ClusterRole</span></dt><dd> Defines cluster-wide Operator permissions. </dd><dt><span class="term">Deployment</span></dt><dd> Defines how an Operand of an Operator is run in pods. </dd><dt><span class="term">CustomResourceDefinition (CRD)</span></dt><dd> Defines custom resources that your Operator reconciles. </dd><dt><span class="term">Custom resource examples</span></dt><dd> Examples of resources adhering to the spec of a particular CRD. </dd></dl></div></section><section class="section" id="osdk-csv-ver_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.1.2. Version management</h4></div></div></div><p> The <code class="literal">--version</code> flag for the <code class="literal">generate bundle</code> subcommand supplies a semantic version for your bundle when creating one for the first time and when upgrading an existing one. </p><p> By setting the <code class="literal">VERSION</code> variable in your <code class="literal">Makefile</code>, the <code class="literal">--version</code> flag is automatically invoked using that value when the <code class="literal">generate bundle</code> subcommand is run by the <code class="literal">make bundle</code> command. The CSV version is the same as the Operator version, and a new CSV is generated when upgrading Operator versions. </p></section></section><section class="section" id="osdk-manually-defined-csv-fields_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.2. Manually-defined CSV fields</h3></div></div></div><p> Many CSV fields cannot be populated using generated, generic manifests that are not specific to Operator SDK. These fields are mostly human-written metadata about the Operator and various custom resource definitions (CRDs). </p><p> Operator authors must directly modify their cluster service version (CSV) YAML file, adding personalized data to the following required fields. The Operator SDK gives a warning during CSV generation when a lack of data in any of the required fields is detected. </p><p> The following tables detail which manually-defined CSV fields are required and which are optional. </p><rh-table id="idm140209486850448"><table class="lt-4-cols lt-7-rows"><caption>Table 5.7. Required</caption><colgroup><col style="width: 20%; " class="col_1"><!--Empty--><col style="width: 80%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209486845616" scope="col">Field</th><th align="left" valign="top" id="idm140209486844528" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">metadata.name</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> A unique name for this CSV. Operator version should be included in the name to ensure uniqueness, for example <code class="literal">app-operator.v0.1.1</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">metadata.capabilities</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> The capability level according to the Operator maturity model. Options include <code class="literal">Basic Install</code>, <code class="literal">Seamless Upgrades</code>, <code class="literal">Full Lifecycle</code>, <code class="literal">Deep Insights</code>, and <code class="literal">Auto Pilot</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.displayName</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> A public name to identify the Operator. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.description</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> A short description of the functionality of the Operator. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.keywords</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> Keywords describing the Operator. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.maintainers</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> Human or organizational entities maintaining the Operator, with a <code class="literal">name</code> and <code class="literal">email</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.provider</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> The provider of the Operator (usually an organization), with a <code class="literal">name</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.labels</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> Key-value pairs to be used by Operator internals. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.version</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> Semantic version of the Operator, for example <code class="literal">0.1.1</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486845616"> <p> <code class="literal">spec.customresourcedefinitions</code> </p> </td><td align="left" valign="top" headers="idm140209486844528"> <p> Any CRDs the Operator uses. This field is populated automatically by the Operator SDK if any CRD YAML files are present in <code class="literal">deploy/</code>. However, several fields not in the CRD manifest spec require user input: </p> <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <code class="literal">description</code>: description of the CRD. </li><li class="listitem"> <code class="literal">resources</code>: any Kubernetes resources leveraged by the CRD, for example <code class="literal">Pod</code> and <code class="literal">StatefulSet</code> objects. </li><li class="listitem"> <code class="literal">specDescriptors</code>: UI hints for inputs and outputs of the Operator. </li></ul></div> </td></tr></tbody></table></rh-table><rh-table id="idm140209486789520"><table class="lt-4-cols lt-7-rows"><caption>Table 5.8. Optional</caption><colgroup><col style="width: 20%; " class="col_1"><!--Empty--><col style="width: 80%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209486784688" scope="col">Field</th><th align="left" valign="top" id="idm140209486783600" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209486784688"> <p> <code class="literal">spec.replaces</code> </p> </td><td align="left" valign="top" headers="idm140209486783600"> <p> The name of the CSV being replaced by this CSV. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486784688"> <p> <code class="literal">spec.links</code> </p> </td><td align="left" valign="top" headers="idm140209486783600"> <p> URLs (for example, websites and documentation) pertaining to the Operator or application being managed, each with a <code class="literal">name</code> and <code class="literal">url</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486784688"> <p> <code class="literal">spec.selector</code> </p> </td><td align="left" valign="top" headers="idm140209486783600"> <p> Selectors by which the Operator can pair resources in a cluster. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486784688"> <p> <code class="literal">spec.icon</code> </p> </td><td align="left" valign="top" headers="idm140209486783600"> <p> A base64-encoded icon unique to the Operator, set in a <code class="literal">base64data</code> field with a <code class="literal">mediatype</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486784688"> <p> <code class="literal">spec.maturity</code> </p> </td><td align="left" valign="top" headers="idm140209486783600"> <p> The level of maturity the software has achieved at this version. Options include <code class="literal">planning</code>, <code class="literal">pre-alpha</code>, <code class="literal">alpha</code>, <code class="literal">beta</code>, <code class="literal">stable</code>, <code class="literal">mature</code>, <code class="literal">inactive</code>, and <code class="literal">deprecated</code>. </p> </td></tr></tbody></table></rh-table><p> Further details on what data each field above should hold are found in the <a class="link" href="https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/building-your-csv.md">CSV spec</a>. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> Several YAML fields currently requiring user intervention can potentially be parsed from Operator code. </p></div></rh-alert><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-maturity-model_olm-what-operators-are">Operator maturity model</a> </li></ul></div><section class="section" id="osdk-csv-manual-annotations_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.2.1. Operator metadata annotations</h4></div></div></div><p> Operator developers can manually define certain annotations in the metadata of a cluster service version (CSV) to enable features or highlight capabilities in user interfaces (UIs), such as OperatorHub. </p><p> The following table lists Operator metadata annotations that can be manually defined using <code class="literal">metadata.annotations</code> fields. </p><rh-table id="idm140209486746000"><table class="lt-4-cols lt-7-rows"><caption>Table 5.9. Annotations</caption><colgroup><col style="width: 50%; " class="col_1"><!--Empty--><col style="width: 50%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209486741168" scope="col">Field</th><th align="left" valign="top" id="idm140209486740080" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209486741168"> <p> <code class="literal">alm-examples</code> </p> </td><td align="left" valign="top" headers="idm140209486740080"> <p> Provide custom resource definition (CRD) templates with a minimum set of configuration. Compatible UIs pre-fill this template for users to further customize. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486741168"> <p> <code class="literal">operatorframework.io/initialization-resource</code> </p> </td><td align="left" valign="top" headers="idm140209486740080"> <p> Specify a single required custom resource by adding <code class="literal">operatorframework.io/initialization-resource</code> annotation to the cluster service version (CSV) during Operator installation. The user is then prompted to create the custom resource through a template provided in the CSV. Must include a template that contains a complete YAML definition. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486741168"> <p> <code class="literal">operatorframework.io/suggested-namespace</code> </p> </td><td align="left" valign="top" headers="idm140209486740080"> <p> Set a suggested namespace where the Operator should be deployed. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486741168"> <p> <code class="literal">operators.openshift.io/infrastructure-features</code> </p> </td><td align="left" valign="top" headers="idm140209486740080"> <p> Infrastructure features supported by the Operator. Users can view and filter by these features when discovering Operators through OperatorHub in the web console. Valid, case-sensitive values: </p> <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <code class="literal">disconnected</code>: Operator supports being mirrored into disconnected catalogs, including all dependencies, and does not require internet access. All related images required for mirroring are listed by the Operator. </li><li class="listitem"> <code class="literal">cnf</code>: Operator provides a Cloud-native Network Functions (CNF) Kubernetes plugin. </li><li class="listitem"> <code class="literal">cni</code>: Operator provides a Container Network Interface (CNI) Kubernetes plugin. </li><li class="listitem"> <code class="literal">csi</code>: Operator provides a Container Storage Interface (CSI) Kubernetes plugin. </li><li class="listitem"> <code class="literal">fips</code>: Operator accepts the FIPS mode of the underlying platform and works on nodes that are booted into FIPS mode. </li></ul></div> <rh-alert class="admonition important" state="warning"><div class="admonition_header" slot="header">Important</div><div><p> The use of FIPS Validated / Modules in Process cryptographic libraries is only supported on OpenShift Container Platform deployments on the <code class="literal">x86_64</code> architecture. </p></div></rh-alert> <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <code class="literal">proxy-aware</code>: Operator supports running on a cluster behind a proxy. Operator accepts the standard proxy environment variables <code class="literal">HTTP_PROXY</code> and <code class="literal">HTTPS_PROXY</code>, which Operator Lifecycle Manager (OLM) provides to the Operator automatically when the cluster is configured to use a proxy. Required environment variables are passed down to Operands for managed workloads. </li></ul></div> </td></tr><tr><td align="left" valign="top" headers="idm140209486741168"> <p> <code class="literal">operators.openshift.io/valid-subscription</code> </p> </td><td align="left" valign="top" headers="idm140209486740080"> <p> Free-form array for listing any specific subscriptions that are required to use the Operator. For example, <code class="literal">'["3Scale Commercial License", "Red Hat Managed Integration"]'</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209486741168"> <p> <code class="literal">operators.operatorframework.io/internal-objects</code> </p> </td><td align="left" valign="top" headers="idm140209486740080"> <p> Hides CRDs in the UI that are not meant for user manipulation. </p> </td></tr></tbody></table></rh-table><h6 id="osdk-csv-manual-annotations-examples_osdk-generating-csvs">Example use cases</h6><div class="formalpara"><p class="title"><strong>Operator supports disconnected and proxy-aware</strong></p><p> </p><pre class="programlisting language-terminal">operators.openshift.io/infrastructure-features: '["disconnected", "proxy-aware"]'</pre> <p></p></div><div class="formalpara"><p class="title"><strong>Operator requires an OpenShift Container Platform license</strong></p><p> </p><pre class="programlisting language-terminal">operators.openshift.io/valid-subscription: '["OpenShift Container Platform"]'</pre> <p></p></div><div class="formalpara"><p class="title"><strong>Operator requires a 3scale license</strong></p><p> </p><pre class="programlisting language-terminal">operators.openshift.io/valid-subscription: '["3Scale Commercial License", "Red Hat Managed Integration"]'</pre> <p></p></div><div class="formalpara"><p class="title"><strong>Operator supports disconnected and proxy-aware, and requires an OpenShift Container Platform license</strong></p><p> </p><pre class="programlisting language-terminal">operators.openshift.io/infrastructure-features: '["disconnected", "proxy-aware"]' operators.openshift.io/valid-subscription: '["OpenShift Container Platform"]'</pre> <p></p></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-crds-templates_osdk-generating-csvs">CRD templates</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-init-resource_osdk-generating-csvs">Initializing required custom resources </a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-suggested-namespace_osdk-generating-csvs">Setting a suggested namespace</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-enabling-operator-for-restricted-network_osdk-generating-csvs">Enabling your Operator for restricted network environments</a> (disconnected mode) </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-hiding-internal-objects_osdk-generating-csvs">Hiding internal objects</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/installing/#installing-fips">Support for FIPS crytography</a> </li></ul></div></section></section><section class="section" id="olm-enabling-operator-for-restricted-network_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.3. Enabling your Operator for restricted network environments</h3></div></div></div><p> As an Operator author, your Operator must meet additional requirements to run properly in a restricted network, or disconnected, environment. </p><div class="itemizedlist"><p class="title"><strong>Operator requirements for supporting disconnected mode</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> In the cluster service version (CSV) of your Operator: </p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem"> List any <span class="emphasis"><em>related images</em></span>, or other container images that your Operator might require to perform their functions. </li><li class="listitem"> Reference all specified images by a digest (SHA) and not by a tag. </li></ul></div></li><li class="listitem"> All dependencies of your Operator must also support running in a disconnected mode. </li><li class="listitem"> Your Operator must not require any off-cluster resources. </li></ul></div><p> For the CSV requirements, you can make the following changes as the Operator author. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> An Operator project with a CSV. </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Use SHA references to related images in two places in the CSV for your Operator: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Update <code class="literal">spec.relatedImages</code>: </p><pre class="programlisting language-yaml">... spec: relatedImages: <span id="CO47-1"><!--Empty--></span><span class="callout">1</span> - name: etcd-operator <span id="CO47-2"><!--Empty--></span><span class="callout">2</span> image: quay.io/etcd-operator/operator@sha256:d134a9865524c29fcf75bbc4469013bc38d8a15cb5f41acfddb6b9e492f556e4 <span id="CO47-3"><!--Empty--></span><span class="callout">3</span> - name: etcd-image image: quay.io/etcd-operator/etcd@sha256:13348c15263bd8838ec1d5fc4550ede9860fcbb0f843e48cbccec07810eebb68 ...</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO47-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Create a <code class="literal">relatedImages</code> section and set the list of related images. </div></dd><dt><a href="#CO47-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Specify a unique identifier for the image. </div></dd><dt><a href="#CO47-3"><span class="callout">3</span></a> </dt><dd><div class="para"> Specify each image by a digest (SHA), not by an image tag. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> Update the <code class="literal">env</code> section in the deployment when declaring environment variables that inject the image that the Operator should use: </p><pre class="programlisting language-yaml">spec: install: spec: deployments: - name: etcd-operator-v3.1.1 spec: replicas: 1 selector: matchLabels: name: etcd-operator strategy: type: Recreate template: metadata: labels: name: etcd-operator spec: containers: - args: - /opt/etcd/bin/etcd_operator_run.sh env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - name: ETCD_OPERATOR_DEFAULT_ETCD_IMAGE <span id="CO48-1"><!--Empty--></span><span class="callout">1</span> value: quay.io/etcd-operator/etcd@sha256:13348c15263bd8838ec1d5fc4550ede9860fcbb0f843e48cbccec07810eebb68 <span id="CO48-2"><!--Empty--></span><span class="callout">2</span> - name: ETCD_LOG_LEVEL value: INFO image: quay.io/etcd-operator/operator@sha256:d134a9865524c29fcf75bbc4469013bc38d8a15cb5f41acfddb6b9e492f556e4 <span id="CO48-3"><!--Empty--></span><span class="callout">3</span> imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: /healthy port: 8080 initialDelaySeconds: 10 periodSeconds: 30 name: etcd-operator readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 10 periodSeconds: 30 resources: {} serviceAccountName: etcd-operator strategy: deployment</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO48-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Inject the images referenced by the Operator by using environment variables. </div></dd><dt><a href="#CO48-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Specify each image by a digest (SHA), not by an image tag. </div></dd><dt><a href="#CO48-3"><span class="callout">3</span></a> </dt><dd><div class="para"> Also reference the Operator container image by a digest (SHA), not by an image tag. </div></dd></dl></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> When configuring probes, the <code class="literal">timeoutSeconds</code> value must be lower than the <code class="literal">periodSeconds</code> value. The <code class="literal">timeoutSeconds</code> default value is <code class="literal">1</code>. The <code class="literal">periodSeconds</code> default value is <code class="literal">10</code>. </p></div></rh-alert></li></ol></div></li><li class="listitem"><p class="simpara"> Add the <code class="literal">disconnected</code> annotation, which indicates that the Operator works in a disconnected environment: </p><pre class="programlisting language-yaml">metadata: annotations: operators.openshift.io/infrastructure-features: '["disconnected"]'</pre><p class="simpara"> Operators can be filtered in OperatorHub by this infrastructure feature. </p></li></ol></div></section><section class="section" id="olm-enabling-operator-for-multi-arch_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.4. Enabling your Operator for multiple architectures and operating systems</h3></div></div></div><p> Operator Lifecycle Manager (OLM) assumes that all Operators run on Linux hosts. However, as an Operator author, you can specify whether your Operator supports managing workloads on other architectures, if worker nodes are available in the OpenShift Container Platform cluster. </p><p> If your Operator supports variants other than AMD64 and Linux, you can add labels to the cluster service version (CSV) that provides the Operator to list the supported variants. Labels indicating supported architectures and operating systems are defined by the following: </p><pre class="programlisting language-yaml">labels: operatorframework.io/arch.&lt;arch&gt;: supported <span id="CO49-1"><!--Empty--></span><span class="callout">1</span> operatorframework.io/os.&lt;os&gt;: supported <span id="CO49-2"><!--Empty--></span><span class="callout">2</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO49-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Set <code class="literal">&lt;arch&gt;</code> to a supported string. </div></dd><dt><a href="#CO49-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Set <code class="literal">&lt;os&gt;</code> to a supported string. </div></dd></dl></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> Only the labels on the channel head of the default channel are considered for filtering package manifests by label. This means, for example, that providing an additional architecture for an Operator in the non-default channel is possible, but that architecture is not available for filtering in the <code class="literal">PackageManifest</code> API. </p></div></rh-alert><p> If a CSV does not include an <code class="literal">os</code> label, it is treated as if it has the following Linux support label by default: </p><pre class="programlisting language-yaml">labels: operatorframework.io/os.linux: supported</pre><p> If a CSV does not include an <code class="literal">arch</code> label, it is treated as if it has the following AMD64 support label by default: </p><pre class="programlisting language-yaml">labels: operatorframework.io/arch.amd64: supported</pre><p> If an Operator supports multiple node architectures or operating systems, you can add multiple labels, as well. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> An Operator project with a CSV. </li><li class="listitem"> To support listing multiple architectures and operating systems, your Operator image referenced in the CSV must be a manifest list image. </li><li class="listitem"> For the Operator to work properly in restricted network, or disconnected, environments, the image referenced must also be specified using a digest (SHA) and not by a tag. </li></ul></div><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Add a label in the <code class="literal">metadata.labels</code> of your CSV for each supported architecture and operating system that your Operator supports: </p><pre class="programlisting language-yaml">labels: operatorframework.io/arch.s390x: supported operatorframework.io/os.zos: supported operatorframework.io/os.linux: supported <span id="CO50-1"><!--Empty--></span><span class="callout">1</span> operatorframework.io/arch.amd64: supported <span id="CO50-2"><!--Empty--></span><span class="callout">2</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO50-1"><span class="callout">1</span></a> <a href="#CO50-2"><span class="callout">2</span></a> </dt><dd><div class="para"> After you add a new architecture or operating system, you must also now include the default <code class="literal">os.linux</code> and <code class="literal">arch.amd64</code> variants explicitly. </div></dd></dl></div></li></ul></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> See the <a class="link" href="https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list">Image Manifest V 2, Schema 2</a> specification for more information on manifest lists. </li></ul></div><section class="section" id="olm-arch-os-support_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.4.1. Architecture and operating system support for Operators</h4></div></div></div><p> The following strings are supported in Operator Lifecycle Manager (OLM) on OpenShift Container Platform when labeling or filtering Operators that support multiple architectures and operating systems: </p><rh-table id="idm140209535214432"><table class="lt-4-cols lt-7-rows"><caption>Table 5.10. Architectures supported on OpenShift Container Platform</caption><colgroup><col style="width: 50%; " class="col_1"><!--Empty--><col style="width: 50%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209535209568" scope="col">Architecture</th><th align="left" valign="top" id="idm140209535208480" scope="col">String</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209535209568"> <p> AMD64 </p> </td><td align="left" valign="top" headers="idm140209535208480"> <p> <code class="literal">amd64</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535209568"> <p> 64-bit PowerPC little-endian </p> </td><td align="left" valign="top" headers="idm140209535208480"> <p> <code class="literal">ppc64le</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535209568"> <p> IBM Z </p> </td><td align="left" valign="top" headers="idm140209535208480"> <p> <code class="literal">s390x</code> </p> </td></tr></tbody></table></rh-table><rh-table id="idm140209535193920"><table class="lt-4-cols lt-7-rows"><caption>Table 5.11. Operating systems supported on OpenShift Container Platform</caption><colgroup><col style="width: 50%; " class="col_1"><!--Empty--><col style="width: 50%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209535189040" scope="col">Operating system</th><th align="left" valign="top" id="idm140209535187952" scope="col">String</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209535189040"> <p> Linux </p> </td><td align="left" valign="top" headers="idm140209535187952"> <p> <code class="literal">linux</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535189040"> <p> z/OS </p> </td><td align="left" valign="top" headers="idm140209535187952"> <p> <code class="literal">zos</code> </p> </td></tr></tbody></table></rh-table><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> Different versions of OpenShift Container Platform and other Kubernetes-based distributions might support a different set of architectures and operating systems. </p></div></rh-alert></section></section><section class="section" id="osdk-suggested-namespace_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.5. Setting a suggested namespace</h3></div></div></div><p> Some Operators must be deployed in a specific namespace, or with ancillary resources in specific namespaces, to work properly. If resolved from a subscription, Operator Lifecycle Manager (OLM) defaults the namespaced resources of an Operator to the namespace of its subscription. </p><p> As an Operator author, you can instead express a desired target namespace as part of your cluster service version (CSV) to maintain control over the final namespaces of the resources installed for their Operators. When adding the Operator to a cluster using OperatorHub, this enables the web console to autopopulate the suggested namespace for the cluster administrator during the installation process. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> In your CSV, set the <code class="literal">operatorframework.io/suggested-namespace</code> annotation to your suggested namespace: </p><pre class="programlisting language-yaml">metadata: annotations: operatorframework.io/suggested-namespace: &lt;namespace&gt; <span id="CO51-1"><!--Empty--></span><span class="callout">1</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO51-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Set your suggested namespace. </div></dd></dl></div></li></ul></div></section><section class="section" id="osdk-operatorconditions_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.6. Enabling Operator conditions</h3></div></div></div><p> Operator Lifecycle Manager (OLM) provides Operators with a channel to communicate complex states that influence OLM behavior while managing the Operator. By default, OLM creates an <code class="literal">OperatorCondition</code> custom resource definition (CRD) when it installs an Operator. Based on the conditions set in the <code class="literal">OperatorCondition</code> custom resource (CR), the behavior of OLM changes accordingly. </p><p> To support Operator conditions, an Operator must be able to read the <code class="literal">OperatorCondition</code> CR created by OLM and have the ability to complete the following tasks: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Get the specific condition. </li><li class="listitem"> Set the status of a specific condition. </li></ul></div><p> This can be accomplished by using the <a class="link" href="https://github.com/operator-framework/operator-lib/tree/v0.3.0"><code class="literal">operator-lib</code></a> library. An Operator author can provide a <a class="link" href="https://github.com/kubernetes-sigs/controller-runtime/tree/master/pkg/client"><code class="literal">controller-runtime</code> client</a> in their Operator for the library to access the <code class="literal">OperatorCondition</code> CR owned by the Operator in the cluster. </p><p> The library provides a generic <code class="literal">Conditions</code> interface, which has the following methods to <code class="literal">Get</code> and <code class="literal">Set</code> a <code class="literal">conditionType</code> in the <code class="literal">OperatorCondition</code> CR: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Get</code></span></dt><dd> To get the specific condition, the library uses the <code class="literal">client.Get</code> function from <code class="literal">controller-runtime</code>, which requires an <code class="literal">ObjectKey</code> of type <code class="literal">types.NamespacedName</code> present in <code class="literal">conditionAccessor</code>. </dd><dt><span class="term"><code class="literal">Set</code></span></dt><dd> To update the status of the specific condition, the library uses the <code class="literal">client.Update</code> function from <code class="literal">controller-runtime</code>. An error occurs if the <code class="literal">conditionType</code> is not present in the CRD. </dd></dl></div><p> The Operator is allowed to modify only the <code class="literal">status</code> subresource of the CR. Operators can either delete or update the <code class="literal">status.conditions</code> array to include the condition. For more details on the format and description of the fields present in the conditions, see the upstream <a class="link" href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Condition">Condition GoDocs</a>. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> Operator SDK v1.8.0 supports <code class="literal">operator-lib</code> v0.3.0. </p></div></rh-alert><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> An Operator project generated using the Operator SDK. </li></ul></div><div class="formalpara"><p class="title"><strong>Procedure</strong></p><p> To enable Operator conditions in your Operator project: </p></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> In the <code class="literal">go.mod</code> file of your Operator project, add <code class="literal">operator-framework/operator-lib</code> as a required library: </p><pre class="programlisting language-go">module github.com/example-inc/memcached-operator go 1.15 require ( k8s.io/apimachinery v0.19.2 k8s.io/client-go v0.19.2 sigs.k8s.io/controller-runtime v0.7.0 operator-framework/operator-lib v0.3.0 )</pre></li><li class="listitem"><p class="simpara"> Write your own constructor in your Operator logic that will result in the following outcomes: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Accepts a <code class="literal">controller-runtime</code> client. </li><li class="listitem"> Accepts a <code class="literal">conditionType</code>. </li><li class="listitem"> Returns a <code class="literal">Condition</code> interface to update or add conditions. </li></ul></div><p class="simpara"> Because OLM currently supports the <code class="literal">Upgradeable</code> condition, you can create an interface that has methods to access the <code class="literal">Upgradeable</code> condition. For example: </p><pre class="programlisting language-go">import ( ... apiv1 "github.com/operator-framework/api/pkg/operators/v1" ) func NewUpgradeable(cl client.Client) (Condition, error) { return NewCondition(cl, "apiv1.OperatorUpgradeable") } cond, err := NewUpgradeable(cl);</pre><p class="simpara"> In this example, the <code class="literal">NewUpgradeable</code> constructor is further used to create a variable <code class="literal">cond</code> of type <code class="literal">Condition</code>. The <code class="literal">cond</code> variable would in turn have <code class="literal">Get</code> and <code class="literal">Set</code> methods, which can be used for handling the OLM <code class="literal">Upgradeable</code> condition. </p></li></ol></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-operatorconditions">Operator conditions</a> </li></ul></div></section><section class="section" id="olm-defining-csv-webhook_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.7. Defining webhooks</h3></div></div></div><p> Webhooks allow Operator authors to intercept, modify, and accept or reject resources before they are saved to the object store and handled by the Operator controller. Operator Lifecycle Manager (OLM) can manage the lifecycle of these webhooks when they are shipped alongside your Operator. </p><p> The cluster service version (CSV) resource of an Operator can include a <code class="literal">webhookdefinitions</code> section to define the following types of webhooks: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Admission webhooks (validating and mutating) </li><li class="listitem"> Conversion webhooks </li></ul></div><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Add a <code class="literal">webhookdefinitions</code> section to the <code class="literal">spec</code> section of the CSV of your Operator and include any webhook definitions using a <code class="literal">type</code> of <code class="literal">ValidatingAdmissionWebhook</code>, <code class="literal">MutatingAdmissionWebhook</code>, or <code class="literal">ConversionWebhook</code>. The following example contains all three types of webhooks: </p><div class="formalpara"><p class="title"><strong>CSV containing webhooks</strong></p><p> </p><pre class="programlisting language-yaml"> apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: name: webhook-operator.v0.0.1 spec: customresourcedefinitions: owned: - kind: WebhookTest name: webhooktests.webhook.operators.coreos.io <span id="CO52-1"><!--Empty--></span><span class="callout">1</span> version: v1 install: spec: deployments: - name: webhook-operator-webhook ... ... ... strategy: deployment installModes: - supported: false type: OwnNamespace - supported: false type: SingleNamespace - supported: false type: MultiNamespace - supported: true type: AllNamespaces webhookdefinitions: - type: ValidatingAdmissionWebhook <span id="CO52-2"><!--Empty--></span><span class="callout">2</span> admissionReviewVersions: - v1beta1 - v1 containerPort: 443 targetPort: 4343 deploymentName: webhook-operator-webhook failurePolicy: Fail generateName: vwebhooktest.kb.io rules: - apiGroups: - webhook.operators.coreos.io apiVersions: - v1 operations: - CREATE - UPDATE resources: - webhooktests sideEffects: None webhookPath: /validate-webhook-operators-coreos-io-v1-webhooktest - type: MutatingAdmissionWebhook <span id="CO52-3"><!--Empty--></span><span class="callout">3</span> admissionReviewVersions: - v1beta1 - v1 containerPort: 443 targetPort: 4343 deploymentName: webhook-operator-webhook failurePolicy: Fail generateName: mwebhooktest.kb.io rules: - apiGroups: - webhook.operators.coreos.io apiVersions: - v1 operations: - CREATE - UPDATE resources: - webhooktests sideEffects: None webhookPath: /mutate-webhook-operators-coreos-io-v1-webhooktest - type: ConversionWebhook <span id="CO52-4"><!--Empty--></span><span class="callout">4</span> admissionReviewVersions: - v1beta1 - v1 containerPort: 443 targetPort: 4343 deploymentName: webhook-operator-webhook generateName: cwebhooktest.kb.io sideEffects: None webhookPath: /convert conversionCRDs: - webhooktests.webhook.operators.coreos.io <span id="CO52-5"><!--Empty--></span><span class="callout">5</span> ...</pre> <p></p></div><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO52-1"><span class="callout">1</span></a> </dt><dd><div class="para"> The CRDs targeted by the conversion webhook must exist here. </div></dd><dt><a href="#CO52-2"><span class="callout">2</span></a> </dt><dd><div class="para"> A validating admission webhook. </div></dd><dt><a href="#CO52-3"><span class="callout">3</span></a> </dt><dd><div class="para"> A mutating admission webhook. </div></dd><dt><a href="#CO52-4"><span class="callout">4</span></a> </dt><dd><div class="para"> A conversion webhook. </div></dd><dt><a href="#CO52-5"><span class="callout">5</span></a> </dt><dd><div class="para"> The <code class="literal">spec.PreserveUnknownFields</code> property of each CRD must be set to <code class="literal">false</code> or <code class="literal">nil</code>. </div></dd></dl></div></li></ul></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/architecture/#admission-webhook-types_admission-plug-ins">Types of webhook admission plugins</a> </li><li class="listitem"><p class="simpara"> Kubernetes documentation: </p><div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem"> <a class="link" href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook">Validating admission webhooks</a> </li><li class="listitem"> <a class="link" href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook">Mutating admission webhooks</a> </li><li class="listitem"> <a class="link" href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion">Conversion webhooks</a> </li></ul></div></li></ul></div><section class="section" id="olm-webhook-considerations_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.7.1. Webhook considerations for OLM</h4></div></div></div><p> When deploying an Operator with webhooks using Operator Lifecycle Manager (OLM), you must define the following: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> The <code class="literal">type</code> field must be set to either <code class="literal">ValidatingAdmissionWebhook</code>, <code class="literal">MutatingAdmissionWebhook</code>, or <code class="literal">ConversionWebhook</code>, or the CSV will be placed in a failed phase. </li><li class="listitem"> The CSV must contain a deployment whose name is equivalent to the value supplied in the <code class="literal">deploymentName</code> field of the <code class="literal">webhookdefinition</code>. </li></ul></div><p> When the webhook is created, OLM ensures that the webhook only acts upon namespaces that match the Operator group that the Operator is deployed in. </p><h5 id="olm-webhook-ca_osdk-generating-csvs">Certificate authority constraints</h5><p> OLM is configured to provide each deployment with a single certificate authority (CA). The logic that generates and mounts the CA into the deployment was originally used by the API service lifecycle logic. As a result: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> The TLS certificate file is mounted to the deployment at <code class="literal">/apiserver.local.config/certificates/apiserver.crt</code>. </li><li class="listitem"> The TLS key file is mounted to the deployment at <code class="literal">/apiserver.local.config/certificates/apiserver.key</code>. </li></ul></div><h5 id="olm-admission-webhook-constraints_osdk-generating-csvs">Admission webhook rules constraints</h5><p> To prevent an Operator from configuring the cluster into an unrecoverable state, OLM places the CSV in the failed phase if the rules defined in an admission webhook intercept any of the following requests: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Requests that target all groups </li><li class="listitem"> Requests that target the <code class="literal">operators.coreos.com</code> group </li><li class="listitem"> Requests that target the <code class="literal">ValidatingWebhookConfigurations</code> or <code class="literal">MutatingWebhookConfigurations</code> resources </li></ul></div><h5 id="olm-conversion-webhook-constraints_osdk-generating-csvs">Conversion webhook constraints</h5><p> OLM places the CSV in the failed phase if a conversion webhook definition does not adhere to the following constraints: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> CSVs featuring a conversion webhook can only support the <code class="literal">AllNamespaces</code> install mode. </li><li class="listitem"> The CRD targeted by the conversion webhook must have its <code class="literal">spec.preserveUnknownFields</code> field set to <code class="literal">false</code> or <code class="literal">nil</code>. </li><li class="listitem"> The conversion webhook defined in the CSV must target an owned CRD. </li><li class="listitem"> There can only be one conversion webhook on the entire cluster for a given CRD. </li></ul></div></section></section><section class="section" id="osdk-crds_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.8. Understanding your custom resource definitions (CRDs)</h3></div></div></div><p> There are two types of custom resource definitions (CRDs) that your Operator can use: ones that are <span class="emphasis"><em>owned</em></span> by it and ones that it depends on, which are <span class="emphasis"><em>required</em></span>. </p><section class="section" id="osdk-crds-owned_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.8.1. Owned CRDs</h4></div></div></div><p> The custom resource definitions (CRDs) owned by your Operator are the most important part of your CSV. This establishes the link between your Operator and the required RBAC rules, dependency management, and other Kubernetes concepts. </p><p> It is common for your Operator to use multiple CRDs to link together concepts, such as top-level database configuration in one object and a representation of replica sets in another. Each one should be listed out in the CSV file. </p><rh-table id="idm140209535045168"><table class="lt-4-cols lt-7-rows"><caption>Table 5.12. Owned CRD fields</caption><colgroup><col style="width: 22%; " class="col_1"><!--Empty--><col style="width: 56%; " class="col_2"><!--Empty--><col style="width: 22%; " class="col_3"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209535039408" scope="col">Field</th><th align="left" valign="top" id="idm140209535038320" scope="col">Description</th><th align="left" valign="top" id="idm140209535037232" scope="col">Required/optional</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">Name</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> The full name of your CRD. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">Version</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> The version of that object API. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">Kind</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> The machine readable name of your CRD. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">DisplayName</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> A human readable version of your CRD name, for example <code class="literal">MongoDB Standalone</code>. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">Description</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> A short description of how this CRD is used by the Operator or a description of the functionality provided by the CRD. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">Group</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> The API group that this CRD belongs to, for example <code class="literal">database.example.com</code>. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Optional </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">Resources</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> Your CRDs own one or more types of Kubernetes objects. These are listed in the <code class="literal">resources</code> section to inform your users of the objects they might need to troubleshoot or how to connect to the application, such as the service or ingress rule that exposes a database. </p> <p> It is recommended to only list out the objects that are important to a human, not an exhaustive list of everything you orchestrate. For example, do not list config maps that store internal state that are not meant to be modified by a user. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Optional </p> </td></tr><tr><td align="left" valign="top" headers="idm140209535039408"> <p> <code class="literal">SpecDescriptors</code>, <code class="literal">StatusDescriptors</code>, and <code class="literal">ActionDescriptors</code> </p> </td><td align="left" valign="top" headers="idm140209535038320"> <p> These descriptors are a way to hint UIs with certain inputs or outputs of your Operator that are most important to an end user. If your CRD contains the name of a secret or config map that the user must provide, you can specify that here. These items are linked and highlighted in compatible UIs. </p> <p> There are three types of descriptors: </p> <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <code class="literal">SpecDescriptors</code>: A reference to fields in the <code class="literal">spec</code> block of an object. </li><li class="listitem"> <code class="literal">StatusDescriptors</code>: A reference to fields in the <code class="literal">status</code> block of an object. </li><li class="listitem"> <code class="literal">ActionDescriptors</code>: A reference to actions that can be performed on an object. </li></ul></div> <p> All descriptors accept the following fields: </p> <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <code class="literal">DisplayName</code>: A human readable name for the <code class="literal">Spec</code>, <code class="literal">Status</code>, or <code class="literal">Action</code>. </li><li class="listitem"> <code class="literal">Description</code>: A short description of the <code class="literal">Spec</code>, <code class="literal">Status</code>, or <code class="literal">Action</code> and how it is used by the Operator. </li><li class="listitem"> <code class="literal">Path</code>: A dot-delimited path of the field on the object that this descriptor describes. </li><li class="listitem"> <code class="literal">X-Descriptors</code>: Used to determine which "capabilities" this descriptor has and which UI component to use. See the <span class="strong strong"><strong>openshift/console</strong></span> project for a canonical <a class="link" href="https://github.com/openshift/console/tree/release-4.3/frontend/packages/operator-lifecycle-manager/src/components/descriptors/types.ts">list of React UI X-Descriptors</a> for OpenShift Container Platform. </li></ul></div> <p> Also see the <span class="strong strong"><strong>openshift/console</strong></span> project for more information on <a class="link" href="https://github.com/openshift/console/tree/release-4.3/frontend/packages/operator-lifecycle-manager/src/components/descriptors">Descriptors</a> in general. </p> </td><td align="left" valign="top" headers="idm140209535037232"> <p> Optional </p> </td></tr></tbody></table></rh-table><p> The following example depicts a <code class="literal">MongoDB Standalone</code> CRD that requires some user input in the form of a secret and config map, and orchestrates services, stateful sets, pods and config maps: </p><div id="osdk-crds-owned-example_osdk-generating-csvs" class="formalpara"><p class="title"><strong>Example owned CRD</strong></p><p> </p><pre class="programlisting language-yaml"> - displayName: MongoDB Standalone group: mongodb.com kind: MongoDbStandalone name: mongodbstandalones.mongodb.com resources: - kind: Service name: '' version: v1 - kind: StatefulSet name: '' version: v1beta2 - kind: Pod name: '' version: v1 - kind: ConfigMap name: '' version: v1 specDescriptors: - description: Credentials for Ops Manager or Cloud Manager. displayName: Credentials path: credentials x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Secret' - description: Project this deployment belongs to. displayName: Project path: project x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap' - description: MongoDB version to be installed. displayName: Version path: version x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:label' statusDescriptors: - description: The status of each of the pods for the MongoDB cluster. displayName: Pod Status path: pods x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:podStatuses' version: v1 description: &gt;- MongoDB Deployment consisting of only one host. No replication of data.</pre> <p></p></div></section><section class="section" id="osdk-crds-required_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.8.2. Required CRDs</h4></div></div></div><p> Relying on other required CRDs is completely optional and only exists to reduce the scope of individual Operators and provide a way to compose multiple Operators together to solve an end-to-end use case. </p><p> An example of this is an Operator that might set up an application and install an etcd cluster (from an etcd Operator) to use for distributed locking and a Postgres database (from a Postgres Operator) for data storage. </p><p> Operator Lifecycle Manager (OLM) checks against the available CRDs and Operators in the cluster to fulfill these requirements. If suitable versions are found, the Operators are started within the desired namespace and a service account created for each Operator to create, watch, and modify the Kubernetes resources required. </p><rh-table id="idm140209534954544"><table class="lt-4-cols lt-7-rows"><caption>Table 5.13. Required CRD fields</caption><colgroup><col style="width: 22%; " class="col_1"><!--Empty--><col style="width: 56%; " class="col_2"><!--Empty--><col style="width: 22%; " class="col_3"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534948784" scope="col">Field</th><th align="left" valign="top" id="idm140209534947696" scope="col">Description</th><th align="left" valign="top" id="idm140209534946608" scope="col">Required/optional</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534948784"> <p> <code class="literal">Name</code> </p> </td><td align="left" valign="top" headers="idm140209534947696"> <p> The full name of the CRD you require. </p> </td><td align="left" valign="top" headers="idm140209534946608"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534948784"> <p> <code class="literal">Version</code> </p> </td><td align="left" valign="top" headers="idm140209534947696"> <p> The version of that object API. </p> </td><td align="left" valign="top" headers="idm140209534946608"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534948784"> <p> <code class="literal">Kind</code> </p> </td><td align="left" valign="top" headers="idm140209534947696"> <p> The Kubernetes object kind. </p> </td><td align="left" valign="top" headers="idm140209534946608"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534948784"> <p> <code class="literal">DisplayName</code> </p> </td><td align="left" valign="top" headers="idm140209534947696"> <p> A human readable version of the CRD. </p> </td><td align="left" valign="top" headers="idm140209534946608"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534948784"> <p> <code class="literal">Description</code> </p> </td><td align="left" valign="top" headers="idm140209534947696"> <p> A summary of how the component fits in your larger architecture. </p> </td><td align="left" valign="top" headers="idm140209534946608"> <p> Required </p> </td></tr></tbody></table></rh-table><div class="formalpara"><p class="title"><strong>Example required CRD</strong></p><p> </p><pre class="programlisting language-yaml"> required: - name: etcdclusters.etcd.database.coreos.com version: v1beta2 kind: EtcdCluster displayName: etcd Cluster description: Represents a cluster of etcd nodes.</pre> <p></p></div></section><section class="section" id="olm-dependency-resolution-crd-upgrades_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.8.3. CRD upgrades</h4></div></div></div><p> OLM upgrades a custom resource definition (CRD) immediately if it is owned by a singular cluster service version (CSV). If a CRD is owned by multiple CSVs, then the CRD is upgraded when it has satisfied all of the following backward compatible conditions: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> All existing serving versions in the current CRD are present in the new CRD. </li><li class="listitem"> All existing instances, or custom resources, that are associated with the serving versions of the CRD are valid when validated against the validation schema of the new CRD. </li></ul></div><section class="section" id="olm-dependency-resolution-adding-new-crd-version_osdk-generating-csvs"><div class="titlepage"><div><div><h5 class="title">5.7.8.3.1. Adding a new CRD version</h5></div></div></div><div class="formalpara"><p class="title"><strong>Procedure</strong></p><p> To add a new version of a CRD to your Operator: </p></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Add a new entry in the CRD resource under the <code class="literal">versions</code> section of your CSV. </p><p class="simpara"> For example, if the current CRD has a version <code class="literal">v1alpha1</code> and you want to add a new version <code class="literal">v1beta1</code> and mark it as the new storage version, add a new entry for <code class="literal">v1beta1</code>: </p><pre class="programlisting language-yaml">versions: - name: v1alpha1 served: true storage: false - name: v1beta1 <span id="CO53-1"><!--Empty--></span><span class="callout">1</span> served: true storage: true</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO53-1"><span class="callout">1</span></a> </dt><dd><div class="para"> New entry. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> Ensure the referencing version of the CRD in the <code class="literal">owned</code> section of your CSV is updated if the CSV intends to use the new version: </p><pre class="programlisting language-yaml">customresourcedefinitions: owned: - name: cluster.example.com version: v1beta1 <span id="CO54-1"><!--Empty--></span><span class="callout">1</span> kind: cluster displayName: Cluster</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO54-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Update the <code class="literal">version</code>. </div></dd></dl></div></li><li class="listitem"> Push the updated CRD and CSV to your bundle. </li></ol></div></section><section class="section" id="olm-dependency-resolution-removing-crd-version_osdk-generating-csvs"><div class="titlepage"><div><div><h5 class="title">5.7.8.3.2. Deprecating or removing a CRD version</h5></div></div></div><p> Operator Lifecycle Manager (OLM) does not allow a serving version of a custom resource definition (CRD) to be removed right away. Instead, a deprecated version of the CRD must be first disabled by setting the <code class="literal">served</code> field in the CRD to <code class="literal">false</code>. Then, the non-serving version can be removed on the subsequent CRD upgrade. </p><div class="formalpara"><p class="title"><strong>Procedure</strong></p><p> To deprecate and remove a specific version of a CRD: </p></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Mark the deprecated version as non-serving to indicate this version is no longer in use and may be removed in a subsequent upgrade. For example: </p><pre class="programlisting language-yaml">versions: - name: v1alpha1 served: false <span id="CO55-1"><!--Empty--></span><span class="callout">1</span> storage: true</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO55-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Set to <code class="literal">false</code>. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> Switch the <code class="literal">storage</code> version to a serving version if the version to be deprecated is currently the <code class="literal">storage</code> version. For example: </p><pre class="programlisting language-yaml">versions: - name: v1alpha1 served: false storage: false <span id="CO56-1"><!--Empty--></span><span class="callout">1</span> - name: v1beta1 served: true storage: true <span id="CO56-2"><!--Empty--></span><span class="callout">2</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO56-1"><span class="callout">1</span></a> <a href="#CO56-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Update the <code class="literal">storage</code> fields accordingly. </div></dd></dl></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> To remove a specific version that is or was the <code class="literal">storage</code> version from a CRD, that version must be removed from the <code class="literal">storedVersion</code> in the status of the CRD. OLM will attempt to do this for you if it detects a stored version no longer exists in the new CRD. </p></div></rh-alert></li><li class="listitem"> Upgrade the CRD with the above changes. </li><li class="listitem"><p class="simpara"> In subsequent upgrade cycles, the non-serving version can be removed completely from the CRD. For example: </p><pre class="programlisting language-yaml">versions: - name: v1beta1 served: true storage: true</pre></li><li class="listitem"> Ensure the referencing CRD version in the <code class="literal">owned</code> section of your CSV is updated accordingly if that version is removed from the CRD. </li></ol></div></section></section><section class="section" id="osdk-crds-templates_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.8.4. CRD templates</h4></div></div></div><p> Users of your Operator must be made aware of which options are required versus optional. You can provide templates for each of your custom resource definitions (CRDs) with a minimum set of configuration as an annotation named <code class="literal">alm-examples</code>. Compatible UIs will pre-fill this template for users to further customize. </p><p> The annotation consists of a list of the kind, for example, the CRD name and the corresponding <code class="literal">metadata</code> and <code class="literal">spec</code> of the Kubernetes object. </p><p> The following full example provides templates for <code class="literal">EtcdCluster</code>, <code class="literal">EtcdBackup</code> and <code class="literal">EtcdRestore</code>: </p><pre class="programlisting language-yaml">metadata: annotations: alm-examples: &gt;- [{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"default"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"&lt;full-s3-path&gt;","awsSecret":"&lt;aws-secret&gt;"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["&lt;etcd-cluster-endpoints&gt;"],"storageType":"S3","s3":{"path":"&lt;full-s3-path&gt;","awsSecret":"&lt;aws-secret&gt;"}}}]</pre></section><section class="section" id="osdk-hiding-internal-objects_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.8.5. Hiding internal objects</h4></div></div></div><p> It is common practice for Operators to use custom resource definitions (CRDs) internally to accomplish a task. These objects are not meant for users to manipulate and can be confusing to users of the Operator. For example, a database Operator might have a <code class="literal">Replication</code> CRD that is created whenever a user creates a Database object with <code class="literal">replication: true</code>. </p><p> As an Operator author, you can hide any CRDs in the user interface that are not meant for user manipulation by adding the <code class="literal">operators.operatorframework.io/internal-objects</code> annotation to the cluster service version (CSV) of your Operator. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"> Before marking one of your CRDs as internal, ensure that any debugging information or configuration that might be required to manage the application is reflected on the status or <code class="literal">spec</code> block of your CR, if applicable to your Operator. </li><li class="listitem"><p class="simpara"> Add the <code class="literal">operators.operatorframework.io/internal-objects</code> annotation to the CSV of your Operator to specify any internal objects to hide in the user interface: </p><div class="formalpara"><p class="title"><strong>Internal object annotation</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: name: my-operator-v1.2.3 annotations: operators.operatorframework.io/internal-objects: '["my.internal.crd1.io","my.internal.crd2.io"]' <span id="CO57-1"><!--Empty--></span><span class="callout">1</span> ...</pre> <p></p></div><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO57-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Set any internal CRDs as an array of strings. </div></dd></dl></div></li></ol></div></section><section class="section" id="osdk-init-resource_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.8.6. Initializing required custom resources</h4></div></div></div><p> An Operator might require the user to instantiate a custom resource before the Operator can be fully functional. However, it can be challenging for a user to determine what is required or how to define the resource. </p><p> As an Operator developer, you can specify a single required custom resource by adding <code class="literal">operatorframework.io/initialization-resource</code> to the cluster service version (CSV) during Operator installation. You are then prompted prompted to create the custom resource through a template that is provided in the CSV. The annotation must include a template that contains a complete YAML definition that is required to initialize the resource during installation. </p><p> If this annotation is defined, after installing the Operator from the OpenShift Container Platform web console, the user is prompted to create the resource using the template provided in the CSV. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Add the <code class="literal">operatorframework.io/initialization-resource</code> annotation to the CSV of your Operator to specify a required custom resource. For example, the following annotation requires the creation of a <code class="literal">StorageCluster</code> resource and provides a full YAML definition: </p><div class="formalpara"><p class="title"><strong>Initialization resource annotation</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: name: my-operator-v1.2.3 annotations: operatorframework.io/initialization-resource: |- { "apiVersion": "ocs.openshift.io/v1", "kind": "StorageCluster", "metadata": { "name": "example-storagecluster" }, "spec": { "manageNodes": false, "monPVCTemplate": { "spec": { "accessModes": [ "ReadWriteOnce" ], "resources": { "requests": { "storage": "10Gi" } }, "storageClassName": "gp2" } }, "storageDeviceSets": [ { "count": 3, "dataPVCTemplate": { "spec": { "accessModes": [ "ReadWriteOnce" ], "resources": { "requests": { "storage": "1Ti" } }, "storageClassName": "gp2", "volumeMode": "Block" } }, "name": "example-deviceset", "placement": {}, "portable": true, "resources": {} } ] } } ...</pre> <p></p></div></li></ul></div></section></section><section class="section" id="osdk-apiservices_osdk-generating-csvs"><div class="titlepage"><div><div><h3 class="title">5.7.9. Understanding your API services</h3></div></div></div><p> As with CRDs, there are two types of API services that your Operator may use: <span class="emphasis"><em>owned</em></span> and <span class="emphasis"><em>required</em></span>. </p><section class="section" id="osdk-apiservices-owned_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.9.1. Owned API services</h4></div></div></div><p> When a CSV owns an API service, it is responsible for describing the deployment of the extension <code class="literal">api-server</code> that backs it and the group/version/kind (GVK) it provides. </p><p> An API service is uniquely identified by the group/version it provides and can be listed multiple times to denote the different kinds it is expected to provide. </p><rh-table id="idm140209534823136"><table class="lt-4-cols lt-7-rows"><caption>Table 5.14. Owned API service fields</caption><colgroup><col style="width: 22%; " class="col_1"><!--Empty--><col style="width: 56%; " class="col_2"><!--Empty--><col style="width: 22%; " class="col_3"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534817360" scope="col">Field</th><th align="left" valign="top" id="idm140209534816272" scope="col">Description</th><th align="left" valign="top" id="idm140209534815184" scope="col">Required/optional</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">Group</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> Group that the API service provides, for example <code class="literal">database.example.com</code>. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">Version</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> Version of the API service, for example <code class="literal">v1alpha1</code>. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">Kind</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> A kind that the API service is expected to provide. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">Name</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> The plural name for the API service provided. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">DeploymentName</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> Name of the deployment defined by your CSV that corresponds to your API service (required for owned API services). During the CSV pending phase, the OLM Operator searches the <code class="literal">InstallStrategy</code> of your CSV for a <code class="literal">Deployment</code> spec with a matching name, and if not found, does not transition the CSV to the "Install Ready" phase. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">DisplayName</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> A human readable version of your API service name, for example <code class="literal">MongoDB Standalone</code>. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">Description</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> A short description of how this API service is used by the Operator or a description of the functionality provided by the API service. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">Resources</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> Your API services own one or more types of Kubernetes objects. These are listed in the resources section to inform your users of the objects they might need to troubleshoot or how to connect to the application, such as the service or ingress rule that exposes a database. </p> <p> It is recommended to only list out the objects that are important to a human, not an exhaustive list of everything you orchestrate. For example, do not list config maps that store internal state that are not meant to be modified by a user. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Optional </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534817360"> <p> <code class="literal">SpecDescriptors</code>, <code class="literal">StatusDescriptors</code>, and <code class="literal">ActionDescriptors</code> </p> </td><td align="left" valign="top" headers="idm140209534816272"> <p> Essentially the same as for owned CRDs. </p> </td><td align="left" valign="top" headers="idm140209534815184"> <p> Optional </p> </td></tr></tbody></table></rh-table><section class="section" id="osdk-apiservices-resource-creation_osdk-generating-csvs"><div class="titlepage"><div><div><h5 class="title">5.7.9.1.1. API service resource creation</h5></div></div></div><p> Operator Lifecycle Manager (OLM) is responsible for creating or replacing the service and API service resources for each unique owned API service: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Service pod selectors are copied from the CSV deployment matching the <code class="literal">DeploymentName</code> field of the API service description. </li><li class="listitem"> A new CA key/certificate pair is generated for each installation and the base64-encoded CA bundle is embedded in the respective API service resource. </li></ul></div></section><section class="section" id="osdk-apiservices-service-certs_osdk-generating-csvs"><div class="titlepage"><div><div><h5 class="title">5.7.9.1.2. API service serving certificates</h5></div></div></div><p> OLM handles generating a serving key/certificate pair whenever an owned API service is being installed. The serving certificate has a common name (CN) containing the hostname of the generated <code class="literal">Service</code> resource and is signed by the private key of the CA bundle embedded in the corresponding API service resource. </p><p> The certificate is stored as a type <code class="literal">kubernetes.io/tls</code> secret in the deployment namespace, and a volume named <code class="literal">apiservice-cert</code> is automatically appended to the volumes section of the deployment in the CSV matching the <code class="literal">DeploymentName</code> field of the API service description. </p><p> If one does not already exist, a volume mount with a matching name is also appended to all containers of that deployment. This allows users to define a volume mount with the expected name to accommodate any custom path requirements. The path of the generated volume mount defaults to <code class="literal">/apiserver.local.config/certificates</code> and any existing volume mounts with the same path are replaced. </p></section></section><section class="section" id="osdk-apiservice-required_osdk-generating-csvs"><div class="titlepage"><div><div><h4 class="title">5.7.9.2. Required API services</h4></div></div></div><p> OLM ensures all required CSVs have an API service that is available and all expected GVKs are discoverable before attempting installation. This allows a CSV to rely on specific kinds provided by API services it does not own. </p><rh-table id="idm140209534742976"><table class="lt-4-cols lt-7-rows"><caption>Table 5.15. Required API service fields</caption><colgroup><col style="width: 22%; " class="col_1"><!--Empty--><col style="width: 56%; " class="col_2"><!--Empty--><col style="width: 22%; " class="col_3"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534737200" scope="col">Field</th><th align="left" valign="top" id="idm140209534736112" scope="col">Description</th><th align="left" valign="top" id="idm140209534735024" scope="col">Required/optional</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534737200"> <p> <code class="literal">Group</code> </p> </td><td align="left" valign="top" headers="idm140209534736112"> <p> Group that the API service provides, for example <code class="literal">database.example.com</code>. </p> </td><td align="left" valign="top" headers="idm140209534735024"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534737200"> <p> <code class="literal">Version</code> </p> </td><td align="left" valign="top" headers="idm140209534736112"> <p> Version of the API service, for example <code class="literal">v1alpha1</code>. </p> </td><td align="left" valign="top" headers="idm140209534735024"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534737200"> <p> <code class="literal">Kind</code> </p> </td><td align="left" valign="top" headers="idm140209534736112"> <p> A kind that the API service is expected to provide. </p> </td><td align="left" valign="top" headers="idm140209534735024"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534737200"> <p> <code class="literal">DisplayName</code> </p> </td><td align="left" valign="top" headers="idm140209534736112"> <p> A human readable version of your API service name, for example <code class="literal">MongoDB Standalone</code>. </p> </td><td align="left" valign="top" headers="idm140209534735024"> <p> Required </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534737200"> <p> <code class="literal">Description</code> </p> </td><td align="left" valign="top" headers="idm140209534736112"> <p> A short description of how this API service is used by the Operator or a description of the functionality provided by the API service. </p> </td><td align="left" valign="top" headers="idm140209534735024"> <p> Required </p> </td></tr></tbody></table></rh-table></section></section></section><section class="section" id="osdk-working-bundle-images"><div class="titlepage"><div><div><h2 class="title">5.8. Working with bundle images</h2></div></div></div><p> You can use the Operator SDK to package, deploy, and upgrade Operators in the bundle format for use on Operator Lifecycle Manager (OLM). </p><section class="section" id="osdk-bundle-operator_osdk-working-bundle-images"><div class="titlepage"><div><div><h3 class="title">5.8.1. Bundling an Operator</h3></div></div></div><p> The Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> OpenShift CLI (<code class="literal">oc</code>) v4.8+ installed </li><li class="listitem"> Operator project initialized by using the Operator SDK </li><li class="listitem"> If your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> commands in your Operator project directory to build and push your Operator image. Modify the <code class="literal">IMG</code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the image: </p><pre class="programlisting language-terminal">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Dockerfile generated by the SDK for the Operator explicitly references <code class="literal">GOARCH=amd64</code> for <code class="literal">go build</code>. This can be amended to <code class="literal">GOARCH=$TARGETARCH</code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by <code class="literal">–platform</code>. With Buildah, the <code class="literal">–build-arg</code> will need to be used for the purpose. For more information, see <a class="link" href="https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures">Multiple Architectures</a>. </p></div></rh-alert></li><li class="listitem"><p class="simpara"> Push the image to a repository: </p><pre class="programlisting language-terminal">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li><li class="listitem"><p class="simpara"> Create your Operator bundle manifest by running the <code class="literal">make bundle</code> command, which invokes several commands, including the Operator SDK <code class="literal">generate bundle</code> and <code class="literal">bundle validate</code> subcommands: </p><pre class="programlisting language-terminal">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> Bundle manifests for an Operator describe how to display, create, and manage an application. The <code class="literal">make bundle</code> command creates the following files and directories in your Operator project: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> A bundle manifests directory named <code class="literal">bundle/manifests</code> that contains a <code class="literal">ClusterServiceVersion</code> object </li><li class="listitem"> A bundle metadata directory named <code class="literal">bundle/metadata</code> </li><li class="listitem"> All custom resource definitions (CRDs) in a <code class="literal">config/crd</code> directory </li><li class="listitem"> A Dockerfile <code class="literal">bundle.Dockerfile</code> </li></ul></div><p class="simpara"> These files are then automatically validated by using <code class="literal">operator-sdk bundle validate</code> to ensure the on-disk bundle representation is correct. </p></li><li class="listitem"><p class="simpara"> Build and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images. </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Build the bundle image. Set <code class="literal">BUNDLE_IMG</code> with the details for the registry, user namespace, and image tag where you intend to push the image: </p><pre class="programlisting language-terminal">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li><li class="listitem"><p class="simpara"> Push the bundle image: </p><pre class="programlisting language-terminal">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre></li></ol></div></li></ol></div></section><section class="section" id="osdk-deploy-olm_osdk-working-bundle-images"><div class="titlepage"><div><div><h3 class="title">5.8.2. Deploying an Operator with Operator Lifecycle Manager</h3></div></div></div><p> Operator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (<code class="literal">oc</code>) for all Operator lifecycle management functions without any additional tools. </p><p> The Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> Operator bundle image built and pushed to a registry </li><li class="listitem"> OLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use <code class="literal">apiextensions.k8s.io/v1</code> CRDs, for example OpenShift Container Platform 4.8) </li><li class="listitem"> Logged in to the cluster with <code class="literal">oc</code> using an account with <code class="literal">cluster-admin</code> permissions </li><li class="listitem"> If your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Enter the following command to run the Operator on the cluster: </p><pre class="programlisting language-terminal">$ operator-sdk run bundle \ [-n &lt;namespace&gt;] \<span id="CO58-1"><!--Empty--></span><span class="callout">1</span> &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO58-1"><span class="callout">1</span></a> </dt><dd><div class="para"> By default, the command installs the Operator in the currently active project in your <code class="literal">~/.kube/config</code> file. You can add the <code class="literal">-n</code> flag to set a different namespace scope for the installation. </div></dd></dl></div><p class="simpara"> This command performs the following actions: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Create an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production. </li><li class="listitem"> Create a catalog source that points to your new index image, which enables OperatorHub to discover your Operator. </li><li class="listitem"> Deploy your Operator to your cluster by creating an <code class="literal">OperatorGroup</code>, <code class="literal">Subscription</code>, <code class="literal">InstallPlan</code>, and all other required objects, including RBAC. </li></ul></div></li></ol></div></section><section class="section" id="osdk-publish-catalog_osdk-working-bundle-images"><div class="titlepage"><div><div><h3 class="title">5.8.3. Publishing a catalog containing a bundled Operator</h3></div></div></div><p> To install and manage Operators, Operator Lifecycle Manager (OLM) requires that Operator bundles are listed in an index image, which is referenced by a catalog on the cluster. As an Operator author, you can use the Operator SDK to create an index containing the bundle for your Operator and all of its dependencies. This is useful for testing on remote clusters and publishing to container registries. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The Operator SDK uses the <code class="literal">opm</code> CLI to facilitate index image creation. Experience with the <code class="literal">opm</code> command is not required. For advanced use cases, the <code class="literal">opm</code> command can be used directly instead of the Operator SDK. </p></div></rh-alert><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed on a development workstation </li><li class="listitem"> Operator bundle image built and pushed to a registry </li><li class="listitem"> OLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use <code class="literal">apiextensions.k8s.io/v1</code> CRDs, for example OpenShift Container Platform 4.8) </li><li class="listitem"> Logged in to the cluster with <code class="literal">oc</code> using an account with <code class="literal">cluster-admin</code> permissions </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Run the following <code class="literal">make</code> command in your Operator project directory to build an index image containing your Operator bundle: </p><pre class="programlisting language-terminal">$ make catalog-build CATALOG_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;index_image_name&gt;:&lt;tag&gt;</pre><p class="simpara"> where the <code class="literal">CATALOG_IMG</code> argument references a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io. </p></li><li class="listitem"><p class="simpara"> Push the built index image to a repository: </p><pre class="programlisting language-terminal">$ make catalog-push CATALOG_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;index_image_name&gt;:&lt;tag&gt;</pre><rh-alert class="admonition tip" state="info"><div class="admonition_header" slot="header">Tip</div><div><p> You can use Operator SDK <code class="literal">make</code> commands together if you would rather perform multiple actions in sequence at once. For example, if you had not yet built a bundle image for your Operator project, you can build and push both a bundle image and an index image with the following syntax: </p><pre class="programlisting language-terminal">$ make bundle-build bundle-push catalog-build catalog-push \ BUNDLE_IMG=&lt;bundle_image_pull_spec&gt; \ CATALOG_IMG=&lt;index_image_pull_spec&gt;</pre><p> Alternatively, you can set the <code class="literal">IMAGE_TAG_BASE</code> field in your <code class="literal">Makefile</code> to an existing repository: </p><pre class="programlisting language-terminal">IMAGE_TAG_BASE=quay.io/example/my-operator</pre><p> You can then use the following syntax to build and push images with automatically-generated names, such as <code class="literal">quay.io/example/my-operator-bundle:v0.0.1</code> for the bundle image and <code class="literal">quay.io/example/my-operator-catalog:v0.0.1</code> for the index image: </p><pre class="programlisting language-terminal">$ make bundle-build bundle-push catalog-build catalog-push</pre></div></rh-alert></li><li class="listitem"><p class="simpara"> Define a <code class="literal">CatalogSource</code> object that references the index image you just generated, and then create the object by using the <code class="literal">oc apply</code> command or web console: </p><div class="formalpara"><p class="title"><strong>Example <code class="literal">CatalogSource</code> YAML</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: operators.coreos.com/v1alpha1 kind: CatalogSource metadata: name: cs-memcached namespace: default spec: displayName: My Test publisher: Company sourceType: grpc image: quay.io/example/memcached-catalog:v0.0.1 <span id="CO59-1"><!--Empty--></span><span class="callout">1</span> updateStrategy: registryPoll: interval: 10m</pre> <p></p></div><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO59-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Set <code class="literal">image</code> to the image pull spec you used previously with the <code class="literal">CATALOG_IMG</code> argument. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> Check the catalog source: </p><pre class="programlisting language-terminal">$ oc get catalogsource</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME DISPLAY TYPE PUBLISHER AGE cs-memcached My Test grpc Company 4h31m</pre> <p></p></div></li></ol></div><div class="orderedlist"><p class="title"><strong>Verification</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Install the Operator using your catalog: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Define an <code class="literal">OperatorGroup</code> object and create it by using the <code class="literal">oc apply</code> command or web console: </p><div class="formalpara"><p class="title"><strong>Example <code class="literal">OperatorGroup</code> YAML</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: my-test namespace: default spec: targetNamespaces: - default</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Define a <code class="literal">Subscription</code> object and create it by using the <code class="literal">oc apply</code> command or web console: </p><div class="formalpara"><p class="title"><strong>Example <code class="literal">Subscription</code> YAML</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: catalogtest namespace: default spec: channel: "alpha" installPlanApproval: Manual name: catalog source: cs-memcached sourceNamespace: default startingCSV: memcached-operator.v0.0.1</pre> <p></p></div></li></ol></div></li><li class="listitem"><p class="simpara"> Verify the installed Operator is running: </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Check the Operator group: </p><pre class="programlisting language-terminal">$ oc get og</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME AGE my-test 4h40m</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the cluster service version (CSV): </p><pre class="programlisting language-terminal">$ oc get csv</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME DISPLAY VERSION REPLACES PHASE memcached-operator.v0.0.1 Test 0.0.1 Succeeded</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Check the pods for the Operator: </p><pre class="programlisting language-terminal">$ oc get pods</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">NAME READY STATUS RESTARTS AGE 9098d908802769fbde8bd45255e69710a9f8420a8f3d814abe88b68f8ervdj6 0/1 Completed 0 4h33m catalog-controller-manager-7fd5b7b987-69s4n 2/2 Running 0 4h32m cs-memcached-7622r 1/1 Running 0 4h33m</pre> <p></p></div></li></ol></div></li></ol></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-managing-custom-catalogs">Managing custom catalogs</a> for details on direct usage of the <code class="literal">opm</code> CLI for more advanced use cases. </li></ul></div></section><section class="section" id="osdk-bundle-upgrade-olm_osdk-working-bundle-images"><div class="titlepage"><div><div><h3 class="title">5.8.4. Testing an Operator upgrade on Operator Lifecycle Manager</h3></div></div></div><p> You can quickly test upgrading your Operator by using Operator Lifecycle Manager (OLM) integration in the Operator SDK, without requiring you to manually manage index images and catalog sources. </p><p> The <code class="literal">run bundle-upgrade</code> subcommand automates triggering an installed Operator to upgrade to a later version by specifying a bundle image for the later version. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator installed with OLM either by using the <code class="literal">run bundle</code> subcommand or with traditional OLM installation </li><li class="listitem"> A bundle image that represents a later version of the installed Operator </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> If your Operator has not already been installed with OLM, install the earlier version either by using the <code class="literal">run bundle</code> subcommand or with traditional OLM installation. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> If the earlier version of the bundle was installed traditionally using OLM, the newer bundle that you intend to upgrade to must not exist in the index image referenced by the catalog source. Otherwise, running the <code class="literal">run bundle-upgrade</code> subcommand will cause the registry pod to fail because the newer bundle is already referenced by the index that provides the package and cluster service version (CSV). </p></div></rh-alert><p class="simpara"> For example, you can use the following <code class="literal">run bundle</code> subcommand for a Memcached Operator by specifying the earlier bundle image: </p><pre class="programlisting language-terminal">$ operator-sdk run bundle &lt;registry&gt;/&lt;user&gt;/memcached-operator:v0.0.1</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">INFO[0009] Successfully created registry pod: quay-io-demo-memcached-operator-v0-0-1 INFO[0009] Created CatalogSource: memcached-operator-catalog INFO[0010] OperatorGroup "operator-sdk-og" created INFO[0010] Created Subscription: memcached-operator-v0-0-1-sub INFO[0013] Approved InstallPlan install-bqggr for the Subscription: memcached-operator-v0-0-1-sub INFO[0013] Waiting for ClusterServiceVersion "my-project/memcached-operator.v0.0.1" to reach 'Succeeded' phase INFO[0013] Waiting for ClusterServiceVersion "my-project/memcached-operator.v0.0.1" to appear INFO[0019] Found ClusterServiceVersion "my-project/memcached-operator.v0.0.1" phase: Succeeded</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Upgrade the installed Operator by specifying the bundle image for the later Operator version: </p><pre class="programlisting language-terminal">$ operator-sdk run bundle-upgrade &lt;registry&gt;/&lt;user&gt;/memcached-operator:v0.0.2</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">INFO[0002] Found existing subscription with name memcached-operator-v0-0-1-sub and namespace my-project INFO[0002] Found existing catalog source with name memcached-operator-catalog and namespace my-project INFO[0009] Successfully created registry pod: quay-io-demo-memcached-operator-v0-0-2 INFO[0009] Updated catalog source memcached-operator-catalog with address and annotations INFO[0010] Deleted previous registry pod with name "quay-io-demo-memcached-operator-v0-0-1" INFO[0041] Approved InstallPlan install-gvcjh for the Subscription: memcached-operator-v0-0-1-sub INFO[0042] Waiting for ClusterServiceVersion "my-project/memcached-operator.v0.0.2" to reach 'Succeeded' phase INFO[0042] Found ClusterServiceVersion "my-project/memcached-operator.v0.0.2" phase: InstallReady INFO[0043] Found ClusterServiceVersion "my-project/memcached-operator.v0.0.2" phase: Installing INFO[0044] Found ClusterServiceVersion "my-project/memcached-operator.v0.0.2" phase: Succeeded INFO[0044] Successfully upgraded to "memcached-operator.v0.0.2"</pre> <p></p></div></li><li class="listitem"><p class="simpara"> Clean up the installed Operators: </p><pre class="programlisting language-terminal">$ operator-sdk cleanup memcached-operator</pre></li></ol></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-adding-operators-to-a-cluster">Traditional Operator installation with OLM</a> </li></ul></div></section><section class="section" id="osdk-control-compat_osdk-working-bundle-images"><div class="titlepage"><div><div><h3 class="title">5.8.5. Controlling Operator compatibility with OpenShift Container Platform versions</h3></div></div></div><rh-alert class="admonition important" state="warning"><div class="admonition_header" slot="header">Important</div><div><p> Kubernetes periodically deprecates certain APIs that are removed in subsequent releases. If your Operator is using a deprecated API, it might no longer work after the OpenShift Container Platform cluster is upgraded to the Kubernetes version where the API has been removed. </p><p> As an Operator author, it is strongly recommended that you review the <a class="link" href="https://kubernetes.io/docs/reference/using-api/deprecation-guide/">Deprecated API Migration Guide</a> in Kubernetes documentation and keep your Operator projects up to date to avoid using deprecated and removed APIs. Ideally, you should update your Operator before the release of a future version of OpenShift Container Platform that would make the Operator incompatible. </p></div></rh-alert><p> When an API is removed from an OpenShift Container Platform version, Operators running on that cluster version that are still using removed APIs will no longer work properly. As an Operator author, you should plan to update your Operator projects to accommodate API deprecation and removal to avoid interruptions for users of your Operator. </p><rh-alert class="admonition tip" state="info"><div class="admonition_header" slot="header">Tip</div><div><p> You can check the event alerts of your Operators running on OpenShift Container Platform 4.8 and later to find whether there are any warnings about APIs currently in use. The following alerts fire when they detect an API in use that will be removed in the next release: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">APIRemovedInNextReleaseInUse</code></span></dt><dd> APIs that will be removed in the next OpenShift Container Platform release. </dd><dt><span class="term"><code class="literal">APIRemovedInNextEUSReleaseInUse</code></span></dt><dd> APIs that will be removed in the next OpenShift Container Platform <a class="link" href="https://access.redhat.com/support/policy/updates/openshift#ocp4_phases">Extended Update Support (EUS)</a> release. </dd></dl></div></div></rh-alert><p> If a cluster administrator has installed your Operator, before they upgrade to the next version of OpenShift Container Platform, they must ensure a version of your Operator is installed that is compatible with that next cluster version. While it is recommended that you update your Operator projects to no longer use deprecated or removed APIs, if you still need to publish your Operator bundles with removed APIs for continued use on earlier versions of OpenShift Container Platform, ensure that the bundle is configured accordingly. </p><p> The following procedure helps prevent administrators from installing versions of your Operator on an incompatible version of OpenShift Container Platform. These steps also prevent administrators from upgrading to a newer version of OpenShift Container Platform that is incompatible with the version of your Operator that is currently installed on their cluster. </p><p> This procedure is also useful when you know that the current version of your Operator will not work well, for any reason, on a specific OpenShift Container Platform version. By defining the cluster versions where the Operator should be distributed, you ensure that the Operator does not appear in a catalog of a cluster version which is outside of the allowed range. </p><rh-alert class="admonition important" state="warning"><div class="admonition_header" slot="header">Important</div><div><p> Operators that use deprecated APIs can adversely impact critical workloads when cluster administrators upgrade to a future version of OpenShift Container Platform where the API is no longer supported. If your Operator is using deprecated APIs, you should configure the following settings in your Operator project as soon as possible. </p></div></rh-alert><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> An existing Operator project </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> If you know that a specific bundle of your Operator is not supported and will not work correctly on OpenShift Container Platform later than a certain cluster version, configure the maximum version of OpenShift Container Platform that your Operator is compatible with. In your Operator project’s cluster service version (CSV), set the <code class="literal">olm.maxOpenShiftVersion</code> annotation to prevent administrators from upgrading their cluster before upgrading the installed Operator to a compatible version: </p><rh-alert class="admonition important" state="warning"><div class="admonition_header" slot="header">Important</div><div><p> You must use <code class="literal">olm.maxOpenShiftVersion</code> annotation only if your Operator bundle version cannot work in later versions. Be aware that cluster admins cannot upgrade their clusters with your solution installed. If you do not provide later version and a valid upgrade path, cluster admins may uninstall your Operator and can upgrade the cluster version. </p></div></rh-alert><div class="formalpara"><p class="title"><strong>Example CSV with <code class="literal">olm.maxOpenShiftVersion</code> annotation</strong></p><p> </p><pre class="programlisting language-yaml">apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: annotations: "olm.properties": '[{"type": "olm.maxOpenShiftVersion", "value": "&lt;cluster_version&gt;"}]' <span id="CO60-1"><!--Empty--></span><span class="callout">1</span></pre> <p></p></div><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO60-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Specify the maximum cluster version of OpenShift Container Platform that your Operator is compatible with. For example, setting <code class="literal">value</code> to <code class="literal">4.8</code> prevents cluster upgrades to OpenShift Container Platform versions later than 4.8 when this bundle is installed on a cluster. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> If your bundle is intended for distribution in a Red Hat-provided Operator catalog, configure the compatible versions of OpenShift Container Platform for your Operator by setting the following properties. This configuration ensures your Operator is only included in catalogs that target compatible versions of OpenShift Container Platform: </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> This step is only valid when publishing Operators in Red Hat-provided catalogs. If your bundle is only intended for distribution in a custom catalog, you can skip this step. For more details, see "Red Hat-provided Operator catalogs". </p></div></rh-alert><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p class="simpara"> Set the <code class="literal">com.redhat.openshift.versions</code> annotation in your project’s <code class="literal">bundle/metadata/annotations.yaml</code> file: </p><div class="formalpara"><p class="title"><strong>Example <code class="literal">bundle/metadata/annotations.yaml</code> file with compatible versions</strong></p><p> </p><pre class="programlisting language-yaml">com.redhat.openshift.versions: "v4.6-v4.8" <span id="CO61-1"><!--Empty--></span><span class="callout">1</span></pre> <p></p></div><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO61-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Set to a range or single version. </div></dd></dl></div></li><li class="listitem"><p class="simpara"> To prevent your bundle from being carried on to an incompatible version of OpenShift Container Platform, ensure that the index image is generated with the proper <code class="literal">com.redhat.openshift.versions</code> label in your Operator’s bundle image. For example, if your project was generated using the Operator SDK, update the <code class="literal">bundle.Dockerfile</code> file: </p><div class="formalpara"><p class="title"><strong>Example <code class="literal">bundle.Dockerfile</code> with compatible versions</strong></p><p> </p><pre class="programlisting language-yaml">LABEL com.redhat.openshift.versions="&lt;versions&gt;" <span id="CO62-1"><!--Empty--></span><span class="callout">1</span></pre> <p></p></div><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO62-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Set to a range or single version, for example, <code class="literal">v4.6-v4.8</code>. This setting defines the cluster versions where the Operator should be distributed, and the Operator does not appear in a catalog of a cluster version which is outside of the range. </div></dd></dl></div></li></ol></div></li></ol></div><p> You can now bundle a new version of your Operator and publish the updated version to a catalog for distribution. </p><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> <a class="link" href="https://redhat-connect.gitbook.io/certified-operator-guide/ocp-deployment/operator-metadata/bundle-directory/managing-openshift-versions">Managing OpenShift Versions</a> in the <span class="emphasis"><em>Certified Operator Build Guide</em></span> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-upgrading-operators">Updating installed Operators</a> </li><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-rh-catalogs">Red Hat-provided Operator catalogs</a> </li></ul></div></section><section class="section _additional-resources" id="osdk-working-bundle-images-additional-resources"><div class="titlepage"><div><div><h3 class="title">5.8.6. Additional resources</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-bundle-format_olm-packaging-format">Operator Framework packaging formats</a> for details on the bundle format. </li><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-managing-custom-catalogs">Managing custom catalogs</a> for details on adding bundle images to index images by using the <code class="literal">opm</code> command. </li><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-workflow">Operator Lifecycle Manager workflow</a> for details on how upgrades work for installed Operators. </li></ul></div></section></section><section class="section" id="osdk-scorecard"><div class="titlepage"><div><div><h2 class="title">5.9. Validating Operators using the scorecard tool</h2></div></div></div><p> As an Operator author, you can use the scorecard tool in the Operator SDK to do the following tasks: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Validate that your Operator project is free of syntax errors and packaged correctly </li><li class="listitem"> Review suggestions about ways you can improve your Operator </li></ul></div><section class="section" id="osdk-about-scorecard_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.1. About the scorecard tool</h3></div></div></div><p> While the Operator SDK <code class="literal">bundle validate</code> subcommand can validate local bundle directories and remote bundle images for content and structure, you can use the <code class="literal">scorecard</code> command to run tests on your Operator based on a configuration file and test images. These tests are implemented within test images that are configured and constructed to be executed by the scorecard. </p><p> The scorecard assumes it is run with access to a configured Kubernetes cluster, such as OpenShift Container Platform. The scorecard runs each test within a pod, from which pod logs are aggregated and test results are sent to the console. The scorecard has built-in basic and Operator Lifecycle Manager (OLM) tests and also provides a means to execute custom test definitions. </p><div class="orderedlist"><p class="title"><strong>Scorecard workflow</strong></p><ol class="orderedlist" type="1"><li class="listitem"> Create all resources required by any related custom resources (CRs) and the Operator </li><li class="listitem"> Create a proxy container in the deployment of the Operator to record calls to the API server and run tests </li><li class="listitem"> Examine parameters in the CRs </li></ol></div><p> The scorecard tests make no assumptions as to the state of the Operator being tested. Creating Operators and CRs for an Operators are beyond the scope of the scorecard itself. Scorecard tests can, however, create whatever resources they require if the tests are designed for resource creation. </p><div class="formalpara"><p class="title"><strong><code class="literal">scorecard</code> command syntax</strong></p><p> </p><pre class="programlisting language-terminal">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; [flags]</pre> <p></p></div><p> The scorecard requires a positional argument for either the on-disk path to your Operator bundle or the name of a bundle image. </p><p> For further information about the flags, run: </p><pre class="programlisting language-terminal">$ operator-sdk scorecard -h</pre></section><section class="section" id="osdk-scorecard-config_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.2. Scorecard configuration</h3></div></div></div><p> The scorecard tool uses a configuration that allows you to configure internal plugins, as well as several global configuration options. Tests are driven by a configuration file named <code class="literal">config.yaml</code>, which is generated by the <code class="literal">make bundle</code> command, located in your <code class="literal">bundle/</code> directory: </p><pre class="programlisting language-terminal">./bundle ... └── tests └── scorecard └── config.yaml</pre><div class="formalpara"><p class="title"><strong>Example scorecard configuration file</strong></p><p> </p><pre class="programlisting language-yaml">kind: Configuration apiversion: scorecard.operatorframework.io/v1alpha3 metadata: name: config stages: - parallel: true tests: - image: quay.io/operator-framework/scorecard-test:v1.8.0 entrypoint: - scorecard-test - basic-check-spec labels: suite: basic test: basic-check-spec-test - image: quay.io/operator-framework/scorecard-test:v1.8.0 entrypoint: - scorecard-test - olm-bundle-validation labels: suite: olm test: olm-bundle-validation-test</pre> <p></p></div><p> The configuration file defines each test that scorecard can execute. The following fields of the scorecard configuration file define the test as follows: </p><rh-table><table class="lt-4-cols lt-7-rows"><colgroup><col style="width: 30%; " class="col_1"><!--Empty--><col style="width: 70%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534436000" scope="col">Configuration field</th><th align="left" valign="top" id="idm140209534434912" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534436000"> <p> <code class="literal">image</code> </p> </td><td align="left" valign="top" headers="idm140209534434912"> <p> Test container image name that implements a test </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534436000"> <p> <code class="literal">entrypoint</code> </p> </td><td align="left" valign="top" headers="idm140209534434912"> <p> Command and arguments that are invoked in the test image to execute a test </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534436000"> <p> <code class="literal">labels</code> </p> </td><td align="left" valign="top" headers="idm140209534434912"> <p> Scorecard-defined or custom labels that select which tests to run </p> </td></tr></tbody></table></rh-table></section><section class="section" id="osdk-scorecard-tests_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.3. Built-in scorecard tests</h3></div></div></div><p> The scorecard ships with pre-defined tests that are arranged into suites: the basic test suite and the Operator Lifecycle Manager (OLM) suite. </p><rh-table id="osdk-scorecard-basic-tests_osdk-scorecard"><table class="lt-4-cols lt-7-rows"><caption>Table 5.16. Basic test suite</caption><colgroup><col style="width: 23%; " class="col_1"><!--Empty--><col style="width: 54%; " class="col_2"><!--Empty--><col style="width: 23%; " class="col_3"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534411664" scope="col">Test</th><th align="left" valign="top" id="idm140209534410576" scope="col">Description</th><th align="left" valign="top" id="idm140209534409488" scope="col">Short name</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534411664"> <p> Spec Block Exists </p> </td><td align="left" valign="top" headers="idm140209534410576"> <p> This test checks the custom resource (CR) created in the cluster to make sure that all CRs have a <code class="literal">spec</code> block. </p> </td><td align="left" valign="top" headers="idm140209534409488"> <p> <code class="literal">basic-check-spec-test</code> </p> </td></tr></tbody></table></rh-table><rh-table id="osdk-scorecard-olm-tests_osdk-scorecard"><table class="lt-4-cols lt-7-rows"><caption>Table 5.17. OLM test suite</caption><colgroup><col style="width: 23%; " class="col_1"><!--Empty--><col style="width: 54%; " class="col_2"><!--Empty--><col style="width: 23%; " class="col_3"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534394736" scope="col">Test</th><th align="left" valign="top" id="idm140209534393648" scope="col">Description</th><th align="left" valign="top" id="idm140209534392560" scope="col">Short name</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534394736"> <p> Bundle Validation </p> </td><td align="left" valign="top" headers="idm140209534393648"> <p> This test validates the bundle manifests found in the bundle that is passed into scorecard. If the bundle contents contain errors, then the test result output includes the validator log as well as error messages from the validation library. </p> </td><td align="left" valign="top" headers="idm140209534392560"> <p> <code class="literal">olm-bundle-validation-test</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534394736"> <p> Provided APIs Have Validation </p> </td><td align="left" valign="top" headers="idm140209534393648"> <p> This test verifies that the custom resource definitions (CRDs) for the provided CRs contain a validation section and that there is validation for each <code class="literal">spec</code> and <code class="literal">status</code> field detected in the CR. </p> </td><td align="left" valign="top" headers="idm140209534392560"> <p> <code class="literal">olm-crds-have-validation-test</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534394736"> <p> Owned CRDs Have Resources Listed </p> </td><td align="left" valign="top" headers="idm140209534393648"> <p> This test makes sure that the CRDs for each CR provided via the <code class="literal">cr-manifest</code> option have a <code class="literal">resources</code> subsection in the <code class="literal">owned</code> CRDs section of the ClusterServiceVersion (CSV). If the test detects used resources that are not listed in the resources section, it lists them in the suggestions at the end of the test. Users are required to fill out the resources section after initial code generation for this test to pass. </p> </td><td align="left" valign="top" headers="idm140209534392560"> <p> <code class="literal">olm-crds-have-resources-test</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534394736"> <p> Spec Fields With Descriptors </p> </td><td align="left" valign="top" headers="idm140209534393648"> <p> This test verifies that every field in the CRs <code class="literal">spec</code> sections has a corresponding descriptor listed in the CSV. </p> </td><td align="left" valign="top" headers="idm140209534392560"> <p> <code class="literal">olm-spec-descriptors-test</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534394736"> <p> Status Fields With Descriptors </p> </td><td align="left" valign="top" headers="idm140209534393648"> <p> This test verifies that every field in the CRs <code class="literal">status</code> sections have a corresponding descriptor listed in the CSV. </p> </td><td align="left" valign="top" headers="idm140209534392560"> <p> <code class="literal">olm-status-descriptors-test</code> </p> </td></tr></tbody></table></rh-table></section><section class="section" id="osdk-scorecard-run_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.4. Running the scorecard tool</h3></div></div></div><p> A default set of Kustomize files are generated by the Operator SDK after running the <code class="literal">init</code> command. The default <code class="literal">bundle/tests/scorecard/config.yaml</code> file that is generated can be immediately used to run the scorecard tool against your Operator, or you can modify this file to your test specifications. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator project generated by using the Operator SDK </li></ul></div><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> Generate or regenerate your bundle manifests and metadata for your Operator: </p><pre class="programlisting language-terminal">$ make bundle</pre><p class="simpara"> This command automatically adds scorecard annotations to your bundle metadata, which is used by the <code class="literal">scorecard</code> command to run tests. </p></li><li class="listitem"><p class="simpara"> Run the scorecard against the on-disk path to your Operator bundle or the name of a bundle image: </p><pre class="programlisting language-terminal">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt;</pre></li></ol></div></section><section class="section" id="osdk-scorecard-output_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.5. Scorecard output</h3></div></div></div><p> The <code class="literal">--output</code> flag for the <code class="literal">scorecard</code> command specifies the scorecard results output format: either <code class="literal">text</code> or <code class="literal">json</code>. </p><div class="example" id="idm140209534341744"><p class="title"><strong>Example 5.29. Example JSON output snippet</strong></p><div class="example-contents"><pre class="programlisting language-json">{ "apiVersion": "scorecard.operatorframework.io/v1alpha3", "kind": "TestList", "items": [ { "kind": "Test", "apiVersion": "scorecard.operatorframework.io/v1alpha3", "spec": { "image": "quay.io/operator-framework/scorecard-test:v1.8.0", "entrypoint": [ "scorecard-test", "olm-bundle-validation" ], "labels": { "suite": "olm", "test": "olm-bundle-validation-test" } }, "status": { "results": [ { "name": "olm-bundle-validation", "log": "time=\"2020-06-10T19:02:49Z\" level=debug msg=\"Found manifests directory\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=debug msg=\"Found metadata directory\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=debug msg=\"Getting mediaType info from manifests directory\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=info msg=\"Found annotations file\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=info msg=\"Could not find optional dependencies file\" name=bundle-test\n", "state": "pass" } ] } } ] }</pre></div></div><div class="example" id="idm140209534338576"><p class="title"><strong>Example 5.30. Example text output snippet</strong></p><div class="example-contents"><pre class="programlisting language-text">-------------------------------------------------------------------------------- Image: quay.io/operator-framework/scorecard-test:v1.8.0 Entrypoint: [scorecard-test olm-bundle-validation] Labels: "suite":"olm" "test":"olm-bundle-validation-test" Results: Name: olm-bundle-validation State: pass Log: time="2020-07-15T03:19:02Z" level=debug msg="Found manifests directory" name=bundle-test time="2020-07-15T03:19:02Z" level=debug msg="Found metadata directory" name=bundle-test time="2020-07-15T03:19:02Z" level=debug msg="Getting mediaType info from manifests directory" name=bundle-test time="2020-07-15T03:19:02Z" level=info msg="Found annotations file" name=bundle-test time="2020-07-15T03:19:02Z" level=info msg="Could not find optional dependencies file" name=bundle-test</pre></div></div><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> The output format spec matches the <a class="link" href="https://pkg.go.dev/github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3#Test"><code class="literal">Test</code></a> type layout. </p></div></rh-alert></section><section class="section" id="osdk-scorecard-select-tests_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.6. Selecting tests</h3></div></div></div><p> Scorecard tests are selected by setting the <code class="literal">--selector</code> CLI flag to a set of label strings. If a selector flag is not supplied, then all the tests within the scorecard configuration file are run. </p><p> Tests are run serially with test results being aggregated by the scorecard and written to standard output, or <span class="emphasis"><em>stdout</em></span>. </p><div class="orderedlist"><p class="title"><strong>Procedure</strong></p><ol class="orderedlist" type="1"><li class="listitem"><p class="simpara"> To select a single test, for example <code class="literal">basic-check-spec-test</code>, specify the test by using the <code class="literal">--selector</code> flag: </p><pre class="programlisting language-terminal">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; \ -o text \ --selector=test=basic-check-spec-test</pre></li><li class="listitem"><p class="simpara"> To select a suite of tests, for example <code class="literal">olm</code>, specify a label that is used by all of the OLM tests: </p><pre class="programlisting language-terminal">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; \ -o text \ --selector=suite=olm</pre></li><li class="listitem"><p class="simpara"> To select multiple tests, specify the test names by using the <code class="literal">selector</code> flag using the following syntax: </p><pre class="programlisting language-terminal">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; \ -o text \ --selector='test in (basic-check-spec-test,olm-bundle-validation-test)'</pre></li></ol></div></section><section class="section" id="osdk-scorecard-parallel_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.7. Enabling parallel testing</h3></div></div></div><p> As an Operator author, you can define separate stages for your tests using the scorecard configuration file. Stages run sequentially in the order they are defined in the configuration file. A stage contains a list of tests and a configurable <code class="literal">parallel</code> setting. </p><p> By default, or when a stage explicitly sets <code class="literal">parallel</code> to <code class="literal">false</code>, tests in a stage are run sequentially in the order they are defined in the configuration file. Running tests one at a time is helpful to guarantee that no two tests interact and conflict with each other. </p><p> However, if tests are designed to be fully isolated, they can be parallelized. </p><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> To run a set of isolated tests in parallel, include them in the same stage and set <code class="literal">parallel</code> to <code class="literal">true</code>: </p><pre class="programlisting language-terminal">apiVersion: scorecard.operatorframework.io/v1alpha3 kind: Configuration metadata: name: config stages: - parallel: true <span id="CO63-1"><!--Empty--></span><span class="callout">1</span> tests: - entrypoint: - scorecard-test - basic-check-spec image: quay.io/operator-framework/scorecard-test:v1.8.0 labels: suite: basic test: basic-check-spec-test - entrypoint: - scorecard-test - olm-bundle-validation image: quay.io/operator-framework/scorecard-test:v1.8.0 labels: suite: olm test: olm-bundle-validation-test</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO63-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Enables parallel testing </div></dd></dl></div><p class="simpara"> All tests in a parallel stage are executed simultaneously, and scorecard waits for all of them to finish before proceding to the next stage. This can make your tests run much faster. </p></li></ul></div></section><section class="section" id="osdk-scorecard-custom-tests_osdk-scorecard"><div class="titlepage"><div><div><h3 class="title">5.9.8. Custom scorecard tests</h3></div></div></div><p> The scorecard tool can run custom tests that follow these mandated conventions: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Tests are implemented within a container image </li><li class="listitem"> Tests accept an entrypoint which include a command and arguments </li><li class="listitem"> Tests produce <code class="literal">v1alpha3</code> scorecard output in JSON format with no extraneous logging in the test output </li><li class="listitem"> Tests can obtain the bundle contents at a shared mount point of <code class="literal">/bundle</code> </li><li class="listitem"> Tests can access the Kubernetes API using an in-cluster client connection </li></ul></div><p> Writing custom tests in other programming languages is possible if the test image follows the above guidelines. </p><p> The following example shows of a custom test image written in Go: </p><div class="example" id="idm140209534297216"><p class="title"><strong>Example 5.31. Example custom scorecard test</strong></p><div class="example-contents"><pre class="programlisting language-go">// Copyright 2020 The Operator-SDK Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "encoding/json" "fmt" "log" "os" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" ) // This is the custom scorecard test example binary // As with the Redhat scorecard test image, the bundle that is under // test is expected to be mounted so that tests can inspect the // bundle contents as part of their test implementations. // The actual test is to be run is named and that name is passed // as an argument to this binary. This argument mechanism allows // this binary to run various tests all from within a single // test image. const PodBundleRoot = "/bundle" func main() { entrypoint := os.Args[1:] if len(entrypoint) == 0 { log.Fatal("Test name argument is required") } // Read the pod's untar'd bundle from a well-known path. cfg, err := apimanifests.GetBundleFromDir(PodBundleRoot) if err != nil { log.Fatal(err.Error()) } var result scapiv1alpha3.TestStatus // Names of the custom tests which would be passed in the // `operator-sdk` command. switch entrypoint[0] { case CustomTest1Name: result = CustomTest1(cfg) case CustomTest2Name: result = CustomTest2(cfg) default: result = printValidTests() } // Convert scapiv1alpha3.TestResult to json. prettyJSON, err := json.MarshalIndent(result, "", " ") if err != nil { log.Fatal("Failed to generate json", err) } fmt.Printf("%s\n", string(prettyJSON)) } // printValidTests will print out full list of test names to give a hint to the end user on what the valid tests are. func printValidTests() scapiv1alpha3.TestStatus { result := scapiv1alpha3.TestResult{} result.State = scapiv1alpha3.FailState result.Errors = make([]string, 0) result.Suggestions = make([]string, 0) str := fmt.Sprintf("Valid tests for this image include: %s %s", CustomTest1Name, CustomTest2Name) result.Errors = append(result.Errors, str) return scapiv1alpha3.TestStatus{ Results: []scapiv1alpha3.TestResult{result}, } } const ( CustomTest1Name = "customtest1" CustomTest2Name = "customtest2" ) // Define any operator specific custom tests here. // CustomTest1 and CustomTest2 are example test functions. Relevant operator specific // test logic is to be implemented in similarly. func CustomTest1(bundle *apimanifests.Bundle) scapiv1alpha3.TestStatus { r := scapiv1alpha3.TestResult{} r.Name = CustomTest1Name r.State = scapiv1alpha3.PassState r.Errors = make([]string, 0) r.Suggestions = make([]string, 0) almExamples := bundle.CSV.GetAnnotations()["alm-examples"] if almExamples == "" { fmt.Println("no alm-examples in the bundle CSV") } return wrapResult(r) } func CustomTest2(bundle *apimanifests.Bundle) scapiv1alpha3.TestStatus { r := scapiv1alpha3.TestResult{} r.Name = CustomTest2Name r.State = scapiv1alpha3.PassState r.Errors = make([]string, 0) r.Suggestions = make([]string, 0) almExamples := bundle.CSV.GetAnnotations()["alm-examples"] if almExamples == "" { fmt.Println("no alm-examples in the bundle CSV") } return wrapResult(r) } func wrapResult(r scapiv1alpha3.TestResult) scapiv1alpha3.TestStatus { return scapiv1alpha3.TestStatus{ Results: []scapiv1alpha3.TestResult{r}, } }</pre></div></div></section></section><section class="section" id="osdk-monitoring-prometheus"><div class="titlepage"><div><div><h2 class="title">5.10. Configuring built-in monitoring with Prometheus</h2></div></div></div><p> This guide describes the built-in monitoring support provided by the Operator SDK using the Prometheus Operator and details usage for Operator authors. </p><section class="section" id="osdk-monitoring-prometheus-operator-support_osdk-monitoring-prometheus"><div class="titlepage"><div><div><h3 class="title">5.10.1. Prometheus Operator support</h3></div></div></div><p> <a class="link" href="https://prometheus.io/">Prometheus</a> is an open-source systems monitoring and alerting toolkit. The Prometheus Operator creates, configures, and manages Prometheus clusters running on Kubernetes-based clusters, such as OpenShift Container Platform. </p><p> Helper functions exist in the Operator SDK by default to automatically set up metrics in any generated Go-based Operator for use on clusters where the Prometheus Operator is deployed. </p></section><section class="section" id="osdk-monitoring-prometheus-metrics-helper_osdk-monitoring-prometheus"><div class="titlepage"><div><div><h3 class="title">5.10.2. Metrics helper</h3></div></div></div><p> In Go-based Operators generated using the Operator SDK, the following function exposes general metrics about the running program: </p><pre class="programlisting language-go">func ExposeMetricsPort(ctx context.Context, port int32) (*v1.Service, error)</pre><p> These metrics are inherited from the <code class="literal">controller-runtime</code> library API. By default, the metrics are served on <code class="literal">0.0.0.0:8383/metrics</code>. </p><p> A <code class="literal">Service</code> object is created with the metrics port exposed, which can be then accessed by Prometheus. The <code class="literal">Service</code> object is garbage collected when the leader pod’s <code class="literal">root</code> owner is deleted. </p><p> The following example is present in the <code class="literal">cmd/manager/main.go</code> file in all Operators generated using the Operator SDK: </p><pre class="programlisting language-go">import( "github.com/operator-framework/operator-sdk/pkg/metrics" "machine.openshift.io/controller-runtime/pkg/manager" ) var ( // Change the below variables to serve metrics on a different host or port. metricsHost = "0.0.0.0" <span id="CO64-1"><!--Empty--></span><span class="callout">1</span> metricsPort int32 = 8383 <span id="CO64-2"><!--Empty--></span><span class="callout">2</span> ) ... func main() { ... // Pass metrics address to controller-runtime manager mgr, err := manager.New(cfg, manager.Options{ Namespace: namespace, MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort), }) ... // Create Service object to expose the metrics port. _, err = metrics.ExposeMetricsPort(ctx, metricsPort) if err != nil { // handle error log.Info(err.Error()) } ... }</pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO64-1"><span class="callout">1</span></a> </dt><dd><div class="para"> The host that the metrics are exposed on. </div></dd><dt><a href="#CO64-2"><span class="callout">2</span></a> </dt><dd><div class="para"> The port that the metrics are exposed on. </div></dd></dl></div><section class="section" id="osdk-monitoring-prometheus-metrics-helper-modifying-port_osdk-monitoring-prometheus"><div class="titlepage"><div><div><h4 class="title">5.10.2.1. Modifying the metrics port</h4></div></div></div><p> Operator authors can modify the port that metrics are exposed on. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Go-based Operator generated using the Operator SDK </li><li class="listitem"> Kubernetes-based cluster with the Prometheus Operator deployed </li></ul></div><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> In the <code class="literal">cmd/manager/main.go</code> file of the generated Operator, change the value of <code class="literal">metricsPort</code> in the following line: </p><pre class="programlisting language-go">var metricsPort int32 = 8383</pre></li></ul></div></section></section><section class="section" id="osdk-monitoring-prometheus-servicemonitor_osdk-monitoring-prometheus"><div class="titlepage"><div><div><h3 class="title">5.10.3. Service monitors</h3></div></div></div><p> A <code class="literal">ServiceMonitor</code> is a custom resource provided by the Prometheus Operator that discovers the <code class="literal">Endpoints</code> in <code class="literal">Service</code> objects and configures Prometheus to monitor those pods. </p><p> In Go-based Operators generated using the Operator SDK, the <code class="literal">GenerateServiceMonitor()</code> helper function can take a <code class="literal">Service</code> object and generate a <code class="literal">ServiceMonitor</code> object based on it. </p><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> See the <a class="link" href="https://github.com/coreos/prometheus-operator/blob/7a25bf6b6bb2347dacb235659b73bc210117acc7/Documentation/design.md#servicemonitor">Prometheus Operator documentation</a> for more information about the <code class="literal">ServiceMonitor</code> custom resource definition (CRD). </li></ul></div><section class="section" id="osdk-monitoring-prometheus-servicemonitor-creating_osdk-monitoring-prometheus"><div class="titlepage"><div><div><h4 class="title">5.10.3.1. Creating service monitors</h4></div></div></div><p> Operator authors can add service target discovery of created monitoring services using the <code class="literal">metrics.CreateServiceMonitor()</code> helper function, which accepts the newly created service. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Go-based Operator generated using the Operator SDK </li><li class="listitem"> Kubernetes-based cluster with the Prometheus Operator deployed </li></ul></div><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Add the <code class="literal">metrics.CreateServiceMonitor()</code> helper function to your Operator code: </p><pre class="programlisting language-go">import( "k8s.io/api/core/v1" "github.com/operator-framework/operator-sdk/pkg/metrics" "machine.openshift.io/controller-runtime/pkg/client/config" ) func main() { ... // Populate below with the Service(s) for which you want to create ServiceMonitors. services := []*v1.Service{} // Create one ServiceMonitor per application per namespace. // Change the below value to name of the Namespace you want the ServiceMonitor to be created in. ns := "default" // restConfig is used for talking to the Kubernetes apiserver restConfig := config.GetConfig() // Pass the Service(s) to the helper function, which in turn returns the array of ServiceMonitor objects. serviceMonitors, err := metrics.CreateServiceMonitors(restConfig, ns, services) if err != nil { // Handle errors here. } ... }</pre></li></ul></div></section></section></section><section class="section" id="osdk-leader-election"><div class="titlepage"><div><div><h2 class="title">5.11. Configuring leader election</h2></div></div></div><p> During the lifecycle of an Operator, it is possible that there may be more than one instance running at any given time, for example when rolling out an upgrade for the Operator. In such a scenario, it is necessary to avoid contention between multiple Operator instances using leader election. This ensures only one leader instance handles the reconciliation while the other instances are inactive but ready to take over when the leader steps down. </p><p> There are two different leader election implementations to choose from, each with its own trade-off: </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Leader-for-life</span></dt><dd> The leader pod only gives up leadership, using garbage collection, when it is deleted. This implementation precludes the possibility of two instances mistakenly running as leaders, a state also known as split brain. However, this method can be subject to a delay in electing a new leader. For example, when the leader pod is on an unresponsive or partitioned node, the <a class="link" href="https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/#options"><code class="literal">pod-eviction-timeout</code></a> dictates long how it takes for the leader pod to be deleted from the node and step down, with a default of <code class="literal">5m</code>. See the <a class="link" href="https://godoc.org/github.com/operator-framework/operator-sdk/pkg/leader">Leader-for-life</a> Go documentation for more. </dd><dt><span class="term">Leader-with-lease</span></dt><dd> The leader pod periodically renews the leader lease and gives up leadership when it cannot renew the lease. This implementation allows for a faster transition to a new leader when the existing leader is isolated, but there is a possibility of split brain in <a class="link" href="https://github.com/kubernetes/client-go/blob/30b06a83d67458700a5378239df6b96948cb9160/tools/leaderelection/leaderelection.go#L21-L24">certain situations</a>. See the <a class="link" href="https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/leaderelection">Leader-with-lease</a> Go documentation for more. </dd></dl></div><p> By default, the Operator SDK enables the Leader-for-life implementation. Consult the related Go documentation for both approaches to consider the trade-offs that make sense for your use case. </p><section class="section" id="osdk-leader-election-types_osdk-leader-election"><div class="titlepage"><div><div><h3 class="title">5.11.1. Operator leader election examples</h3></div></div></div><p> The following examples illustrate how to use the two leader election options for an Operator, Leader-for-life and Leader-with-lease. </p><section class="section" id="osdk-leader-for-life-election_osdk-leader-election"><div class="titlepage"><div><div><h4 class="title">5.11.1.1. Leader-for-life election</h4></div></div></div><p> With the Leader-for-life election implementation, a call to <code class="literal">leader.Become()</code> blocks the Operator as it retries until it can become the leader by creating the config map named <code class="literal">memcached-operator-lock</code>: </p><pre class="programlisting language-go">import ( ... "github.com/operator-framework/operator-sdk/pkg/leader" ) func main() { ... err = leader.Become(context.TODO(), "memcached-operator-lock") if err != nil { log.Error(err, "Failed to retry for leader lock") os.Exit(1) } ... }</pre><p> If the Operator is not running inside a cluster, <code class="literal">leader.Become()</code> simply returns without error to skip the leader election since it cannot detect the name of the Operator. </p></section><section class="section" id="osdk-leader-with-lease-election_osdk-leader-election"><div class="titlepage"><div><div><h4 class="title">5.11.1.2. Leader-with-lease election</h4></div></div></div><p> The Leader-with-lease implementation can be enabled using the <a class="link" href="https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/manager#Options">Manager Options</a> for leader election: </p><pre class="programlisting language-go">import ( ... "sigs.k8s.io/controller-runtime/pkg/manager" ) func main() { ... opts := manager.Options{ ... LeaderElection: true, LeaderElectionID: "memcached-operator-lock" } mgr, err := manager.New(cfg, opts) ... }</pre><p> When the Operator is not running in a cluster, the Manager returns an error when starting because it cannot detect the namespace of the Operator to create the config map for leader election. You can override this namespace by setting the <code class="literal">LeaderElectionNamespace</code> option for the Manager. </p></section></section></section><section class="section" id="osdk-pkgman-to-bundle"><div class="titlepage"><div><div><h2 class="title">5.12. Migrating package manifest projects to bundle format</h2></div></div></div><p> Support for the legacy <span class="emphasis"><em>package manifest format</em></span> for Operators is removed in OpenShift Container Platform 4.8 and later. If you have an Operator project that was initially created using the package manifest format, you can use the Operator SDK to migrate the project to the bundle format. The bundle format is the preferred packaging format for Operator Lifecycle Manager (OLM) starting in OpenShift Container Platform 4.6. </p><section class="section" id="osdk-about-pkg-format-migration_osdk-pkgman-to-bundle"><div class="titlepage"><div><div><h3 class="title">5.12.1. About packaging format migration</h3></div></div></div><p> The Operator SDK <code class="literal">pkgman-to-bundle</code> command helps in migrating Operator Lifecycle Manager (OLM) package manifests to bundles. The command takes an input package manifest directory and generates bundles for each of the versions of manifests present in the input directory. You can also then build bundle images for each of the generated bundles. </p><p> For example, consider the following <code class="literal">packagemanifests/</code> directory for a project in the package manifest format: </p><div class="formalpara"><p class="title"><strong>Example package manifest format layout</strong></p><p> </p><pre class="programlisting language-terminal">packagemanifests/ └── etcd ├── 0.0.1 │ ├── etcdcluster.crd.yaml │ └── etcdoperator.clusterserviceversion.yaml ├── 0.0.2 │ ├── etcdbackup.crd.yaml │ ├── etcdcluster.crd.yaml │ ├── etcdoperator.v0.0.2.clusterserviceversion.yaml │ └── etcdrestore.crd.yaml └── etcd.package.yaml</pre> <p></p></div><p> After running the migration, the following bundles are generated in the <code class="literal">bundle/</code> directory: </p><div class="formalpara"><p class="title"><strong>Example bundle format layout</strong></p><p> </p><pre class="programlisting language-terminal">bundle/ ├── bundle-0.0.1 │   ├── bundle.Dockerfile │   ├── manifests │   │   ├── etcdcluster.crd.yaml │   │   ├── etcdoperator.clusterserviceversion.yaml │   ├── metadata │   │   └── annotations.yaml │   └── tests │   └── scorecard │   └── config.yaml └── bundle-0.0.2 ├── bundle.Dockerfile ├── manifests │   ├── etcdbackup.crd.yaml │   ├── etcdcluster.crd.yaml │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml │   ├── etcdrestore.crd.yaml ├── metadata │   └── annotations.yaml └── tests └── scorecard └── config.yaml</pre> <p></p></div><p> Based on this generated layout, bundle images for both of the bundles are also built with the following names: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> <code class="literal">quay.io/example/etcd:0.0.1</code> </li><li class="listitem"> <code class="literal">quay.io/example/etcd:0.0.2</code> </li></ul></div><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-packaging-format">Operator Framework packaging formats</a> </li></ul></div></section><section class="section" id="osdk-migrating-pkgman_osdk-pkgman-to-bundle"><div class="titlepage"><div><div><h3 class="title">5.12.2. Migrating a package manifest project to bundle format</h3></div></div></div><p> Operator authors can use the Operator SDK to migrate a package manifest format Operator project to a bundle format project. </p><div class="itemizedlist"><p class="title"><strong>Prerequisites</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"> Operator SDK CLI installed </li><li class="listitem"> Operator project initially generated using the Operator SDK in package manifest format </li></ul></div><div class="itemizedlist"><p class="title"><strong>Procedure</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Use the Operator SDK to migrate your package manifest project to the bundle format and generate bundle images: </p><pre class="programlisting language-terminal">$ operator-sdk pkgman-to-bundle &lt;package_manifests_dir&gt; \ <span id="CO65-1"><!--Empty--></span><span class="callout">1</span> [--output-dir &lt;directory&gt;] \ <span id="CO65-2"><!--Empty--></span><span class="callout">2</span> --image-tag-base &lt;image_name_base&gt; <span id="CO65-3"><!--Empty--></span><span class="callout">3</span></pre><div class="calloutlist"><dl class="calloutlist"><dt><a href="#CO65-1"><span class="callout">1</span></a> </dt><dd><div class="para"> Specify the location of the package manifests directory for the project, such as <code class="literal">packagemanifests/</code> or <code class="literal">manifests/</code>. </div></dd><dt><a href="#CO65-2"><span class="callout">2</span></a> </dt><dd><div class="para"> Optional: By default, the generated bundles are written locally to disk to the <code class="literal">bundle/</code> directory. You can use the <code class="literal">--output-dir</code> flag to specify an alternative location. </div></dd><dt><a href="#CO65-3"><span class="callout">3</span></a> </dt><dd><div class="para"> Set the <code class="literal">--image-tag-base</code> flag to provide the base of the image name, such as <code class="literal">quay.io/example/etcd</code>, that will be used for the bundles. Provide the name without a tag, because the tag for the images will be set according to the bundle version. For example, the full bundle image names are generated in the format <code class="literal">&lt;image_name_base&gt;:&lt;bundle_version&gt;</code>. </div></dd></dl></div></li></ul></div><div class="itemizedlist"><p class="title"><strong>Verification</strong></p><ul class="itemizedlist" type="disc"><li class="listitem"><p class="simpara"> Verify that the generated bundle image runs successfully: </p><pre class="programlisting language-terminal">$ operator-sdk run bundle &lt;bundle_image_name&gt;:&lt;tag&gt;</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal">INFO[0025] Successfully created registry pod: quay-io-my-etcd-0-9-4 INFO[0025] Created CatalogSource: etcd-catalog INFO[0026] OperatorGroup "operator-sdk-og" created INFO[0026] Created Subscription: etcdoperator-v0-9-4-sub INFO[0031] Approved InstallPlan install-5t58z for the Subscription: etcdoperator-v0-9-4-sub INFO[0031] Waiting for ClusterServiceVersion "default/etcdoperator.v0.9.4" to reach 'Succeeded' phase INFO[0032] Waiting for ClusterServiceVersion "default/etcdoperator.v0.9.4" to appear INFO[0048] Found ClusterServiceVersion "default/etcdoperator.v0.9.4" phase: Pending INFO[0049] Found ClusterServiceVersion "default/etcdoperator.v0.9.4" phase: Installing INFO[0064] Found ClusterServiceVersion "default/etcdoperator.v0.9.4" phase: Succeeded INFO[0065] OLM has successfully installed "etcdoperator.v0.9.4"</pre> <p></p></div></li></ul></div></section></section><section class="section" id="osdk-cli-ref"><div class="titlepage"><div><div><h2 class="title">5.13. Operator SDK CLI reference</h2></div></div></div><p> The Operator SDK command-line interface (CLI) is a development kit designed to make writing Operators easier. </p><div class="formalpara"><p class="title"><strong>Operator SDK CLI syntax</strong></p><p> </p><pre class="programlisting language-terminal">$ operator-sdk &lt;command&gt; [&lt;subcommand&gt;] [&lt;argument&gt;] [&lt;flags&gt;]</pre> <p></p></div><p> Operator authors with cluster administrator access to a Kubernetes-based cluster (such as OpenShift Container Platform) can use the Operator SDK CLI to develop their own Operators based on Go, Ansible, or Helm. <a class="link" href="https://kubebuilder.io/">Kubebuilder</a> is embedded into the Operator SDK as the scaffolding solution for Go-based Operators, which means existing Kubebuilder projects can be used as is with the Operator SDK and continue to work. </p><section class="section" id="osdk-cli-ref-bundle_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.1. bundle</h3></div></div></div><p> The <code class="literal">operator-sdk bundle</code> command manages Operator bundle metadata. </p><section class="section" id="osdk-cli-ref-bundle-validate_osdk-cli-ref"><div class="titlepage"><div><div><h4 class="title">5.13.1.1. validate</h4></div></div></div><p> The <code class="literal">bundle validate</code> subcommand validates an Operator bundle. </p><rh-table id="idm140209534154016"><table class="lt-4-cols lt-7-rows"><caption>Table 5.18. bundle validate flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534148864" scope="col">Flag</th><th align="left" valign="top" id="idm140209534147776" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534148864"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209534147776"> <p> Help output for the <code class="literal">bundle validate</code> subcommand. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534148864"> <p> <code class="literal">--index-builder</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534147776"> <p> Tool to pull and unpack bundle images. Only used when validating a bundle image. Available options are <code class="literal">docker</code>, which is the default, <code class="literal">podman</code>, or <code class="literal">none</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534148864"> <p> <code class="literal">--list-optional</code> </p> </td><td align="left" valign="top" headers="idm140209534147776"> <p> List all optional validators available. When set, no validators are run. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534148864"> <p> <code class="literal">--select-optional</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534147776"> <p> Label selector to select optional validators to run. When run with the <code class="literal">--list-optional</code> flag, lists available optional validators. </p> </td></tr></tbody></table></rh-table></section></section><section class="section" id="osdk-cli-ref-cleanup_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.2. cleanup</h3></div></div></div><p> The <code class="literal">operator-sdk cleanup</code> command destroys and removes resources that were created for an Operator that was deployed with the <code class="literal">run</code> command. </p><rh-table id="idm140209534122816"><table class="lt-4-cols lt-7-rows"><caption>Table 5.19. cleanup flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534117664" scope="col">Flag</th><th align="left" valign="top" id="idm140209534116576" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534117664"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209534116576"> <p> Help output for the <code class="literal">run bundle</code> subcommand. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534117664"> <p> <code class="literal">--kubeconfig</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534116576"> <p> Path to the <code class="literal">kubeconfig</code> file to use for CLI requests. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534117664"> <p> <code class="literal">n</code>, <code class="literal">--namespace</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534116576"> <p> If present, namespace in which to run the CLI request. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534117664"> <p> <code class="literal">--timeout &lt;duration&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209534116576"> <p> Time to wait for the command to complete before failing. The default value is <code class="literal">2m0s</code>. </p> </td></tr></tbody></table></rh-table></section><section class="section" id="osdk-cli-ref-completion_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.3. completion</h3></div></div></div><p> The <code class="literal">operator-sdk completion</code> command generates shell completions to make issuing CLI commands quicker and easier. </p><rh-table id="idm140209534092864"><table class="lt-4-cols lt-7-rows"><caption>Table 5.20. completion subcommands</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534087712" scope="col">Subcommand</th><th align="left" valign="top" id="idm140209534086624" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534087712"> <p> <code class="literal">bash</code> </p> </td><td align="left" valign="top" headers="idm140209534086624"> <p> Generate bash completions. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534087712"> <p> <code class="literal">zsh</code> </p> </td><td align="left" valign="top" headers="idm140209534086624"> <p> Generate zsh completions. </p> </td></tr></tbody></table></rh-table><rh-table id="idm140209534076160"><table class="lt-4-cols lt-7-rows"><caption>Table 5.21. completion flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534071008" scope="col">Flag</th><th align="left" valign="top" id="idm140209534069920" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534071008"> <p> <code class="literal">-h, --help</code> </p> </td><td align="left" valign="top" headers="idm140209534069920"> <p> Usage help output. </p> </td></tr></tbody></table></rh-table><p> For example: </p><pre class="programlisting language-terminal">$ operator-sdk completion bash</pre><div class="formalpara"><p class="title"><strong>Example output</strong></p><p> </p><pre class="programlisting language-terminal"># bash completion for operator-sdk -*- shell-script -*- ... # ex: ts=4 sw=4 et filetype=sh</pre> <p></p></div></section><section class="section" id="osdk-cli-ref-create_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.4. create</h3></div></div></div><p> The <code class="literal">operator-sdk create</code> command is used to create, or <span class="emphasis"><em>scaffold</em></span>, a Kubernetes API. </p><section class="section" id="osdk-cli-ref-create-api_osdk-cli-ref"><div class="titlepage"><div><div><h4 class="title">5.13.4.1. api</h4></div></div></div><p> The <code class="literal">create api</code> subcommand scaffolds a Kubernetes API. The subcommand must be run in a project that was initialized with the <code class="literal">init</code> command. </p><rh-table id="idm140209534053600"><table class="lt-4-cols lt-7-rows"><caption>Table 5.22. create api flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534048448" scope="col">Flag</th><th align="left" valign="top" id="idm140209534047360" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534048448"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209534047360"> <p> Help output for the <code class="literal">run bundle</code> subcommand. </p> </td></tr></tbody></table></rh-table></section></section><section class="section" id="osdk-cli-ref-generate_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.5. generate</h3></div></div></div><p> The <code class="literal">operator-sdk generate</code> command invokes a specific generator to generate code or manifests. </p><section class="section" id="osdk-cli-ref-generate-bundle_osdk-cli-ref"><div class="titlepage"><div><div><h4 class="title">5.13.5.1. bundle</h4></div></div></div><p> The <code class="literal">generate bundle</code> subcommand generates a set of bundle manifests, metadata, and a <code class="literal">bundle.Dockerfile</code> file for your Operator project. </p><rh-alert class="admonition note" state="info"><div class="admonition_header" slot="header">Note</div><div><p> Typically, you run the <code class="literal">generate kustomize manifests</code> subcommand first to generate the input <a class="link" href="https://kustomize.io/">Kustomize</a> bases that are used by the <code class="literal">generate bundle</code> subcommand. However, you can use the <code class="literal">make bundle</code> command in an initialized project to automate running these commands in sequence. </p></div></rh-alert><rh-table id="idm140209534031184"><table class="lt-4-cols lt-7-rows"><caption>Table 5.23. generate bundle flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209534026032" scope="col">Flag</th><th align="left" valign="top" id="idm140209534024944" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--channels</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Comma-separated list of channels to which the bundle belongs. The default value is <code class="literal">alpha</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--crds-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Root directory for <code class="literal">CustomResoureDefinition</code> manifests. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--default-channel</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> The default channel for the bundle. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--deploy-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Root directory for Operator manifests, such as deployments and RBAC. This directory is different from the directory passed to the <code class="literal">--input-dir</code> flag. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Help for <code class="literal">generate bundle</code> </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--input-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Directory from which to read an existing bundle. This directory is the parent of your bundle <code class="literal">manifests</code> directory and is different from the <code class="literal">--deploy-dir</code> directory. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--kustomize-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Directory containing Kustomize bases and a <code class="literal">kustomization.yaml</code> file for bundle manifests. The default path is <code class="literal">config/manifests</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--manifests</code> </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Generate bundle manifests. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--metadata</code> </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Generate bundle metadata and Dockerfile. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--output-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Directory to write the bundle to. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--overwrite</code> </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Overwrite the bundle metadata and Dockerfile if they exist. The default value is <code class="literal">true</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--package</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Package name for the bundle. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">-q</code>, <code class="literal">--quiet</code> </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Run in quiet mode. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--stdout</code> </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Write bundle manifest to standard out. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209534026032"> <p> <code class="literal">--version</code> (string) </p> </td><td align="left" valign="top" headers="idm140209534024944"> <p> Semantic version of the Operator in the generated bundle. Set only when creating a new bundle or upgrading the Operator. </p> </td></tr></tbody></table></rh-table><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-bundle-operator_osdk-working-bundle-images">Bundling an Operator</a> for a full procedure that includes using the <code class="literal">make bundle</code> command to call the <code class="literal">generate bundle</code> subcommand. </li></ul></div></section><section class="section" id="osdk-cli-ref-generate-kustomize_osdk-cli-ref"><div class="titlepage"><div><div><h4 class="title">5.13.5.2. kustomize</h4></div></div></div><p> The <code class="literal">generate kustomize</code> subcommand contains subcommands that generate <a class="link" href="https://kustomize.io/">Kustomize</a> data for the Operator. </p><section class="section" id="osdk-cli-ref-generate-kustomize-manifests_osdk-cli-ref"><div class="titlepage"><div><div><h5 class="title">5.13.5.2.1. manifests</h5></div></div></div><p> The <code class="literal">generate kustomize manifests</code> subcommand generates or regenerates Kustomize bases and a <code class="literal">kustomization.yaml</code> file in the <code class="literal">config/manifests</code> directory, which are used to build bundle manifests by other Operator SDK commands. This command interactively asks for UI metadata, an important component of manifest bases, by default unless a base already exists or you set the <code class="literal">--interactive=false</code> flag. </p><rh-table id="idm140209533943552"><table class="lt-4-cols lt-7-rows"><caption>Table 5.24. generate kustomize manifests flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209533938384" scope="col">Flag</th><th align="left" valign="top" id="idm140209533937296" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209533938384"> <p> <code class="literal">--apis-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533937296"> <p> Root directory for API type definitions. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533938384"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209533937296"> <p> Help for <code class="literal">generate kustomize manifests</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533938384"> <p> <code class="literal">--input-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533937296"> <p> Directory containing existing Kustomize files. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533938384"> <p> <code class="literal">--interactive</code> </p> </td><td align="left" valign="top" headers="idm140209533937296"> <p> When set to <code class="literal">false</code>, if no Kustomize base exists, an interactive command prompt is presented to accept custom metadata. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533938384"> <p> <code class="literal">--output-dir</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533937296"> <p> Directory where to write Kustomize files. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533938384"> <p> <code class="literal">--package</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533937296"> <p> Package name. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533938384"> <p> <code class="literal">-q</code>, <code class="literal">--quiet</code> </p> </td><td align="left" valign="top" headers="idm140209533937296"> <p> Run in quiet mode. </p> </td></tr></tbody></table></rh-table></section></section></section><section class="section" id="osdk-cli-ref-init_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.6. init</h3></div></div></div><p> The <code class="literal">operator-sdk init</code> command initializes an Operator project and generates, or <span class="emphasis"><em>scaffolds</em></span>, a default project directory layout for the given plugin. </p><p> This command writes the following files: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> Boilerplate license file </li><li class="listitem"> <code class="literal">PROJECT</code> file with the domain and repository </li><li class="listitem"> <code class="literal">Makefile</code> to build the project </li><li class="listitem"> <code class="literal">go.mod</code> file with project dependencies </li><li class="listitem"> <code class="literal">kustomization.yaml</code> file for customizing manifests </li><li class="listitem"> Patch file for customizing images for manager manifests </li><li class="listitem"> Patch file for enabling Prometheus metrics </li><li class="listitem"> <code class="literal">main.go</code> file to run </li></ul></div><rh-table id="idm140209533889616"><table class="lt-4-cols lt-7-rows"><caption>Table 5.25. init flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209533884464" scope="col">Flag</th><th align="left" valign="top" id="idm140209533883376" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209533884464"> <p> <code class="literal">--help, -h</code> </p> </td><td align="left" valign="top" headers="idm140209533883376"> <p> Help output for the <code class="literal">init</code> command. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533884464"> <p> <code class="literal">--plugins</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533883376"> <p> Name and optionally version of the plugin to initialize the project with. Available plugins are <code class="literal">ansible.sdk.operatorframework.io/v1</code>, <code class="literal">go.kubebuilder.io/v2</code>, <code class="literal">go.kubebuilder.io/v3</code>, and <code class="literal">helm.sdk.operatorframework.io/v1</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533884464"> <p> <code class="literal">--project-version</code> </p> </td><td align="left" valign="top" headers="idm140209533883376"> <p> Project version. Available values are <code class="literal">2</code> and <code class="literal">3-alpha</code>, which is the default. </p> </td></tr></tbody></table></rh-table></section><section class="section" id="osdk-cli-ref-run_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.7. run</h3></div></div></div><p> The <code class="literal">operator-sdk run</code> command provides options that can launch the Operator in various environments. </p><section class="section" id="osdk-cli-ref-run-bundle_osdk-cli-ref"><div class="titlepage"><div><div><h4 class="title">5.13.7.1. bundle</h4></div></div></div><p> The <code class="literal">run bundle</code> subcommand deploys an Operator in the bundle format with Operator Lifecycle Manager (OLM). </p><rh-table id="idm140209533860368"><table class="lt-4-cols lt-7-rows"><caption>Table 5.26. run bundle flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209533855216" scope="col">Flag</th><th align="left" valign="top" id="idm140209533854128" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209533855216"> <p> <code class="literal">--index-image</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533854128"> <p> Index image in which to inject a bundle. The default image is <code class="literal">quay.io/operator-framework/upstream-opm-builder:latest</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533855216"> <p> <code class="literal">--install-mode &lt;install_mode_value&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209533854128"> <p> Install mode supported by the cluster service version (CSV) of the Operator, for example <code class="literal">AllNamespaces</code> or <code class="literal">SingleNamespace</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533855216"> <p> <code class="literal">--timeout &lt;duration&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209533854128"> <p> Install timeout. The default value is <code class="literal">2m0s</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533855216"> <p> <code class="literal">--kubeconfig</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533854128"> <p> Path to the <code class="literal">kubeconfig</code> file to use for CLI requests. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533855216"> <p> <code class="literal">n</code>, <code class="literal">--namespace</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533854128"> <p> If present, namespace in which to run the CLI request. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533855216"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209533854128"> <p> Help output for the <code class="literal">run bundle</code> subcommand. </p> </td></tr></tbody></table></rh-table><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-operatorgroups-membership_olm-understanding-operatorgroups">Operator group membership</a> for details on possible install modes. </li></ul></div></section><section class="section" id="osdk-cli-ref-run-bundle-upgrade_osdk-cli-ref"><div class="titlepage"><div><div><h4 class="title">5.13.7.2. bundle-upgrade</h4></div></div></div><p> The <code class="literal">run bundle-upgrade</code> subcommand upgrades an Operator that was previously installed in the bundle format with Operator Lifecycle Manager (OLM). </p><rh-table id="idm140209533817264"><table class="lt-4-cols lt-7-rows"><caption>Table 5.27. run bundle-upgrade flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209533812112" scope="col">Flag</th><th align="left" valign="top" id="idm140209533811024" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209533812112"> <p> <code class="literal">--timeout &lt;duration&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209533811024"> <p> Upgrade timeout. The default value is <code class="literal">2m0s</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533812112"> <p> <code class="literal">--kubeconfig</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533811024"> <p> Path to the <code class="literal">kubeconfig</code> file to use for CLI requests. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533812112"> <p> <code class="literal">n</code>, <code class="literal">--namespace</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533811024"> <p> If present, namespace in which to run the CLI request. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533812112"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209533811024"> <p> Help output for the <code class="literal">run bundle</code> subcommand. </p> </td></tr></tbody></table></rh-table></section></section><section class="section" id="osdk-cli-ref-scorecard_osdk-cli-ref"><div class="titlepage"><div><div><h3 class="title">5.13.8. scorecard</h3></div></div></div><p> The <code class="literal">operator-sdk scorecard</code> command runs the scorecard tool to validate an Operator bundle and provide suggestions for improvements. The command takes one argument, either a bundle image or directory containing manifests and metadata. If the argument holds an image tag, the image must be present remotely. </p><rh-table id="idm140209533787008"><table class="lt-4-cols lt-7-rows"><caption>Table 5.28. scorecard flags</caption><colgroup><col style="width: 25%; " class="col_1"><!--Empty--><col style="width: 75%; " class="col_2"><!--Empty--></colgroup><thead><tr><th align="left" valign="top" id="idm140209533781856" scope="col">Flag</th><th align="left" valign="top" id="idm140209533780768" scope="col">Description</th></tr></thead><tbody><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-c</code>, <code class="literal">--config</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Path to scorecard configuration file. The default path is <code class="literal">bundle/tests/scorecard/config.yaml</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-h</code>, <code class="literal">--help</code> </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Help output for the <code class="literal">scorecard</code> command. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">--kubeconfig</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Path to <code class="literal">kubeconfig</code> file. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-L</code>, <code class="literal">--list</code> </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> List which tests are available to run. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-n</code>, --namespace (string) </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Namespace in which to run the test images. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-o</code>, <code class="literal">--output</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Output format for results. Available values are <code class="literal">text</code>, which is the default, and <code class="literal">json</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-l</code>, <code class="literal">--selector</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Label selector to determine which tests are run. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-s</code>, <code class="literal">--service-account</code> (string) </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Service account to use for tests. The default value is <code class="literal">default</code>. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-x</code>, <code class="literal">--skip-cleanup</code> </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Disable resource cleanup after tests are run. </p> </td></tr><tr><td align="left" valign="top" headers="idm140209533781856"> <p> <code class="literal">-w</code>, <code class="literal">--wait-time &lt;duration&gt;</code> </p> </td><td align="left" valign="top" headers="idm140209533780768"> <p> Seconds to wait for tests to complete, for example <code class="literal">35s</code>. The default value is <code class="literal">30s</code>. </p> </td></tr></tbody></table></rh-table><div class="itemizedlist _additional-resources"><p class="title"><strong>Additional resources</strong></p><ul class="itemizedlist _additional-resources" type="disc"><li class="listitem"> See <a class="link" href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-scorecard">Validating Operators using the scorecard tool</a> for details about running the scorecard tool. </li></ul></div></section></section></section></body></section><nav class="pagination" aria-label="pagination" data-v-8589d091 data-v-a6039582><rh-cta aria-disabled="false" class="previous-btn" variant="brick" data-v-a6039582><a href="/en/documentation/openshift_container_platform/4.8/html/operators/administrator-tasks" data-v-a6039582>Previous</a></rh-cta><rh-cta aria-disabled="false" class="next-btn" variant="brick" data-v-a6039582><a href="/en/documentation/openshift_container_platform/4.8/html/operators/cluster-operators-ref" data-v-a6039582>Next</a></rh-cta></nav></div></article><aside id="layout" class="span-xs-12 span-sm-2 span-md-2 content-format-selectors" aria-label="Select page format" data-v-8589d091><div class="page-layout-options" data-v-8589d091><label for="page-format" data-v-8589d091>Format</label><select id="page-format" class="page-format-dropdown" data-v-8589d091><option selected class="page-type" value="html" data-v-8589d091>Multi-page</option><option class="page-type" value="html-single" data-v-8589d091>Single-page</option><option class="page-type" value="pdf" data-v-8589d091>View full doc as PDF</option></select></div><details open id="jump-links-details" class="sticky-top" data-v-8589d091><summary class="jump-links-heading" data-v-8589d091>Jump to section</summary><nav class="jump-links" id="right-navigation-links" data-v-8589d091 data-v-1d1b84c1><ul data-v-1d1b84c1><!--[--><li class="active_link jump-link-item" data-v-1d1b84c1><a href="#osdk-about" id="right-sub-link-to-osdk-about" data-v-1d1b84c1>About the Operator SDK</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-installing-cli" id="right-sub-link-to-osdk-installing-cli" data-v-1d1b84c1>Installing the Operator SDK CLI</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-upgrading-projects" id="right-sub-link-to-osdk-upgrading-projects" data-v-1d1b84c1>Upgrading projects for newer Operator SDK versions</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#go-based-operators" id="right-sub-link-to-go-based-operators" data-v-1d1b84c1>Go-based Operators</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#ansible-based-operators" id="right-sub-link-to-ansible-based-operators" data-v-1d1b84c1>Ansible-based Operators</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#helm-based-operators" id="right-sub-link-to-helm-based-operators" data-v-1d1b84c1>Helm-based Operators</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-generating-csvs" id="right-sub-link-to-osdk-generating-csvs" data-v-1d1b84c1>Defining cluster service versions (CSVs)</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-working-bundle-images" id="right-sub-link-to-osdk-working-bundle-images" data-v-1d1b84c1>Working with bundle images</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-scorecard" id="right-sub-link-to-osdk-scorecard" data-v-1d1b84c1>Validating Operators using the scorecard tool</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-monitoring-prometheus" id="right-sub-link-to-osdk-monitoring-prometheus" data-v-1d1b84c1>Configuring built-in monitoring with Prometheus</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-leader-election" id="right-sub-link-to-osdk-leader-election" data-v-1d1b84c1>Configuring leader election</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-pkgman-to-bundle" id="right-sub-link-to-osdk-pkgman-to-bundle" data-v-1d1b84c1>Migrating package manifest projects to bundle format</a></li><li class="jump-link-item" data-v-1d1b84c1><a href="#osdk-cli-ref" id="right-sub-link-to-osdk-cli-ref" data-v-1d1b84c1>Operator SDK CLI reference</a></li><!--]--></ul></nav></details></aside></div><div class="btn-container hidden" data-v-8589d091><pf-button class="top-scroll-btn" icon="angle-up" icon-set="fas" icon-position="right" data-v-8589d091>Back to top</pf-button></div><!--]--><!--]--></main><rh-footer data-analytics-region="page-footer" data-v-97dd2752><a slot="logo" href="/en" data-analytics-category="Footer" data-analytics-text="Logo" data-v-97dd2752><img alt="Red Hat logo" src="/Logo-Red_Hat-Documentation-A-Reverse-RGB.svg" loading="lazy" width="222" height="40" data-v-97dd2752></a><rh-footer-social-link slot="social-links" icon="github" data-v-97dd2752><a href="https://github.com/redhat-documentation" data-analytics-region="social-links-exit" data-analytics-category="Footer|social-links" data-analytics-text="LinkedIn" data-v-97dd2752>Github</a></rh-footer-social-link><rh-footer-social-link slot="social-links" icon="reddit" data-v-97dd2752><a href="https://www.reddit.com/r/redhat/" data-analytics-region="social-links-exit" data-analytics-category="Footer|social-links" data-analytics-text="YouTube" data-v-97dd2752>Reddit</a></rh-footer-social-link><rh-footer-social-link slot="social-links" icon="youtube" data-v-97dd2752><a href="https://www.youtube.com/@redhat" data-analytics-region="social-links-exit" data-analytics-category="Footer|social-links" data-analytics-text="Facebook" data-v-97dd2752>Youtube</a></rh-footer-social-link><rh-footer-social-link slot="social-links" icon="twitter" data-v-97dd2752><a href="https://twitter.com/RedHat" data-analytics-region="social-links-exit" data-analytics-category="Footer|social-links" data-analytics-text="Twitter" data-v-97dd2752>Twitter</a></rh-footer-social-link><h3 slot="links" data-analytics-text="Learn" data-v-97dd2752>Learn</h3><ul slot="links" data-v-97dd2752><li data-v-97dd2752><a href="https://developers.redhat.com/learn" data-analytics-category="Footer|Learn" data-analytics-text="Developer resources" data-v-97dd2752>Developer resources</a></li><li data-v-97dd2752><a href="https://cloud.redhat.com/learn" data-analytics-category="Footer|Learn" data-analytics-text="Cloud learning hub" data-v-97dd2752>Cloud learning hub</a></li><li data-v-97dd2752><a href="https://www.redhat.com/en/interactive-labs" data-analytics-category="Footer|Learn" data-analytics-text="Interactive labs" data-v-97dd2752>Interactive labs</a></li><li data-v-97dd2752><a href="https://www.redhat.com/services/training-and-certification" data-analytics-category="Footer|Learn" data-analytics-text="Training and certification" data-v-97dd2752>Training and certification</a></li><li data-v-97dd2752><a href="https://access.redhat.com/support" data-analytics-category="Footer|Learn" data-analytics-text="Customer support" data-v-97dd2752>Customer support</a></li><li data-v-97dd2752><a href="/products" data-analytics-category="Footer|Learn" data-analytics-text="See all documentation" data-v-97dd2752>See all documentation</a></li></ul><h3 slot="links" data-analytics-text="Try buy sell" data-v-97dd2752>Try, buy, &amp; sell</h3><ul slot="links" data-v-97dd2752><li data-v-97dd2752><a href="https://redhat.com/en/products/trials" data-analytics-category="Footer|Try buy sell" data-analytics-text="Product trial center" data-v-97dd2752>Product trial center</a></li><li data-v-97dd2752><a href="https://marketplace.redhat.com" data-analytics-category="Footer|Try buy sell" data-analytics-text="Red Hat Marketplace" data-v-97dd2752>Red Hat Marketplace</a></li><li data-v-97dd2752><a href="https://catalog.redhat.com/" data-analytics-category="Footer|Try buy sell" data-analytics-text="Red Hat Ecosystem Catalog" data-v-97dd2752>Red Hat Ecosystem Catalog</a></li><li data-v-97dd2752><a href="https://www.redhat.com/en/store" data-analytics-category="Footer|Try buy sell" data-analytics-text="Red Hat Store" data-v-97dd2752>Red Hat Store</a></li><li data-v-97dd2752><a href="https://www.redhat.com/about/japan-buy" data-analytics-category="Footer|Try buy sell" data-analytics-text="Buy online (Japan)" data-v-97dd2752>Buy online (Japan)</a></li></ul><h3 slot="links" data-analytics-text="Communities" data-v-97dd2752>Communities</h3><ul slot="links" data-v-97dd2752><li data-v-97dd2752><a href="https://access.redhat.com/community" data-analytics-category="Footer|Communities" data-analytics-text="Customer Portal Community" data-v-97dd2752>Customer Portal Community</a></li><li data-v-97dd2752><a href="https://www.redhat.com/events" data-analytics-category="Footer|Communities" data-analytics-text="Events" data-v-97dd2752>Events</a></li><li data-v-97dd2752><a href="https://www.redhat.com/about/our-community-contributions" data-analytics-category="Footer|Communities" data-analytics-text="How we contribute" data-v-97dd2752>How we contribute</a></li></ul><rh-footer-block slot="main-secondary" data-v-97dd2752><h3 slot="header" data-analytics-text="About Red Hat Documentation" data-v-97dd2752>About Red Hat Documentation</h3><p data-v-97dd2752>We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.</p></rh-footer-block><rh-footer-block slot="main-secondary" data-v-97dd2752><h3 slot="header" data-analytics-text="Making open source more inclusive" data-v-97dd2752>Making open source more inclusive</h3><p data-v-97dd2752>Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the <a href=" https://www.redhat.com/en/blog/making-open-source-more-inclusive-eradicating-problematic-language" data-analytics-category="Footer|Making open source more inclusive" data-analytics-text="Red Hat Blog" data-v-97dd2752>Red Hat Blog</a>.</p></rh-footer-block><rh-footer-block slot="main-secondary" data-v-97dd2752><h3 slot="header" data-analytics-text="About Red Hat" data-v-97dd2752>About Red Hat</h3><p data-v-97dd2752>We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.</p></rh-footer-block><rh-footer-universal slot="universal" data-v-97dd2752><h3 slot="links-primary" data-analytics-text="Red Hat legal and privacy links" hidden data-v-97dd2752>Red Hat legal and privacy links</h3><ul slot="links-primary" data-analytics-region="page-footer-bottom-primary" data-v-97dd2752><li data-v-97dd2752><a href="https://redhat.com/en/about/company" data-analytics-category="Footer|Corporate" data-analytics-text="About Red Hat" data-v-97dd2752>About Red Hat</a></li><li data-v-97dd2752><a href="https://redhat.com/en/jobs" data-analytics-category="Footer|Corporate" data-analytics-text="Jobs" data-v-97dd2752>Jobs</a></li><li data-v-97dd2752><a href="https://redhat.com/en/events" data-analytics-category="Footer|Corporate" data-analytics-text="Events" data-v-97dd2752>Events</a></li><li data-v-97dd2752><a href="https://redhat.com/en/about/office-locations" data-analytics-category="Footer|Corporate" data-analytics-text="Locations" data-v-97dd2752>Locations</a></li><li data-v-97dd2752><a href="https://redhat.com/en/contact" data-analytics-category="Footer|Corporate" data-analytics-text="Contact Red Hat" data-v-97dd2752>Contact Red Hat</a></li><li data-v-97dd2752><a href="https://redhat.com/en/blog" data-analytics-category="Footer|Corporate" data-analytics-text="Red Hat Blog" data-v-97dd2752>Red Hat Blog</a></li><li data-v-97dd2752><a href="https://redhat.com/en/about/our-culture/diversity-equity-inclusion" data-analytics-category="Footer|Corporate" data-analytics-text="Diversity equity and inclusion" data-v-97dd2752>Diversity, equity, and inclusion</a></li><li data-v-97dd2752><a href="https://coolstuff.redhat.com/" data-analytics-category="Footer|Corporate" data-analytics-text="Cool Stuff Store" data-v-97dd2752>Cool Stuff Store</a></li><li data-v-97dd2752><a href="https://www.redhat.com/en/summit" data-analytics-category="Footer|Corporate" data-analytics-text="Red Hat Summit" data-v-97dd2752>Red Hat Summit</a></li></ul><span data-v-97dd2752 data-v-5f538988></span><rh-footer-copyright slot="links-secondary" data-v-97dd2752>© 2024 Red Hat, Inc.</rh-footer-copyright><h3 slot="links-secondary" data-analytics-text="Red Hat legal and privacy links" hidden data-v-97dd2752>Red Hat legal and privacy links</h3><ul slot="links-secondary" data-analytics-region="page-footer-bottom-secondary" data-v-97dd2752><li data-v-97dd2752><a href="https://redhat.com/en/about/privacy-policy" data-analytics-category="Footer|Red Hat legal and privacy links" data-analytics-text="Privacy statement" data-v-97dd2752>Privacy statement</a></li><li data-v-97dd2752><a href="https://redhat.com/en/about/terms-use" data-analytics-category="Footer|Red Hat legal and privacy links" data-analytics-text="Terms of use" data-v-97dd2752>Terms of use</a></li><li data-v-97dd2752><a href="https://redhat.com/en/about/all-policies-guidelines" data-analytics-category="Footer|Red Hat legal and privacy links" data-analytics-text="All policies and guidelines" data-v-97dd2752>All policies and guidelines</a></li><li data-v-97dd2752><a href="https://redhat.com/en/about/digital-accessibility" data-analytics-category="Footer|Red Hat legal and privacy links" data-analytics-text="Digital accessibility" class="active" data-v-97dd2752>Digital accessibility</a></li><li data-v-97dd2752><span id="teconsent" data-v-97dd2752></span></li></ul></rh-footer-universal></rh-footer><div id="consent_blackbar" style="position:fixed;bottom:0;width:100%;z-index:5;padding:10px;"></div><!--]--><!--]--></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="true">[["ShallowReactive",1],{"data":2,"state":11872,"once":11876,"_errors":11877,"serverRendered":17,"path":11879},["ShallowReactive",3],{"s8LoCEfG4A":4,"rFVLKcOK8e":9,"uUstF4AIyn":11,"Pn02PlJOas":11802},[5,6,7,8],"en-us","ko-kr","zh-cn","ja-jp",{"product":10},"Red Hat OpenShift Container Platform",{"name":12,"html":13,"type":-1,"toc":14,"breadcrumbs":11235,"error":23,"title":11246,"productName":11237,"productVersions":11282,"pagination":11369,"redirect":11737,"canonicalLinks":11738,"openShiftProducts":11747,"tocFromVolume":17,"jumpLinks":11762},"Chapter 5. Developing Operators","\u003Cbody>\u003Csection class=\"chapter\" id=\"developing-operators\">\u003Csection class=\"section\" id=\"osdk-about\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.1. About the Operator SDK\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tThe \u003Ca class=\"link\" href=\"https://operatorframework.io/\">Operator Framework\u003C/a> is an open source toolkit to manage Kubernetes native applications, called \u003Cspan class=\"emphasis\">\u003Cem>Operators\u003C/em>\u003C/span>, in an effective, automated, and scalable way. Operators take advantage of Kubernetes extensibility to deliver the automation advantages of cloud services, like provisioning, scaling, and backup and restore, while being able to run anywhere that Kubernetes can run.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tOperators make it easy to manage complex, stateful applications on top of Kubernetes. However, writing an Operator today can be difficult because of challenges such as using low-level APIs, writing boilerplate, and a lack of modularity, which leads to duplication.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tThe Operator SDK, a component of the Operator Framework, provides a command-line interface (CLI) tool that Operator developers can use to build, test, and deploy an Operator.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Why use the Operator SDK?\u003C/strong>\u003C/span>\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tThe Operator SDK simplifies this process of building Kubernetes-native applications, which can require deep, application-specific operational knowledge. The Operator SDK not only lowers that barrier, but it also helps reduce the amount of boilerplate code required for many common management capabilities, such as metering or monitoring.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tThe Operator SDK is a framework that uses the \u003Ca class=\"link\" href=\"https://github.com/kubernetes-sigs/controller-runtime\">controller-runtime\u003C/a> library to make writing Operators easier by providing the following features:\n\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\tHigh-level APIs and abstractions to write the operational logic more intuitively\n\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\tTools for scaffolding and code generation to quickly bootstrap a new project\n\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\tIntegration with Operator Lifecycle Manager (OLM) to streamline packaging, installing, and running Operators on a cluster\n\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\tExtensions to cover common Operator use cases\n\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\tMetrics set up automatically in any generated Go-based Operator for use on clusters where the Prometheus Operator is deployed\n\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\tOperator authors with cluster administrator access to a Kubernetes-based cluster (such as OpenShift Container Platform) can use the Operator SDK CLI to develop their own Operators based on Go, Ansible, or Helm. \u003Ca class=\"link\" href=\"https://kubebuilder.io/\">Kubebuilder\u003C/a> is embedded into the Operator SDK as the scaffolding solution for Go-based Operators, which means existing Kubebuilder projects can be used as is with the Operator SDK and continue to work.\n\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\tOpenShift Container Platform 4.8 supports Operator SDK v1.8.0 or later.\n\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Csection class=\"section\" id=\"osdk-about-what-are-operators\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.1.1. What are Operators?\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tFor an overview about basic Operator concepts and terminology, see \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-what-operators-are\">Understanding Operators\u003C/a>.\n\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-workflow_osdk-about\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.1.2. Development workflow\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe Operator SDK provides the following workflow to develop a new Operator:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tCreate an Operator project by using the Operator SDK command-line interface (CLI).\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tDefine new resource APIs by adding custom resource definitions (CRDs).\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSpecify resources to watch by using the Operator SDK API.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tDefine the Operator reconciling logic in a designated handler and use the Operator SDK API to interact with resources.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tUse the Operator SDK CLI to build and generate the Operator deployment manifests.\n\t\t\t\t\t\t\u003C/li>\u003C/ol>\u003C/div>\u003Cdiv class=\"figure\" id=\"idm140209515070576\">\u003Cp class=\"title\">\u003Cstrong>Figure 5.1. Operator SDK workflow\u003C/strong>\u003C/p>\u003Cdiv class=\"figure-contents\">\u003Cdiv class=\"mediaobject\">\u003Cimg src=\"https://access.redhat.com/webassets/avalon/d/OpenShift_Container_Platform-4.8-Operators-en-US/images/455883d59723ffcc9b05b9a4d4d0503c/osdk-workflow.png\" alt=\"osdk workflow\"/>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tAt a high level, an Operator that uses the Operator SDK processes events for watched resources in an Operator author-defined handler and takes actions to reconcile the state of the application.\n\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section _additional-resources\" id=\"osdk-about-addtl-resources\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.1.3. Additional resources\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://redhat-connect.gitbook.io/certified-operator-guide/\">Certified Operator Build Guide\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-installing-cli\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.2. Installing the Operator SDK CLI\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tThe Operator SDK provides a command-line interface (CLI) tool that Operator developers can use to build, test, and deploy an Operator. You can install the Operator SDK CLI on your workstation so that you are prepared to start authoring your own Operators.\n\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\tOpenShift Container Platform 4.8 supports Operator SDK v1.8.0.\n\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Csection class=\"section\" id=\"osdk-installing-cli-linux-macos_osdk-installing-cli\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.2.1. Installing the Operator SDK CLI\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tYou can install the OpenShift SDK CLI tool on Linux.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://golang.org/dl/\">Go\u003C/a> v1.16+\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">docker\u003C/code> v17.03+, \u003Ccode class=\"literal\">podman\u003C/code> v1.9.3+, or \u003Ccode class=\"literal\">buildah\u003C/code> v1.7+\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tNavigate to the \u003Ca class=\"link\" href=\"https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/operator-sdk/4.8.4/\">OpenShift mirror site\u003C/a>.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tFrom the \u003Ccode class=\"literal\">4.8.4\u003C/code> directory, download the latest version of the tarball for Linux.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tUnpack the archive:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ tar xvf operator-sdk-v1.8.0-ocp-linux-x86_64.tar.gz\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMake the file executable:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ chmod +x operator-sdk\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMove the extracted \u003Ccode class=\"literal\">operator-sdk\u003C/code> binary to a directory that is on your \u003Ccode class=\"literal\">PATH\u003C/code>.\n\t\t\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition tip\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Tip\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\tTo check your \u003Ccode class=\"literal\">PATH\u003C/code>:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ echo $PATH\u003C/pre>\u003C/div>\u003C/rh-alert>\u003Cpre class=\"programlisting language-terminal\">$ sudo mv ./operator-sdk /usr/local/bin/operator-sdk\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Verification\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tAfter you install the Operator SDK CLI, verify that it is available:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk version\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">operator-sdk version: \"v1.8.0-ocp\", ...\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-upgrading-projects\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.3. Upgrading projects for newer Operator SDK versions\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tOpenShift Container Platform 4.8 supports Operator SDK v1.8.0. If you already have the v1.3.0 CLI installed on your workstation, you can upgrade the CLI to v1.8.0 by \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli\">installing the latest version\u003C/a>.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tHowever, to ensure your existing Operator projects maintain compatibility with Operator SDK v1.8.0, upgrade steps are required for the associated breaking changes introduced since v1.3.0. You must perform the upgrade steps manually in any of your Operator projects that were previously created or maintained with v1.3.0.\n\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-upgrading-v130-to-v180_osdk-upgrading-projects\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.3.1. Upgrading projects for Operator SDK v1.8.0\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe following upgrade steps must be performed to upgrade an existing Operator project for compatibility with v1.8.0.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator SDK v1.8.0 installed\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator project that was previously created or maintained with Operator SDK v1.3.0\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMake the following changes to your \u003Ccode class=\"literal\">PROJECT\u003C/code> file:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">PROJECT\u003C/code> file \u003Ccode class=\"literal\">plugins\u003C/code> object to use \u003Ccode class=\"literal\">manifests\u003C/code> and \u003Ccode class=\"literal\">scorecard\u003C/code> objects.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">manifests\u003C/code> and \u003Ccode class=\"literal\">scorecard\u003C/code> plug-ins that create Operator Lifecycle Manager (OLM) and scorecard manifests now have plug-in objects for running \u003Ccode class=\"literal\">create\u003C/code> subcommands to create related files.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tFor Go-based Operator projects, an existing Go-based plug-in configuration object is already present. While the old configuration is still supported, these new objects will be useful in the future as configuration options are added to their respective plug-ins:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Old configuration\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">version: 3-alpha\n...\nplugins:\n go.sdk.operatorframework.io/v2-alpha: {}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>New configuration\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">version: 3-alpha\n...\nplugins:\n manifests.sdk.operatorframework.io/v2: {}\n scorecard.sdk.operatorframework.io/v2: {}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tOptional: For Ansible- and Helm-based Operator projects, the plug-in configuration object previously did not exist. While you are not required to add the plug-in configuration objects, these new objects will be useful in the future as configuration options are added to their respective plug-ins:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">version: 3-alpha\n...\nplugins:\n manifests.sdk.operatorframework.io/v2: {}\n scorecard.sdk.operatorframework.io/v2: {}\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">PROJECT\u003C/code> config version \u003Ccode class=\"literal\">3-alpha\u003C/code> must be upgraded to \u003Ccode class=\"literal\">3\u003C/code>. The \u003Ccode class=\"literal\">version\u003C/code> key in your \u003Ccode class=\"literal\">PROJECT\u003C/code> file represents the \u003Ccode class=\"literal\">PROJECT\u003C/code> config version:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Old \u003Ccode class=\"literal\">PROJECT\u003C/code> file\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">version: 3-alpha\nresources:\n- crdVersion: v1\n...\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tVersion \u003Ccode class=\"literal\">3-alpha\u003C/code> has been stabilized as \u003Ca class=\"link\" href=\"https://book.kubebuilder.io/migration/v2vsv3.html\">version 3\u003C/a> and contains a set of config fields sufficient to fully describe a project. While this change is not technically breaking because the spec at that version was alpha, it was used by default in \u003Ccode class=\"literal\">operator-sdk\u003C/code> commands, so it should be marked as breaking and have a convenient upgrade path.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"i\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">alpha config-3alpha-to-3\u003C/code> command to convert most of your \u003Ccode class=\"literal\">PROJECT\u003C/code> file from version \u003Ccode class=\"literal\">3-alpha\u003C/code> to \u003Ccode class=\"literal\">3\u003C/code>:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk alpha config-3alpha-to-3\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">Your PROJECT config file has been converted from version 3-alpha to 3. Please make sure all config data is correct.\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tThe command will also output comments with directions where automatic conversion is not possible.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tVerify the change:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>New \u003Ccode class=\"literal\">PROJECT\u003C/code> file\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">version: \"3\"\nresources:\n- api:\n crdVersion: v1\n...\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMake the following changes to your \u003Ccode class=\"literal\">config/manager/manager.yaml\u003C/code> file:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Ansible- and Helm-based Operator projects, add liveness and readiness probes.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tNew projects built with the Operator SDK have the probes configured by default. The endpoints \u003Ccode class=\"literal\">/healthz\u003C/code> and \u003Ccode class=\"literal\">/readyz\u003C/code> are available now in the provided image base. You can update your existing projects to use the probes by updating the \u003Ccode class=\"literal\">Dockerfile\u003C/code> to use the latest base image, then add the following to the \u003Ccode class=\"literal\">manager\u003C/code> container in the \u003Ccode class=\"literal\">config/manager/manager.yaml\u003C/code> file:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488226944\">\u003Cp class=\"title\">\u003Cstrong>Example 5.1. Configuration for Ansible-based Operator projects\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\"> livenessProbe:\n httpGet:\n path: /healthz\n port: 6789\n initialDelaySeconds: 15\n periodSeconds: 20\n readinessProbe:\n httpGet:\n path: /readyz\n port: 6789\n initialDelaySeconds: 5\n periodSeconds: 10\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209488224640\">\u003Cp class=\"title\">\u003Cstrong>Example 5.2. Configuration for Helm-based Operator projects\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\"> livenessProbe:\n httpGet:\n path: /healthz\n port: 8081\n initialDelaySeconds: 15\n periodSeconds: 20\n readinessProbe:\n httpGet:\n path: /readyz\n port: 8081\n initialDelaySeconds: 5\n periodSeconds: 10\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Ansible- and Helm-based Operator projects, add security contexts to your manager’s deployment.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tIn the \u003Ccode class=\"literal\">config/manager/manager.yaml\u003C/code> file, add the following security contexts:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488220144\">\u003Cp class=\"title\">\u003Cstrong>Example 5.3. \u003Ccode class=\"literal\">config/manager/manager.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">spec:\n ...\n template:\n ...\n spec:\n securityContext:\n runAsNonRoot: true\n containers:\n - name: manager\n securityContext:\n allowPrivilegeEscalation: false\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMake the following changes to your \u003Ccode class=\"literal\">Makefile\u003C/code>:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Ansible- and Helm-based Operator projects, update the \u003Ccode class=\"literal\">helm-operator\u003C/code> and \u003Ccode class=\"literal\">ansible-operator\u003C/code> URLs in the \u003Ccode class=\"literal\">Makefile\u003C/code>:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tFor Ansible-based Operator projects, change:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/ansible-operator-v1.3.0-$(ARCHOPER)-$(OSOPER)\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tto:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/ansible-operator_$(OS)_$(ARCH)\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tFor Helm-based Operator projects, change:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/helm-operator-v1.3.0-$(ARCHOPER)-$(OSOPER)\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tto:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/helm-operator_$(OS)_$(ARCH)\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Ansible- and Helm-based Operator projects, update the \u003Ccode class=\"literal\">helm-operator\u003C/code>, \u003Ccode class=\"literal\">ansible-operator\u003C/code>, and \u003Ccode class=\"literal\">kustomize\u003C/code> rules in the \u003Ccode class=\"literal\">Makefile\u003C/code>. These rules download a local binary but do not use it if a global binary is present:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488201648\">\u003Cp class=\"title\">\u003Cstrong>Example 5.4. \u003Ccode class=\"literal\">Makefile\u003C/code> diff for Ansible-based Operator projects\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\"> PATH := $(PATH):$(PWD)/bin\n SHELL := env PATH=$(PATH) /bin/sh\n-OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')\n-ARCH := $(shell uname -m | sed 's/x86_64/amd64/')\n+OS = $(shell uname -s | tr '[:upper:]' '[:lower:]')\n+ARCH = $(shell uname -m | sed 's/x86_64/amd64/')\n+OSOPER = $(shell uname -s | tr '[:upper:]' '[:lower:]' | sed 's/darwin/apple-darwin/' | sed 's/linux/linux-gnu/')\n+ARCHOPER = $(shell uname -m )\n\n-# Download kustomize locally if necessary, preferring the $(pwd)/bin path over global if both exist.\n-.PHONY: kustomize\n-KUSTOMIZE = $(shell pwd)/bin/kustomize\n kustomize:\n-ifeq (,$(wildcard $(KUSTOMIZE)))\n-ifeq (,$(shell which kustomize 2&gt;/dev/null))\n+ifeq (, $(shell which kustomize 2&gt;/dev/null))\n \t@{ \\\n \tset -e ;\\\n-\tmkdir -p $(dir $(KUSTOMIZE)) ;\\\n-\tcurl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | \\\n-\ttar xzf - -C bin/ ;\\\n+\tmkdir -p bin ;\\\n+\tcurl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | tar xzf - -C bin/ ;\\\n \t}\n+KUSTOMIZE=$(realpath ./bin/kustomize)\n else\n-KUSTOMIZE = $(shell which kustomize)\n-endif\n+KUSTOMIZE=$(shell which kustomize)\n endif\n\n-# Download ansible-operator locally if necessary, preferring the $(pwd)/bin path over global if both exist.\n-.PHONY: ansible-operator\n-ANSIBLE_OPERATOR = $(shell pwd)/bin/ansible-operator\n ansible-operator:\n-ifeq (,$(wildcard $(ANSIBLE_OPERATOR)))\n-ifeq (,$(shell which ansible-operator 2&gt;/dev/null))\n+ifeq (, $(shell which ansible-operator 2&gt;/dev/null))\n \t@{ \\\n \tset -e ;\\\n-\tmkdir -p $(dir $(ANSIBLE_OPERATOR)) ;\\\n-\tcurl -sSLo $(ANSIBLE_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/ansible-operator_$(OS)_$(ARCH) ;\\\n-\tchmod +x $(ANSIBLE_OPERATOR) ;\\\n+\tmkdir -p bin ;\\\n+\tcurl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/ansible-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ;\\\n+\tmv ansible-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ./bin/ansible-operator ;\\\n+\tchmod +x ./bin/ansible-operator ;\\\n \t}\n+ANSIBLE_OPERATOR=$(realpath ./bin/ansible-operator)\n else\n-ANSIBLE_OPERATOR = $(shell which ansible-operator)\n-endif\n+ANSIBLE_OPERATOR=$(shell which ansible-operator)\n endif\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209488194944\">\u003Cp class=\"title\">\u003Cstrong>Example 5.5. \u003Ccode class=\"literal\">Makefile\u003C/code> diff for Helm-based Operator projects\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\"> PATH := $(PATH):$(PWD)/bin\n SHELL := env PATH=$(PATH) /bin/sh\n-OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')\n-ARCH := $(shell uname -m | sed 's/x86_64/amd64/')\n+OS = $(shell uname -s | tr '[:upper:]' '[:lower:]')\n+ARCH = $(shell uname -m | sed 's/x86_64/amd64/')\n+OSOPER = $(shell uname -s | tr '[:upper:]' '[:lower:]' | sed 's/darwin/apple-darwin/' | sed 's/linux/linux-gnu/')\n+ARCHOPER = $(shell uname -m )\n\n-# Download kustomize locally if necessary, preferring the $(pwd)/bin path over global if both exist.\n-.PHONY: kustomize\n-KUSTOMIZE = $(shell pwd)/bin/kustomize\n kustomize:\n-ifeq (,$(wildcard $(KUSTOMIZE)))\n-ifeq (,$(shell which kustomize 2&gt;/dev/null))\n+ifeq (, $(shell which kustomize 2&gt;/dev/null))\n \t@{ \\\n \tset -e ;\\\n-\tmkdir -p $(dir $(KUSTOMIZE)) ;\\\n-\tcurl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | \\\n-\ttar xzf - -C bin/ ;\\\n+\tmkdir -p bin ;\\\n+\tcurl -sSLo - https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.5.4/kustomize_v3.5.4_$(OS)_$(ARCH).tar.gz | tar xzf - -C bin/ ;\\\n \t}\n+KUSTOMIZE=$(realpath ./bin/kustomize)\n else\n-KUSTOMIZE = $(shell which kustomize)\n-endif\n+KUSTOMIZE=$(shell which kustomize)\n endif\n\n-# Download helm-operator locally if necessary, preferring the $(pwd)/bin path over global if both exist.\n-.PHONY: helm-operator\n-HELM_OPERATOR = $(shell pwd)/bin/helm-operator\n helm-operator:\n-ifeq (,$(wildcard $(HELM_OPERATOR)))\n-ifeq (,$(shell which helm-operator 2&gt;/dev/null))\n+ifeq (, $(shell which helm-operator 2&gt;/dev/null))\n \t@{ \\\n \tset -e ;\\\n-\tmkdir -p $(dir $(HELM_OPERATOR)) ;\\\n-\tcurl -sSLo $(HELM_OPERATOR) https://github.com/operator-framework/operator-sdk/releases/download/v1.3.0/helm-operator_$(OS)_$(ARCH) ;\\\n-\tchmod +x $(HELM_OPERATOR) ;\\\n+\tmkdir -p bin ;\\\n+\tcurl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.8.0/helm-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ;\\\n+\tmv helm-operator-v1.8.0-$(ARCHOPER)-$(OSOPER) ./bin/helm-operator ;\\\n+\tchmod +x ./bin/helm-operator ;\\\n \t}\n+HELM_OPERATOR=$(realpath ./bin/helm-operator)\n else\n-HELM_OPERATOR = $(shell which helm-operator)\n-endif\n+HELM_OPERATOR=$(shell which helm-operator)\n endif\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tMove the positional directory argument \u003Ccode class=\"literal\">.\u003C/code> in the \u003Ccode class=\"literal\">make\u003C/code> target for \u003Ccode class=\"literal\">docker-build\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThe directory argument \u003Ccode class=\"literal\">.\u003C/code> in the \u003Ccode class=\"literal\">docker-build\u003C/code> target was moved to the last positional argument to align with \u003Ccode class=\"literal\">podman\u003C/code> CLI expectations, which makes substitution cleaner:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Old target\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">docker-build:\n docker build . -t ${IMG}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>New target\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">docker-build:\n docker build -t ${IMG} .\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tYou can make this change by running the following command:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ sed -i 's/docker build . -t ${IMG}/docker build -t ${IMG} ./' $(git grep -l 'docker.*build \\. ')\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Ansible- and Helm-based Operator projects, add a \u003Ccode class=\"literal\">help\u003C/code> target to the \u003Ccode class=\"literal\">Makefile\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAnsible- and Helm-based projects now provide \u003Ccode class=\"literal\">help\u003C/code> target in the \u003Ccode class=\"literal\">Makefile\u003C/code> by default, similar to a \u003Ccode class=\"literal\">--help\u003C/code> flag. You can manually add this target to your \u003Ccode class=\"literal\">Makefile\u003C/code> using the following lines:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488172544\">\u003Cp class=\"title\">\u003Cstrong>Example 5.6. \u003Ccode class=\"literal\">help\u003C/code> target\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-make\">##@ General\n\n# The help target prints out all targets with their descriptions organized\n# beneath their categories. The categories are represented by '##@' and the\n# target descriptions by '##'. The awk commands is responsible for reading the\n# entire set of makefiles included in this invocation, looking for lines of the\n# file as xyz: ## something, and then pretty-format the target and help. Then,\n# if there's a line with ##@ something, that gets pretty-printed as a category.\n# More info on the usage of ANSI control characters for terminal formatting:\n# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters\n# More info on the awk command:\n# http://linuxcommand.org/lc3_adv_awk.php\n\nhelp: ## Display this help.\n\t@awk 'BEGIN {FS = \":.*##\"; printf \"\\nUsage:\\n make \\033[36m&lt;target&gt;\\033[0m\\n\"} /^[a-zA-Z_0-9-]+:.*?##/ { printf \" \\033[36m%-15s\\033[0m %s\\n\", $$1, $$2 } /^##@/ { printf \"\\n\\033[1m%s\\033[0m\\n\", substr($$0, 5) } ' $(MAKEFILE_LIST)\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAdd \u003Ccode class=\"literal\">opm\u003C/code> and \u003Ccode class=\"literal\">catalog-build\u003C/code> targets. You can use these targets to create your own catalogs for your Operator or add your Operator bundles to an existing catalog:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"i\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tAdd the targets to your \u003Ccode class=\"literal\">Makefile\u003C/code> by adding the following lines:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488164624\">\u003Cp class=\"title\">\u003Cstrong>Example 5.7. \u003Ccode class=\"literal\">opm\u003C/code> and \u003Ccode class=\"literal\">catalog-build\u003C/code> targets\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-make\">.PHONY: opm\nOPM = ./bin/opm\nopm:\nifeq (,$(wildcard $(OPM)))\nifeq (,$(shell which opm 2&gt;/dev/null))\n\t@{ \\\n\tset -e ;\\\n\tmkdir -p $(dir $(OPM)) ;\\\n\tcurl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.15.1/$(OS)-$(ARCH)-opm ;\\\n\tchmod +x $(OPM) ;\\\n\t}\nelse\nOPM = $(shell which opm)\nendif\nendif\nBUNDLE_IMGS ?= $(BUNDLE_IMG)\nCATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:v$(VERSION) ifneq ($(origin CATALOG_BASE_IMG), undefined) FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) endif\n.PHONY: catalog-build\ncatalog-build: opm\n\t$(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT)\n\n.PHONY: catalog-push\ncatalog-push: ## Push the catalog image.\n\t$(MAKE) docker-push IMG=$(CATALOG_IMG)\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tIf you are updating a Go-based Operator project, also add the following \u003Ccode class=\"literal\">Makefile\u003C/code> variables:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488158560\">\u003Cp class=\"title\">\u003Cstrong>Example 5.8. \u003Ccode class=\"literal\">Makefile\u003C/code> variables\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-make\">OS = $(shell go env GOOS)\nARCH = $(shell go env GOARCH)\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Go-based Operator projects, set the \u003Ccode class=\"literal\">SHELL\u003C/code> variable in your \u003Ccode class=\"literal\">Makefile\u003C/code> to the system \u003Ccode class=\"literal\">bash\u003C/code> binary.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tImporting the \u003Ccode class=\"literal\">setup-envtest.sh\u003C/code> script requires \u003Ccode class=\"literal\">bash\u003C/code>, so the \u003Ccode class=\"literal\">SHELL\u003C/code> variable must be set to \u003Ccode class=\"literal\">bash\u003C/code> with error options:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488150960\">\u003Cp class=\"title\">\u003Cstrong>Example 5.9. \u003Ccode class=\"literal\">Makefile\u003C/code> diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\">else GOBIN=$(shell go env GOBIN)\nendif\n+# Setting SHELL to bash allows bash commands to be executed by recipes.\n+# This is a requirement for 'setup-envtest.sh' in the test target.\n+# Options are set to exit when a recipe line exits non-zero or a piped command fails.\n+SHELL = /usr/bin/env bash -o pipefail\n+.SHELLFLAGS = -ec\n+ all: build\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tFor Go-based Operator projects, upgrade \u003Ccode class=\"literal\">controller-runtime\u003C/code> to v0.8.3 and Kubernetes dependencies to v0.20.2 by changing the following entries in your \u003Ccode class=\"literal\">go.mod\u003C/code> file, then rebuild your project:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488145888\">\u003Cp class=\"title\">\u003Cstrong>Example 5.10. \u003Ccode class=\"literal\">go.mod\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-go\">...\n\tk8s.io/api v0.20.2\n\tk8s.io/apimachinery v0.20.2\n\tk8s.io/client-go v0.20.2\n\tsigs.k8s.io/controller-runtime v0.8.3\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tAdd a \u003Ccode class=\"literal\">system:controller-manager\u003C/code> service account to your project. A non-default service account \u003Ccode class=\"literal\">controller-manager\u003C/code> is now generated by the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command to improve security for Operators installed in shared namespaces. To add this service account to your existing project, follow these steps:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tCreate the \u003Ccode class=\"literal\">ServiceAccount\u003C/code> definition in a file:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488138880\">\u003Cp class=\"title\">\u003Cstrong>Example 5.11. \u003Ccode class=\"literal\">config/rbac/service_account.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: controller-manager\n namespace: system\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAdd the service account to the list of RBAC resources:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ echo \"- service_account.yaml\" &gt;&gt; config/rbac/kustomization.yaml\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tUpdate all \u003Ccode class=\"literal\">RoleBinding\u003C/code> and \u003Ccode class=\"literal\">ClusterRoleBinding\u003C/code> objects that reference the Operator’s service account:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ find config/rbac -name *_binding.yaml -exec sed -i -E 's/ name: default/ name: controller-manager/g' {} \\;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAdd the service account name to the manager deployment’s \u003Ccode class=\"literal\">spec.template.spec.serviceAccountName\u003C/code> field:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ sed -i -E 's/([ ]+)(terminationGracePeriodSeconds:)/\\1serviceAccountName: controller-manager\\n\\1\\2/g' config/manager/manager.yaml\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tVerify the changes look like the following diffs:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488127248\">\u003Cp class=\"title\">\u003Cstrong>Example 5.12. \u003Ccode class=\"literal\">config/manager/manager.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\">...\n requests:\n cpu: 100m\n memory: 20Mi\n+ serviceAccountName: controller-manager\n terminationGracePeriodSeconds: 10\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209488124720\">\u003Cp class=\"title\">\u003Cstrong>Example 5.13. \u003Ccode class=\"literal\">config/rbac/auth_proxy_role_binding.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\">...\n name: proxy-role\n subjects:\n - kind: ServiceAccount\n- name: default\n+ name: controller-manager\n namespace: system\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209488122208\">\u003Cp class=\"title\">\u003Cstrong>Example 5.14. \u003Ccode class=\"literal\">config/rbac/kustomization.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\"> resources:\n+- service_account.yaml\n - role.yaml\n - role_binding.yaml\n - leader_election_role.yaml\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209488119744\">\u003Cp class=\"title\">\u003Cstrong>Example 5.15. \u003Ccode class=\"literal\">config/rbac/leader_election_role_binding.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\">...\n name: leader-election-role\n subjects:\n - kind: ServiceAccount\n- name: default\n+ name: controller-manager\n namespace: system\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209488117232\">\u003Cp class=\"title\">\u003Cstrong>Example 5.16. \u003Ccode class=\"literal\">config/rbac/role_binding.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\">...\n name: manager-role\n subjects:\n - kind: ServiceAccount\n- name: default\n+ name: controller-manager\n namespace: system\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209488114736\">\u003Cp class=\"title\">\u003Cstrong>Example 5.17. \u003Ccode class=\"literal\">config/rbac/service_account.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\">+apiVersion: v1\n+kind: ServiceAccount\n+metadata:\n+ name: controller-manager\n+ namespace: system\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMake the following changes to your \u003Ccode class=\"literal\">config/manifests/kustomization.yaml\u003C/code> file:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAdd a \u003Ca class=\"link\" href=\"https://kustomize.io/\">Kustomize\u003C/a> patch to remove the \u003Ca class=\"link\" href=\"https://cert-manager.io/\">cert-manager\u003C/a> \u003Ccode class=\"literal\">volume\u003C/code> and \u003Ccode class=\"literal\">volumeMount\u003C/code> objects from your cluster service version (CSV).\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tBecause Operator Lifecycle Manager (OLM) does not yet support cert-manager, a JSON patch was added to remove this volume and mount so OLM can create and manage certificates for your Operator.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tIn the \u003Ccode class=\"literal\">config/manifests/kustomization.yaml\u003C/code> file, add the following lines:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488104768\">\u003Cp class=\"title\">\u003Cstrong>Example 5.18. \u003Ccode class=\"literal\">config/manifests/kustomization.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">patchesJson6902:\n- target:\n group: apps\n version: v1\n kind: Deployment\n name: controller-manager\n namespace: system\n patch: |-\n # Remove the manager container's \"cert\" volumeMount, since OLM will create and mount a set of certs.\n # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment.\n - op: remove\n path: /spec/template/spec/containers/1/volumeMounts/0\n # Remove the \"cert\" volume, since OLM will create and mount a set of certs.\n # Update the indices in this path if adding or removing volumes in the manager's Deployment.\n - op: remove\n path: /spec/template/spec/volumes/0\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tOptional: For Ansible- and Helm-based Operator projects, configure \u003Ccode class=\"literal\">ansible-operator\u003C/code> and \u003Ccode class=\"literal\">helm-operator\u003C/code> with a component config. To add this option, follow these steps:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"i\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tCreate the following file:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488098224\">\u003Cp class=\"title\">\u003Cstrong>Example 5.19. \u003Ccode class=\"literal\">config/default/manager_config_patch.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: controller-manager\n namespace: system\nspec:\n template:\n spec:\n containers:\n - name: manager\n args:\n - \"--config=controller_manager_config.yaml\"\n volumeMounts:\n - name: manager-config\n mountPath: /controller_manager_config.yaml\n subPath: controller_manager_config.yaml\n volumes:\n - name: manager-config\n configMap:\n name: manager-config\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tCreate the following file:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488094368\">\u003Cp class=\"title\">\u003Cstrong>Example 5.20. \u003Ccode class=\"literal\">config/manager/controller_manager_config.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">apiVersion: controller-runtime.sigs.k8s.io/v1alpha1\nkind: ControllerManagerConfig\nhealth:\n healthProbeBindAddress: :6789\nmetrics:\n bindAddress: 127.0.0.1:8080\n\nleaderElection:\n leaderElect: true\n resourceName: &lt;resource_name&gt;\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">config/default/kustomization.yaml\u003C/code> file by applying the following changes to \u003Ccode class=\"literal\">resources\u003C/code>:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488089584\">\u003Cp class=\"title\">\u003Cstrong>Example 5.21. \u003Ccode class=\"literal\">config/default/kustomization.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\"> resources:\n ...\n - manager_config_patch.yaml\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">config/manager/kustomization.yaml\u003C/code> file by applying the following changes:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488085680\">\u003Cp class=\"title\">\u003Cstrong>Example 5.22. \u003Ccode class=\"literal\">config/manager/kustomization.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\"> generatorOptions:\n disableNameSuffixHash: true\n\n configMapGenerator:\n - files:\n - controller_manager_config.yaml\n name: manager-config\n apiVersion: kustomize.config.k8s.io/v1beta1\n kind: Kustomization\n images:\n - name: controller\n newName: quay.io/example/memcached-operator\n newTag: v0.0.1\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tOptional: Add a manager config patch to the \u003Ccode class=\"literal\">config/default/kustomization.yaml\u003C/code> file.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThe generated \u003Ccode class=\"literal\">--config\u003C/code> flag was not added to either the \u003Ccode class=\"literal\">ansible-operator\u003C/code> or \u003Ccode class=\"literal\">helm-operator\u003C/code> binary when \u003Ca class=\"link\" href=\"https://master.book.kubebuilder.io/component-config-tutorial/tutorial.html\">config file\u003C/a> support was originally added, so it does not currently work. The \u003Ccode class=\"literal\">--config\u003C/code> flag supports configuration of both binaries by file; this method of configuration only applies to the underlying \u003Ca class=\"link\" href=\"https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/manager#Manager\">controller manager\u003C/a> and not the Operator as a whole.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tTo optionally configure the Operator’s deployment with a config file, make changes to the \u003Ccode class=\"literal\">config/default/kustomization.yaml\u003C/code> file as shown in the following diff:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488075696\">\u003Cp class=\"title\">\u003Cstrong>Example 5.23. \u003Ccode class=\"literal\">config/default/kustomization.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\"># If you want your controller-manager to expose the /metrics # endpoint w/o any authn/z, please comment the following line.\n\\- manager_auth_proxy_patch.yaml\n+# Mount the controller config file for loading manager configurations\n+# through a ComponentConfig type\n+- manager_config_patch.yaml\u003C/pre>\u003C/div>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFlags can be used as is or to override config file values.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tFor Ansible- and Helm-based Operator projects, add role rules for leader election by making the following changes to the \u003Ccode class=\"literal\">config/rbac/leader_election_role.yaml\u003C/code> file:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488070608\">\u003Cp class=\"title\">\u003Cstrong>Example 5.24. \u003Ccode class=\"literal\">config/rbac/leader_election_role.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">- apiGroups:\n - coordination.k8s.io\n resources:\n - leases\n verbs:\n - get\n - list\n - watch\n - create\n - update\n - patch\n - delete\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tFor Ansible-based Operator projects, update Ansible collections.\n\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIn your \u003Ccode class=\"literal\">requirements.yml\u003C/code> file, change the \u003Ccode class=\"literal\">version\u003C/code> field for \u003Ccode class=\"literal\">community.kubernetes\u003C/code> to \u003Ccode class=\"literal\">1.2.1\u003C/code>, and the \u003Ccode class=\"literal\">version\u003C/code> field for \u003Ccode class=\"literal\">operator_sdk.util\u003C/code> to \u003Ccode class=\"literal\">0.2.0\u003C/code>.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMake the following changes to your \u003Ccode class=\"literal\">config/default/manager_auth_proxy_patch.yaml\u003C/code> file:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Ansible-based Operator projects, add the \u003Ccode class=\"literal\">--health-probe-bind-address=:6789\u003C/code> argument to the \u003Ccode class=\"literal\">config/default/manager_auth_proxy_patch.yaml\u003C/code> file:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488059568\">\u003Cp class=\"title\">\u003Cstrong>Example 5.25. \u003Ccode class=\"literal\">config/default/manager_auth_proxy_patch.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">spec:\n template:\n spec:\n containers:\n - name: manager\n args:\n - \"--health-probe-bind-address=:6789\"\n ...\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor Helm-based Operator projects:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"i\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tAdd the \u003Ccode class=\"literal\">--health-probe-bind-address=:8081\u003C/code> argument to the \u003Ccode class=\"literal\">config/default/manager_auth_proxy_patch.yaml\u003C/code> file:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488053616\">\u003Cp class=\"title\">\u003Cstrong>Example 5.26. \u003Ccode class=\"literal\">config/default/manager_auth_proxy_patch.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-yaml\">spec:\n template:\n spec:\n containers:\n - name: manager\n args:\n - \"--health-probe-bind-address=:8081\"\n ...\u003C/pre>\u003C/div>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\tReplace the deprecated flag \u003Ccode class=\"literal\">--enable-leader-election\u003C/code> with \u003Ccode class=\"literal\">--leader-elect\u003C/code>, and the deprecated flag \u003Ccode class=\"literal\">--metrics-addr\u003C/code> with \u003Ccode class=\"literal\">--metrics-bind-address\u003C/code>.\n\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tMake the following changes to your \u003Ccode class=\"literal\">config/prometheus/monitor.yaml\u003C/code> file:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAdd scheme, token, and TLS config to the Prometheus \u003Ccode class=\"literal\">ServiceMonitor\u003C/code> metrics endpoint.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">/metrics\u003C/code> endpoint, while specifying the \u003Ccode class=\"literal\">https\u003C/code> port on the manager pod, was not actually configured to serve over HTTPS because no \u003Ccode class=\"literal\">tlsConfig\u003C/code> was set. Because \u003Ccode class=\"literal\">kube-rbac-proxy\u003C/code> secures this endpoint as a manager sidecar, using the service account token mounted into the pod by default corrects this problem.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tApply the changes to the \u003Ccode class=\"literal\">config/prometheus/monitor.yaml\u003C/code> file as shown in the following diff:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209488040416\">\u003Cp class=\"title\">\u003Cstrong>Example 5.27. \u003Ccode class=\"literal\">config/prometheus/monitor.yaml\u003C/code> file diff\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-diff\">spec:\n endpoints:\n - path: /metrics\n port: https\n+ scheme: https\n+ bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n+ tlsConfig:\n+ insecureSkipVerify: true\n selector:\n matchLabels:\n control-plane: controller-manager\u003C/pre>\u003C/div>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\tIf you removed \u003Ccode class=\"literal\">kube-rbac-proxy\u003C/code> from your project, ensure that you secure the \u003Ccode class=\"literal\">/metrics\u003C/code> endpoint using a proper \u003Ca class=\"link\" href=\"https://prometheus.io/docs/guides/tls-encryption\">TLS configuration\u003C/a>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tEnsure that existing dependent resources have owner annotations.\n\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tFor Ansible-based Operator projects, \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/building-operators/ansible/reference/retroactively-owned-resources/\">owner reference annotations\u003C/a> on cluster-scoped dependent resources and dependent resources in other namespaces were not applied correctly. A workaround was to add these annotations manually, which is no longer required as this bug has been fixed.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tDeprecate support for package manifests.\n\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tThe \u003Ca class=\"link\" href=\"https://operatorframework.io/\">Operator Framework\u003C/a> is removing support for the Operator package manifest format in a future release. As part of the ongoing deprecation process, the \u003Ccode class=\"literal\">operator-sdk generate packagemanifests\u003C/code> and \u003Ccode class=\"literal\">operator-sdk run packagemanifests\u003C/code> commands are now deprecated. To migrate package manifests to bundles, the \u003Ccode class=\"literal\">operator-sdk pkgman-to-bundle\u003C/code> command can be used.\n\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">operator-sdk pkgman-to-bundle --help\u003C/code> command and see \"Migrating package manifest projects to bundle format\" for more details.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tUpdate the finalizer names for your Operator.\n\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tThe finalizer name format suggested by \u003Ca class=\"link\" href=\"https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#finalizers\">Kubernetes documentation\u003C/a> is:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">&lt;qualified_group&gt;/&lt;finalizer_name&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\twhile the format previously documented for Operator SDK was:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">&lt;finalizer_name&gt;.&lt;qualified_group&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIf your Operator uses any finalizers with names that match the incorrect format, change them to match the official format. For example, \u003Ccode class=\"literal\">finalizer.cache.example.com\u003C/code> must be changed to \u003Ccode class=\"literal\">cache.example.com/finalizer\u003C/code>.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003Cp>\n\t\t\t\t\tYour Operator project is now compatible with Operator SDK v1.8.0.\n\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section _additional-resources\" id=\"additional-resources_osdk-upgrading-projects\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.3.2. Additional resources\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-pkgman-to-bundle\">Migrating package manifest projects to bundle format\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"go-based-operators\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.4. Go-based Operators\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-golang-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.4.1. Getting started with Operator SDK for Go-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tTo demonstrate the basics of setting up and running a Go-based Operator using tools and libraries provided by the Operator SDK, Operator developers can build an example Go-based Operator for Memcached, a distributed key-value store, and deploy it to a cluster.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-common-prereqs_osdk-golang-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.1.1. Prerequisites\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli\">Operator SDK CLI installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli\">OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tLogged into an OpenShift Container Platform 4.8 cluster with \u003Ccode class=\"literal\">oc\u003C/code> with an account that has \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tTo allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-quickstart_osdk-golang-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.1.2. Creating and deploying Go-based Operators\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tYou can build and deploy a simple Go-based Operator for Memcached by using the Operator SDK.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create a project.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate your project directory:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ mkdir memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tChange into the project directory:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ cd memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command to initialize the project:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk init \\\n --domain=example.com \\\n --repo=github.com/example-inc/memcached-operator\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tThe command uses the Go plugin by default.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create an API.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate a simple Memcached API:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk create api \\\n --resource=true \\\n --controller=true \\\n --group cache \\\n --version v1 \\\n --kind Memcached\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Build and push the Operator image.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUse the default \u003Ccode class=\"literal\">Makefile\u003C/code> targets to build and push your Operator. Set \u003Ccode class=\"literal\">IMG\u003C/code> with a pull spec for your image that uses a registry you can push to:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Run the Operator.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tInstall the CRD:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make install\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tDeploy the project to the cluster. Set \u003Ccode class=\"literal\">IMG\u003C/code> to the image that you pushed:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create a sample custom resource (CR).\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate a sample CR:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/cache_v1_memcached.yaml \\\n -n memcached-operator-system\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tWatch for the CR to reconcile the Operator:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc logs deployment.apps/memcached-operator-controller-manager \\\n -c manager \\\n -n memcached-operator-system\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Clean up.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the following command to clean up the resources that have been created as part of this procedure:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make undeploy\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-quickstart-next-steps\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.1.3. Next steps\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-golang-tutorial\">Operator SDK tutorial for Go-based Operators\u003C/a> for a more in-depth walkthrough on building a Go-based Operator.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.4.2. Operator SDK tutorial for Go-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator developers can take advantage of Go programming language support in the Operator SDK to build an example Go-based Operator for Memcached, a distributed key-value store, and manage its lifecycle.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThis process is accomplished using two centerpieces of the Operator Framework:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">Operator SDK\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk\u003C/code> CLI tool and \u003Ccode class=\"literal\">controller-runtime\u003C/code> library API\n\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">Operator Lifecycle Manager (OLM)\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tInstallation, upgrade, and role-based access control (RBAC) of Operators on a cluster\n\t\t\t\t\t\t\t\u003C/dd>\u003C/dl>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tThis tutorial goes into greater detail than \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-golang-quickstart\">Getting started with Operator SDK for Go-based Operators\u003C/a>.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Csection class=\"section\" id=\"osdk-common-prereqs_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.2.1. Prerequisites\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli\">Operator SDK CLI installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli\">OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tLogged into an OpenShift Container Platform 4.8 cluster with \u003Ccode class=\"literal\">oc\u003C/code> with an account that has \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tTo allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-create-project_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.2.2. Creating a project\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tUse the Operator SDK CLI to create a project called \u003Ccode class=\"literal\">memcached-operator\u003C/code>.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate a directory for the project:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ mkdir -p $HOME/projects/memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tChange to the directory:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ cd $HOME/projects/memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tActivate support for Go modules:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ export GO111MODULE=on\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command to initialize the project:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk init \\\n --domain=example.com \\\n --repo=github.com/example-inc/memcached-operator\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command uses the Go plugin by default.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command generates a \u003Ccode class=\"literal\">go.mod\u003C/code> file to be used with \u003Ca class=\"link\" href=\"https://golang.org/ref/mod\">Go modules\u003C/a>. The \u003Ccode class=\"literal\">--repo\u003C/code> flag is required when creating a project outside of \u003Ccode class=\"literal\">$GOPATH/src/\u003C/code>, because generated files require a valid module path.\n\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003Csection class=\"section\" id=\"osdk-project-file_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.2.1. PROJECT file\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tAmong the files generated by the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command is a Kubebuilder \u003Ccode class=\"literal\">PROJECT\u003C/code> file. Subsequent \u003Ccode class=\"literal\">operator-sdk\u003C/code> commands, as well as \u003Ccode class=\"literal\">help\u003C/code> output, that are run from the project root read this file and are aware that the project type is Go. For example:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">domain: example.com\nlayout: go.kubebuilder.io/v3\nprojectName: memcached-operator\nrepo: github.com/example-inc/memcached-operator\nversion: 3\nplugins:\n manifests.sdk.operatorframework.io/v2: {}\n scorecard.sdk.operatorframework.io/v2: {}\u003C/pre>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-manager_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.2.2. About the Manager\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tThe main program for the Operator is the \u003Ccode class=\"literal\">main.go\u003C/code> file, which initializes and runs the \u003Ca class=\"link\" href=\"https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/manager#Manager\">Manager\u003C/a>. The Manager automatically registers the Scheme for all custom resource (CR) API definitions and sets up and runs controllers and webhooks.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tThe Manager can restrict the namespace that all controllers watch for resources:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: namespace})\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tBy default, the Manager watches the namespace where the Operator runs. To watch all namespaces, you can leave the \u003Ccode class=\"literal\">namespace\u003C/code> option empty:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: \"\"})\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tYou can also use the \u003Ca class=\"link\" href=\"https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/cache#MultiNamespacedCacheBuilder\">\u003Ccode class=\"literal\">MultiNamespacedCacheBuilder\u003C/code>\u003C/a> function to watch a specific set of namespaces:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">var namespaces []string \u003Cspan id=\"CO38-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\nmgr, err := ctrl.NewManager(cfg, manager.Options{ \u003Cspan id=\"CO38-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\n NewCache: cache.MultiNamespacedCacheBuilder(namespaces),\n})\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO38-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tList of namespaces.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO38-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tCreates a \u003Ccode class=\"literal\">Cmd\u003C/code> struct to provide shared dependencies and start components.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-multi-group-apis_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.2.3. About multi-group APIs\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tBefore you create an API and controller, consider whether your Operator requires multiple API groups. This tutorial covers the default case of a single group API, but to change the layout of your project to support multi-group APIs, you can run the following command:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk edit --multigroup=true\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tThis command updates the \u003Ccode class=\"literal\">PROJECT\u003C/code> file, which should look like the following example:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">domain: example.com\nlayout: go.kubebuilder.io/v3\nmultigroup: true\n...\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tFor multi-group projects, the API Go type files are created in the \u003Ccode class=\"literal\">apis/&lt;group&gt;/&lt;version&gt;/\u003C/code> directory, and the controllers are created in the \u003Ccode class=\"literal\">controllers/&lt;group&gt;/\u003C/code> directory. The Dockerfile is then updated accordingly.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Additional resource\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tFor more details on migrating to a multi-group project, see the \u003Ca class=\"link\" href=\"https://book.kubebuilder.io/migration/multi-group.html\">Kubebuilder documentation\u003C/a>.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-create-api-controller_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.2.3. Creating an API and controller\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tUse the Operator SDK CLI to create a custom resource definition (CRD) API and controller.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the following command to create an API with group \u003Ccode class=\"literal\">cache\u003C/code>, version, \u003Ccode class=\"literal\">v1\u003C/code>, and kind \u003Ccode class=\"literal\">Memcached\u003C/code>:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk create api \\\n --group=cache \\\n --version=v1 \\\n --kind=Memcached\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tWhen prompted, enter \u003Ccode class=\"literal\">y\u003C/code> for creating both the resource and controller:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">Create Resource [y/n]\ny\nCreate Controller [y/n]\ny\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">Writing scaffold for you to edit...\napi/v1/memcached_types.go\ncontrollers/memcached_controller.go\n...\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThis process generates the \u003Ccode class=\"literal\">Memcached\u003C/code> resource API at \u003Ccode class=\"literal\">api/v1/memcached_types.go\u003C/code> and the controller at \u003Ccode class=\"literal\">controllers/memcached_controller.go\u003C/code>.\n\t\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-golang-define-api_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.3.1. Defining the API\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tDefine the API for the \u003Ccode class=\"literal\">Memcached\u003C/code> custom resource (CR).\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tModify the Go type definitions at \u003Ccode class=\"literal\">api/v1/memcached_types.go\u003C/code> to have the following \u003Ccode class=\"literal\">spec\u003C/code> and \u003Ccode class=\"literal\">status\u003C/code>:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">// MemcachedSpec defines the desired state of Memcached\ntype MemcachedSpec struct {\n\t// +kubebuilder:validation:Minimum=0\n\t// Size is the size of the memcached deployment\n\tSize int32 `json:\"size\"`\n}\n\n// MemcachedStatus defines the observed state of Memcached\ntype MemcachedStatus struct {\n\t// Nodes are the names of the memcached pods\n\tNodes []string `json:\"nodes\"`\n}\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tUpdate the generated code for the resource type:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make generate\u003C/pre>\u003Crh-alert class=\"admonition tip\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Tip\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\tAfter you modify a \u003Ccode class=\"literal\">*_types.go\u003C/code> file, you must run the \u003Ccode class=\"literal\">make generate\u003C/code> command to update the generated code for that resource type.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThe above Makefile target invokes the \u003Ccode class=\"literal\">controller-gen\u003C/code> utility to update the \u003Ccode class=\"literal\">api/v1/zz_generated.deepcopy.go\u003C/code> file. This ensures your API Go type definitions implement the \u003Ccode class=\"literal\">runtime.Object\u003C/code> interface that all Kind types must implement.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-generate-crd_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.3.2. Generating CRD manifests\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tAfter the API is defined with \u003Ccode class=\"literal\">spec\u003C/code> and \u003Ccode class=\"literal\">status\u003C/code> fields and custom resource definition (CRD) validation markers, you can generate CRD manifests.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following command to generate and update CRD manifests:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make manifests\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThis Makefile target invokes the \u003Ccode class=\"literal\">controller-gen\u003C/code> utility to generate the CRD manifests in the \u003Ccode class=\"literal\">config/crd/bases/cache.example.com_memcacheds.yaml\u003C/code> file.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"osdk-about-openapi-validation_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch6 class=\"title\">5.4.2.3.2.1. About OpenAPI validation\u003C/h6>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\t\tOpenAPIv3 schemas are added to CRD manifests in the \u003Ccode class=\"literal\">spec.validation\u003C/code> block when the manifests are generated. This validation block allows Kubernetes to validate the properties in a Memcached custom resource (CR) when it is created or updated.\n\t\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\tMarkers, or annotations, are available to configure validations for your API. These markers always have a \u003Ccode class=\"literal\">+kubebuilder:validation\u003C/code> prefix.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tFor more details on the usage of markers in API code, see the following Kubebuilder documentation:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"circle\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://book.kubebuilder.io/reference/generating-crd.html\">CRD generation\u003C/a>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://book.kubebuilder.io/reference/markers.html\">Markers\u003C/a>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://book.kubebuilder.io/reference/markers/crd-validation.html\">List of OpenAPIv3 validation markers\u003C/a>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tFor more details about OpenAPIv3 validation schemas in CRDs, see the \u003Ca class=\"link\" href=\"https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema\">Kubernetes documentation\u003C/a>.\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-implement-controller_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.2.4. Implementing the controller\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAfter creating a new API and controller, you can implement the controller logic.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tFor this example, replace the generated controller file \u003Ccode class=\"literal\">controllers/memcached_controller.go\u003C/code> with following example implementation:\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209515967600\">\u003Cp class=\"title\">\u003Cstrong>Example 5.28. Example \u003Ccode class=\"literal\">memcached_controller.go\u003C/code>\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-golang\">/*\nCopyright 2020.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllers\n\nimport (\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\t\"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"reflect\"\n\n\t\"context\"\n\n\t\"github.com/go-logr/logr\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tctrl \"sigs.k8s.io/controller-runtime\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\tcachev1alpha1 \"github.com/example/memcached-operator/api/v1alpha1\"\n)\n\n// MemcachedReconciler reconciles a Memcached object\ntype MemcachedReconciler struct {\n\tclient.Client\n\tLog logr.Logger\n\tScheme *runtime.Scheme\n}\n\n// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete\n// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch\n// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update\n// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete\n// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;\n\n// Reconcile is part of the main kubernetes reconciliation loop which aims to\n// move the current state of the cluster closer to the desired state.\n// TODO(user): Modify the Reconcile function to compare the state specified by\n// the Memcached object against the actual cluster state, and then\n// perform operations to make the cluster state reflect the state specified by\n// the user.\n//\n// For more details, check Reconcile and its Result here:\n// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.7.0/pkg/reconcile\nfunc (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {\n\tlog := r.Log.WithValues(\"memcached\", req.NamespacedName)\n\n\t// Fetch the Memcached instance\n\tmemcached := &amp;cachev1alpha1.Memcached{}\n\terr := r.Get(ctx, req.NamespacedName, memcached)\n\tif err != nil {\n\t\tif errors.IsNotFound(err) {\n\t\t\t// Request object not found, could have been deleted after reconcile request.\n\t\t\t// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.\n\t\t\t// Return and don't requeue\n\t\t\tlog.Info(\"Memcached resource not found. Ignoring since object must be deleted\")\n\t\t\treturn ctrl.Result{}, nil\n\t\t}\n\t\t// Error reading the object - requeue the request.\n\t\tlog.Error(err, \"Failed to get Memcached\")\n\t\treturn ctrl.Result{}, err\n\t}\n\n\t// Check if the deployment already exists, if not create a new one\n\tfound := &amp;appsv1.Deployment{}\n\terr = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found)\n\tif err != nil &amp;&amp; errors.IsNotFound(err) {\n\t\t// Define a new deployment\n\t\tdep := r.deploymentForMemcached(memcached)\n\t\tlog.Info(\"Creating a new Deployment\", \"Deployment.Namespace\", dep.Namespace, \"Deployment.Name\", dep.Name)\n\t\terr = r.Create(ctx, dep)\n\t\tif err != nil {\n\t\t\tlog.Error(err, \"Failed to create new Deployment\", \"Deployment.Namespace\", dep.Namespace, \"Deployment.Name\", dep.Name)\n\t\t\treturn ctrl.Result{}, err\n\t\t}\n\t\t// Deployment created successfully - return and requeue\n\t\treturn ctrl.Result{Requeue: true}, nil\n\t} else if err != nil {\n\t\tlog.Error(err, \"Failed to get Deployment\")\n\t\treturn ctrl.Result{}, err\n\t}\n\n\t// Ensure the deployment size is the same as the spec\n\tsize := memcached.Spec.Size\n\tif *found.Spec.Replicas != size {\n\t\tfound.Spec.Replicas = &amp;size\n\t\terr = r.Update(ctx, found)\n\t\tif err != nil {\n\t\t\tlog.Error(err, \"Failed to update Deployment\", \"Deployment.Namespace\", found.Namespace, \"Deployment.Name\", found.Name)\n\t\t\treturn ctrl.Result{}, err\n\t\t}\n\t\t// Spec updated - return and requeue\n\t\treturn ctrl.Result{Requeue: true}, nil\n\t}\n\n\t// Update the Memcached status with the pod names\n\t// List the pods for this memcached's deployment\n\tpodList := &amp;corev1.PodList{}\n\tlistOpts := []client.ListOption{\n\t\tclient.InNamespace(memcached.Namespace),\n\t\tclient.MatchingLabels(labelsForMemcached(memcached.Name)),\n\t}\n\tif err = r.List(ctx, podList, listOpts...); err != nil {\n\t\tlog.Error(err, \"Failed to list pods\", \"Memcached.Namespace\", memcached.Namespace, \"Memcached.Name\", memcached.Name)\n\t\treturn ctrl.Result{}, err\n\t}\n\tpodNames := getPodNames(podList.Items)\n\n\t// Update status.Nodes if needed\n\tif !reflect.DeepEqual(podNames, memcached.Status.Nodes) {\n\t\tmemcached.Status.Nodes = podNames\n\t\terr := r.Status().Update(ctx, memcached)\n\t\tif err != nil {\n\t\t\tlog.Error(err, \"Failed to update Memcached status\")\n\t\t\treturn ctrl.Result{}, err\n\t\t}\n\t}\n\n\treturn ctrl.Result{}, nil\n}\n\n// deploymentForMemcached returns a memcached Deployment object\nfunc (r *MemcachedReconciler) deploymentForMemcached(m *cachev1alpha1.Memcached) *appsv1.Deployment {\n\tls := labelsForMemcached(m.Name)\n\treplicas := m.Spec.Size\n\n\tdep := &amp;appsv1.Deployment{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: m.Name,\n\t\t\tNamespace: m.Namespace,\n\t\t},\n\t\tSpec: appsv1.DeploymentSpec{\n\t\t\tReplicas: &amp;replicas,\n\t\t\tSelector: &amp;metav1.LabelSelector{\n\t\t\t\tMatchLabels: ls,\n\t\t\t},\n\t\t\tTemplate: corev1.PodTemplateSpec{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tLabels: ls,\n\t\t\t\t},\n\t\t\t\tSpec: corev1.PodSpec{\n\t\t\t\t\tContainers: []corev1.Container{{\n\t\t\t\t\t\tImage: \"memcached:1.4.36-alpine\",\n\t\t\t\t\t\tName: \"memcached\",\n\t\t\t\t\t\tCommand: []string{\"memcached\", \"-m=64\", \"-o\", \"modern\", \"-v\"},\n\t\t\t\t\t\tPorts: []corev1.ContainerPort{{\n\t\t\t\t\t\t\tContainerPort: 11211,\n\t\t\t\t\t\t\tName: \"memcached\",\n\t\t\t\t\t\t}},\n\t\t\t\t\t}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// Set Memcached instance as the owner and controller\n\tctrl.SetControllerReference(m, dep, r.Scheme)\n\treturn dep\n}\n\n// labelsForMemcached returns the labels for selecting the resources\n// belonging to the given memcached CR name.\nfunc labelsForMemcached(name string) map[string]string {\n\treturn map[string]string{\"app\": \"memcached\", \"memcached_cr\": name}\n}\n\n// getPodNames returns the pod names of the array of pods passed in\nfunc getPodNames(pods []corev1.Pod) []string {\n\tvar podNames []string\n\tfor _, pod := range pods {\n\t\tpodNames = append(podNames, pod.Name)\n\t}\n\treturn podNames\n}\n\n// SetupWithManager sets up the controller with the Manager.\nfunc (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {\n\treturn ctrl.NewControllerManagedBy(mgr).\n\t\tFor(&amp;cachev1alpha1.Memcached{}).\n\t\tOwns(&amp;appsv1.Deployment{}).\n\t\tComplete(r)\n}\u003C/pre>\u003C/div>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThe example controller runs the following reconciliation logic for each \u003Ccode class=\"literal\">Memcached\u003C/code> custom resource (CR):\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"circle\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tCreate a Memcached deployment if it does not exist.\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tEnsure that the deployment size is the same as specified by the \u003Ccode class=\"literal\">Memcached\u003C/code> CR spec.\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">Memcached\u003C/code> CR status with the names of the \u003Ccode class=\"literal\">memcached\u003C/code> pods.\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe next subsections explain how the controller in the example implementation watches resources and how the reconcile loop is triggered. You can skip these subsections to go directly to \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-run-operator_osdk-golang-tutorial\">Running the Operator\u003C/a>.\n\t\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-golang-controller-resources_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.4.1. Resources watched by the controller\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">SetupWithManager()\u003C/code> function in \u003Ccode class=\"literal\">controllers/memcached_controller.go\u003C/code> specifies how the controller is built to watch a CR and other resources that are owned and managed by that controller.\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import (\n\t...\n\tappsv1 \"k8s.io/api/apps/v1\"\n\t...\n)\n\nfunc (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {\n\treturn ctrl.NewControllerManagedBy(mgr).\n\t\tFor(&amp;cachev1.Memcached{}).\n\t\tOwns(&amp;appsv1.Deployment{}).\n\t\tComplete(r)\n}\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">NewControllerManagedBy()\u003C/code> provides a controller builder that allows various controller configurations.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">For(&amp;cachev1.Memcached{})\u003C/code> specifies the \u003Ccode class=\"literal\">Memcached\u003C/code> type as the primary resource to watch. For each Add, Update, or Delete event for a \u003Ccode class=\"literal\">Memcached\u003C/code> type, the reconcile loop is sent a reconcile \u003Ccode class=\"literal\">Request\u003C/code> argument, which consists of a namespace and name key, for that \u003Ccode class=\"literal\">Memcached\u003C/code> object.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Owns(&amp;appsv1.Deployment{})\u003C/code> specifies the \u003Ccode class=\"literal\">Deployment\u003C/code> type as the secondary resource to watch. For each \u003Ccode class=\"literal\">Deployment\u003C/code> type Add, Update, or Delete event, the event handler maps each event to a reconcile request for the owner of the deployment. In this case, the owner is the \u003Ccode class=\"literal\">Memcached\u003C/code> object for which the deployment was created.\n\t\t\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-controller-configs_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.4.2. Controller configurations\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can initialize a controller by using many other useful configurations. For example:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tSet the maximum number of concurrent reconciles for the controller by using the \u003Ccode class=\"literal\">MaxConcurrentReconciles\u003C/code> option, which defaults to \u003Ccode class=\"literal\">1\u003C/code>:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {\n return ctrl.NewControllerManagedBy(mgr).\n For(&amp;cachev1.Memcached{}).\n Owns(&amp;appsv1.Deployment{}).\n WithOptions(controller.Options{\n MaxConcurrentReconciles: 2,\n }).\n Complete(r)\n}\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tFilter watch events using predicates.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tChoose the type of \u003Ca class=\"link\" href=\"https://godoc.org/sigs.k8s.io/controller-runtime/pkg/handler#hdr-EventHandlers\">EventHandler\u003C/a> to change how a watch event translates to reconcile requests for the reconcile loop. For Operator relationships that are more complex than primary and secondary resources, you can use the \u003Ccode class=\"literal\">EnqueueRequestsFromMapFunc\u003C/code> handler to transform a watch event into an arbitrary set of reconcile requests.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tFor more details on these and other configurations, see the upstream \u003Ca class=\"link\" href=\"https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/builder#example-Builder\">Builder\u003C/a> and \u003Ca class=\"link\" href=\"https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/controller\">Controller\u003C/a> GoDocs.\n\t\t\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-controller-reconcile-loop_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.4.3. Reconcile loop\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tEvery controller has a reconciler object with a \u003Ccode class=\"literal\">Reconcile()\u003C/code> method that implements the reconcile loop. The reconcile loop is passed the \u003Ccode class=\"literal\">Request\u003C/code> argument, which is a namespace and name key used to find the primary resource object, \u003Ccode class=\"literal\">Memcached\u003C/code>, from the cache:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import (\n\tctrl \"sigs.k8s.io/controller-runtime\"\n\n\tcachev1 \"github.com/example-inc/memcached-operator/api/v1\"\n\t...\n)\n\nfunc (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {\n // Lookup the Memcached instance for this reconcile request\n memcached := &amp;cachev1.Memcached{}\n err := r.Get(ctx, req.NamespacedName, memcached)\n ...\n}\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tBased on the return values, result, and error, the request might be requeued and the reconcile loop might be triggered again:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">// Reconcile successful - don't requeue\nreturn ctrl.Result{}, nil\n// Reconcile failed due to error - requeue\nreturn ctrl.Result{}, err\n// Requeue for any reason other than an error\nreturn ctrl.Result{Requeue: true}, nil\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tYou can set the \u003Ccode class=\"literal\">Result.RequeueAfter\u003C/code> to requeue the request after a grace period as well:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import \"time\"\n\n// Reconcile for any reason other than an error after 5 seconds\nreturn ctrl.Result{RequeueAfter: time.Second*5}, nil\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\tYou can return \u003Ccode class=\"literal\">Result\u003C/code> with \u003Ccode class=\"literal\">RequeueAfter\u003C/code> set to periodically reconcile a CR.\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cp>\n\t\t\t\t\t\t\tFor more on reconcilers, clients, and interacting with resource events, see the \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/building-operators/golang/references/client/\">Controller Runtime Client API\u003C/a> documentation.\n\t\t\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-controller-rbac-markers_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.4.4. Permissions and RBAC manifests\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tThe controller requires certain RBAC permissions to interact with the resources it manages. These are specified using RBAC markers, such as the following:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete\n// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch\n// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update\n// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete\n// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;\n\nfunc (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {\n ...\n}\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">ClusterRole\u003C/code> object manifest at \u003Ccode class=\"literal\">config/rbac/role.yaml\u003C/code> is generated from the previous markers by using the \u003Ccode class=\"literal\">controller-gen\u003C/code> utility whenever the \u003Ccode class=\"literal\">make manifests\u003C/code> command is run.\n\t\t\t\t\t\t\u003C/p>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-run-operator_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.2.5. Running the Operator\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThere are three ways you can use the Operator SDK CLI to build and run your Operator:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRun locally outside the cluster as a Go program.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRun as a deployment on the cluster.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tBundle your Operator and use Operator Lifecycle Manager (OLM) to deploy on the cluster.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\tBefore running your Go-based Operator as either a deployment on OpenShift Container Platform or as a bundle that uses OLM, ensure that your project has been updated to use supported images.\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Csection class=\"section\" id=\"osdk-run-locally_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.5.1. Running locally outside the cluster\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can run your Operator project as a Go program outside of the cluster. This is useful for development purposes to speed up deployment and testing.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following command to install the custom resource definitions (CRDs) in the cluster configured in your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file and run the Operator locally:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make install run\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">...\n2021-01-10T21:09:29.016-0700\tINFO\tcontroller-runtime.metrics\tmetrics server is starting to listen\t{\"addr\": \":8080\"}\n2021-01-10T21:09:29.017-0700\tINFO\tsetup\tstarting manager\n2021-01-10T21:09:29.017-0700\tINFO\tcontroller-runtime.manager\tstarting metrics server\t{\"path\": \"/metrics\"}\n2021-01-10T21:09:29.018-0700\tINFO\tcontroller-runtime.manager.controller.memcached\tStarting EventSource\t{\"reconciler group\": \"cache.example.com\", \"reconciler kind\": \"Memcached\", \"source\": \"kind source: /, Kind=\"}\n2021-01-10T21:09:29.218-0700\tINFO\tcontroller-runtime.manager.controller.memcached\tStarting Controller\t{\"reconciler group\": \"cache.example.com\", \"reconciler kind\": \"Memcached\"}\n2021-01-10T21:09:29.218-0700\tINFO\tcontroller-runtime.manager.controller.memcached\tStarting workers\t{\"reconciler group\": \"cache.example.com\", \"reconciler kind\": \"Memcached\", \"worker count\": 1}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-run-deployment_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.5.2. Running as a deployment on the cluster\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can run your Operator project as a deployment on your cluster.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tPrepared your Go-based Operator to run on OpenShift Container Platform by updating the project to use supported images\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands to build and push the Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\tThe name and tag of the image, for example \u003Ccode class=\"literal\">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/code>, in both the commands can also be set in your Makefile. Modify the \u003Ccode class=\"literal\">IMG ?= controller:latest\u003C/code> value to set your default image name.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following command to deploy the Operator:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tBy default, this command creates a namespace with the name of your Operator project in the form \u003Ccode class=\"literal\">&lt;project_name&gt;-system\u003C/code> and is used for the deployment. This command also installs the RBAC manifests from \u003Ccode class=\"literal\">config/rbac\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tVerify that the Operator is running:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployment -n &lt;project_name&gt;-system\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\n&lt;project_name&gt;-controller-manager 1/1 1 1 8m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-bundle-deploy-olm_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.4.2.5.3. Bundling an Operator and deploying with Operator Lifecycle Manager\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-bundle-operator_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch6 class=\"title\">5.4.2.5.3.1. Bundling an Operator\u003C/h6>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator project initialized by using the Operator SDK\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tIf your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands in your Operator project directory to build and push your Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate your Operator bundle manifest by running the \u003Ccode class=\"literal\">make bundle\u003C/code> command, which invokes several commands, including the Operator SDK \u003Ccode class=\"literal\">generate bundle\u003C/code> and \u003Ccode class=\"literal\">bundle validate\u003C/code> subcommands:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tBundle manifests for an Operator describe how to display, create, and manage an application. The \u003Ccode class=\"literal\">make bundle\u003C/code> command creates the following files and directories in your Operator project:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA bundle manifests directory named \u003Ccode class=\"literal\">bundle/manifests\u003C/code> that contains a \u003Ccode class=\"literal\">ClusterServiceVersion\u003C/code> object\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA bundle metadata directory named \u003Ccode class=\"literal\">bundle/metadata\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tAll custom resource definitions (CRDs) in a \u003Ccode class=\"literal\">config/crd\u003C/code> directory\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA Dockerfile \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tThese files are then automatically validated by using \u003Ccode class=\"literal\">operator-sdk bundle validate\u003C/code> to ensure the on-disk bundle representation is correct.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tBuild and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tBuild the bundle image. Set \u003Ccode class=\"literal\">BUNDLE_IMG\u003C/code> with the details for the registry, user namespace, and image tag where you intend to push the image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tPush the bundle image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-deploy-olm_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch6 class=\"title\">5.4.2.5.3.2. Deploying an Operator with Operator Lifecycle Manager\u003C/h6>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\t\tOperator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) for all Operator lifecycle management functions without any additional tools.\n\t\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator bundle image built and pushed to a registry\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use \u003Ccode class=\"literal\">apiextensions.k8s.io/v1\u003C/code> CRDs, for example OpenShift Container Platform 4.8)\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tLogged in to the cluster with \u003Ccode class=\"literal\">oc\u003C/code> using an account with \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tIf your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tEnter the following command to run the Operator on the cluster:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk run bundle \\\n [-n &lt;namespace&gt;] \\\u003Cspan id=\"CO39-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO39-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\t\tBy default, the command installs the Operator in the currently active project in your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file. You can add the \u003Ccode class=\"literal\">-n\u003C/code> flag to set a different namespace scope for the installation.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tThis command performs the following actions:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tCreate an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tCreate a catalog source that points to your new index image, which enables OperatorHub to discover your Operator.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tDeploy your Operator to your cluster by creating an \u003Ccode class=\"literal\">OperatorGroup\u003C/code>, \u003Ccode class=\"literal\">Subscription\u003C/code>, \u003Ccode class=\"literal\">InstallPlan\u003C/code>, and all other required objects, including RBAC.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-create-cr_osdk-golang-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.2.6. Creating a custom resource\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAfter your Operator is installed, you can test it by creating a custom resource (CR) that is now provided on the cluster by the Operator.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tExample Memcached Operator, which provides the \u003Ccode class=\"literal\">Memcached\u003C/code> CR, installed on a cluster\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tChange to the namespace where your Operator is installed. For example, if you deployed the Operator using the \u003Ccode class=\"literal\">make deploy\u003C/code> command:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc project memcached-operator-system\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tEdit the sample \u003Ccode class=\"literal\">Memcached\u003C/code> CR manifest at \u003Ccode class=\"literal\">config/samples/cache_v1_memcached.yaml\u003C/code> to contain the following specification:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: cache.example.com/v1\nkind: Memcached\nmetadata:\n name: memcached-sample\n...\nspec:\n...\n size: 3\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate the CR:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/cache_v1_memcached.yaml\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tEnsure that the \u003Ccode class=\"literal\">Memcached\u003C/code> Operator creates the deployment for the sample CR with the correct size:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployments\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\nmemcached-operator-controller-manager 1/1 1 1 8m\nmemcached-sample 3/3 3 3 1m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCheck the pods and CR status to confirm the status is updated with the Memcached pod names.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCheck the pods:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get pods\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY STATUS RESTARTS AGE\nmemcached-sample-6fd7c98d8-7dqdr 1/1 Running 0 1m\nmemcached-sample-6fd7c98d8-g5k7v 1/1 Running 0 1m\nmemcached-sample-6fd7c98d8-m7vn7 1/1 Running 0 1m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCheck the CR status:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get memcached/memcached-sample -o yaml\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: cache.example.com/v1\nkind: Memcached\nmetadata:\n...\n name: memcached-sample\n...\nspec:\n size: 3\nstatus:\n nodes:\n - memcached-sample-6fd7c98d8-7dqdr\n - memcached-sample-6fd7c98d8-g5k7v\n - memcached-sample-6fd7c98d8-m7vn7\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUpdate the deployment size.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tUpdate \u003Ccode class=\"literal\">config/samples/cache_v1_memcached.yaml\u003C/code> file to change the \u003Ccode class=\"literal\">spec.size\u003C/code> field in the \u003Ccode class=\"literal\">Memcached\u003C/code> CR from \u003Ccode class=\"literal\">3\u003C/code> to \u003Ccode class=\"literal\">5\u003C/code>:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc patch memcached memcached-sample \\\n -p '{\"spec\":{\"size\": 5}}' \\\n --type=merge\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tConfirm that the Operator changes the deployment size:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployments\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\nmemcached-operator-controller-manager 1/1 1 1 10m\nmemcached-sample 5/5 5 5 3m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tClean up the resources that have been created as part of this tutorial.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tIf you used the \u003Ccode class=\"literal\">make deploy\u003C/code> command to test the Operator, run the following command:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make undeploy\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tIf you used the \u003Ccode class=\"literal\">operator-sdk run bundle\u003C/code> command to test the Operator, run the following command:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk cleanup &lt;project_name&gt;\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section _additional-resources\" id=\"osdk-golang-tutorial-addtl-resources\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.2.7. Additional resources\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-golang-project-layout\">Project layout for Go-based Operators\u003C/a> to learn about the directory structures created by the Operator SDK.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-golang-project-layout\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.4.3. Project layout for Go-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk\u003C/code> CLI can generate, or \u003Cspan class=\"emphasis\">\u003Cem>scaffold\u003C/em>\u003C/span>, a number of packages and files for each Operator project.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-golang-project-layout_osdk-golang-project-layout\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.4.3.1. Go-based project layout\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tGo-based Operator projects, the default type, generated using the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command contain the following files and directories:\n\t\t\t\t\t\u003C/p>\u003Crh-table>\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccolgroup>\u003Ccol style=\"width: 20%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 80%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209515730048\" scope=\"col\">File or directory\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209515728960\" scope=\"col\">Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515730048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">main.go\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515728960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tMain program of the Operator. This instantiates a new manager that registers all custom resource definitions (CRDs) in the \u003Ccode class=\"literal\">apis/\u003C/code> directory and starts all controllers in the \u003Ccode class=\"literal\">controllers/\u003C/code> directory.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515730048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">apis/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515728960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tDirectory tree that defines the APIs of the CRDs. You must edit the \u003Ccode class=\"literal\">apis/&lt;version&gt;/&lt;kind&gt;_types.go\u003C/code> files to define the API for each resource type and import these packages in your controllers to watch for these resource types.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515730048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">controllers/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515728960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tController implementations. Edit the \u003Ccode class=\"literal\">controller/&lt;kind&gt;_controller.go\u003C/code> files to define the reconcile logic of the controller for handling a resource type of the specified kind.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515730048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515728960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKubernetes manifests used to deploy your controller on a cluster, including CRDs, RBAC, and certificates.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515730048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Makefile\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515728960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tTargets used to build and deploy your controller.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515730048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515728960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tInstructions used by a container engine to build your Operator.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515730048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">manifests/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515728960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKubernetes manifests for registering CRDs, setting up RBAC, and deploying the Operator as a deployment.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"ansible-based-operators\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.5. Ansible-based Operators\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-ansible-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.5.1. Getting started with Operator SDK for Ansible-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe Operator SDK includes options for generating an Operator project that leverages existing Ansible playbooks and modules to deploy Kubernetes resources as a unified application, without having to write any Go code.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tTo demonstrate the basics of setting up and running an \u003Ca class=\"link\" href=\"https://docs.ansible.com/ansible/latest/index.html\">Ansible\u003C/a>-based Operator using tools and libraries provided by the Operator SDK, Operator developers can build an example Ansible-based Operator for Memcached, a distributed key-value store, and deploy it to a cluster.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-common-prereqs_osdk-ansible-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.1.1. Prerequisites\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli\">Operator SDK CLI installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli\">OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://docs.ansible.com/ansible/2.9/index.html\">Ansible\u003C/a> version v2.9.0\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://ansible-runner.readthedocs.io/en/latest/install.html\">Ansible Runner\u003C/a> version v1.1.0+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://github.com/ansible/ansible-runner-http\">Ansible Runner HTTP Event Emitter plugin\u003C/a> version v1.0.0+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://pypi.org/project/openshift/\">OpenShift Python client\u003C/a> version v0.11.2+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tLogged into an OpenShift Container Platform 4.8 cluster with \u003Ccode class=\"literal\">oc\u003C/code> with an account that has \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tTo allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-quickstart_osdk-ansible-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.1.2. Creating and deploying Ansible-based Operators\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tYou can build and deploy a simple Ansible-based Operator for Memcached by using the Operator SDK.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create a project.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate your project directory:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ mkdir memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tChange into the project directory:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ cd memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command with the \u003Ccode class=\"literal\">ansible\u003C/code> plugin to initialize the project:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk init \\\n --plugins=ansible \\\n --domain=example.com\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create an API.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate a simple Memcached API:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk create api \\\n --group cache \\\n --version v1 \\\n --kind Memcached \\\n --generate-role \u003Cspan id=\"CO40-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO40-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\tGenerates an Ansible role for the API.\n\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Build and push the Operator image.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUse the default \u003Ccode class=\"literal\">Makefile\u003C/code> targets to build and push your Operator. Set \u003Ccode class=\"literal\">IMG\u003C/code> with a pull spec for your image that uses a registry you can push to:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Run the Operator.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tInstall the CRD:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make install\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tDeploy the project to the cluster. Set \u003Ccode class=\"literal\">IMG\u003C/code> to the image that you pushed:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create a sample custom resource (CR).\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate a sample CR:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/cache_v1_memcached.yaml \\\n -n memcached-operator-system\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tWatch for the CR to reconcile the Operator:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc logs deployment.apps/memcached-operator-controller-manager \\\n -c manager \\\n -n memcached-operator-system\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">...\nI0205 17:48:45.881666 7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator\n{\"level\":\"info\",\"ts\":1612547325.8819902,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting EventSource\",\"source\":\"kind source: cache.example.com/v1, Kind=Memcached\"}\n{\"level\":\"info\",\"ts\":1612547325.98242,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting Controller\"}\n{\"level\":\"info\",\"ts\":1612547325.9824686,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting workers\",\"worker count\":4}\n{\"level\":\"info\",\"ts\":1612547348.8311093,\"logger\":\"runner\",\"msg\":\"Ansible-runner exited successfully\",\"job\":\"4037200794235010051\",\"name\":\"memcached-sample\",\"namespace\":\"memcached-operator-system\"}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Clean up.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the following command to clean up the resources that have been created as part of this procedure:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make undeploy\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-quickstart-next-steps\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.1.3. Next steps\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-tutorial\">Operator SDK tutorial for Ansible-based Operators\u003C/a> for a more in-depth walkthrough on building an Ansible-based Operator.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.5.2. Operator SDK tutorial for Ansible-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator developers can take advantage of \u003Ca class=\"link\" href=\"https://docs.ansible.com/ansible/latest/index.html\">Ansible\u003C/a> support in the Operator SDK to build an example Ansible-based Operator for Memcached, a distributed key-value store, and manage its lifecycle. This tutorial walks through the following process:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tCreate a Memcached deployment\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tEnsure that the deployment size is the same as specified by the \u003Ccode class=\"literal\">Memcached\u003C/code> custom resource (CR) spec\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">Memcached\u003C/code> CR status using the status writer with the names of the \u003Ccode class=\"literal\">memcached\u003C/code> pods\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\tThis process is accomplished by using two centerpieces of the Operator Framework:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">Operator SDK\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk\u003C/code> CLI tool and \u003Ccode class=\"literal\">controller-runtime\u003C/code> library API\n\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">Operator Lifecycle Manager (OLM)\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tInstallation, upgrade, and role-based access control (RBAC) of Operators on a cluster\n\t\t\t\t\t\t\t\u003C/dd>\u003C/dl>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tThis tutorial goes into greater detail than \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-quickstart\">Getting started with Operator SDK for Ansible-based Operators\u003C/a>.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Csection class=\"section\" id=\"osdk-common-prereqs_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.2.1. Prerequisites\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli\">Operator SDK CLI installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli\">OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://docs.ansible.com/ansible/2.9/index.html\">Ansible\u003C/a> version v2.9.0\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://ansible-runner.readthedocs.io/en/latest/install.html\">Ansible Runner\u003C/a> version v1.1.0+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://github.com/ansible/ansible-runner-http\">Ansible Runner HTTP Event Emitter plugin\u003C/a> version v1.0.0+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://pypi.org/project/openshift/\">OpenShift Python client\u003C/a> version v0.11.2+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tLogged into an OpenShift Container Platform 4.8 cluster with \u003Ccode class=\"literal\">oc\u003C/code> with an account that has \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tTo allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-create-project_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.2.2. Creating a project\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tUse the Operator SDK CLI to create a project called \u003Ccode class=\"literal\">memcached-operator\u003C/code>.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate a directory for the project:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ mkdir -p $HOME/projects/memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tChange to the directory:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ cd $HOME/projects/memcached-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command with the \u003Ccode class=\"literal\">ansible\u003C/code> plugin to initialize the project:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk init \\\n --plugins=ansible \\\n --domain=example.com\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003Csection class=\"section\" id=\"osdk-project-file_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.2.2.1. PROJECT file\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tAmong the files generated by the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command is a Kubebuilder \u003Ccode class=\"literal\">PROJECT\u003C/code> file. Subsequent \u003Ccode class=\"literal\">operator-sdk\u003C/code> commands, as well as \u003Ccode class=\"literal\">help\u003C/code> output, that are run from the project root read this file and are aware that the project type is Ansible. For example:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">domain: example.com\nlayout: ansible.sdk.operatorframework.io/v1\nprojectName: memcached-operator\nversion: 3\u003C/pre>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-create-api-controller_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.2.3. Creating an API\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tUse the Operator SDK CLI to create a Memcached API.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the following command to create an API with group \u003Ccode class=\"literal\">cache\u003C/code>, version, \u003Ccode class=\"literal\">v1\u003C/code>, and kind \u003Ccode class=\"literal\">Memcached\u003C/code>:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk create api \\\n --group cache \\\n --version v1 \\\n --kind Memcached \\\n --generate-role \u003Cspan id=\"CO41-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO41-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\tGenerates an Ansible role for the API.\n\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAfter creating the API, your Operator project updates with the following structure:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">Memcached CRD\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\t\tIncludes a sample \u003Ccode class=\"literal\">Memcached\u003C/code> resource\n\t\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">Manager\u003C/span>\u003C/dt>\u003Cdd>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tProgram that reconciles the state of the cluster to the desired state by using:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\tA reconciler, either an Ansible role or playbook\n\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\tA \u003Ccode class=\"literal\">watches.yaml\u003C/code> file, which connects the \u003Ccode class=\"literal\">Memcached\u003C/code> resource to the \u003Ccode class=\"literal\">memcached\u003C/code> Ansible role\n\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-modify-manager_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.2.4. Modifying the manager\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tUpdate your Operator project to provide the reconcile logic, in the form of an Ansible role, which runs every time a \u003Ccode class=\"literal\">Memcached\u003C/code> resource is created, updated, or deleted.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">roles/memcached/tasks/main.yml\u003C/code> file with the following structure:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">---\n- name: start memcached\n community.kubernetes.k8s:\n definition:\n kind: Deployment\n apiVersion: apps/v1\n metadata:\n name: '{{ ansible_operator_meta.name }}-memcached'\n namespace: '{{ ansible_operator_meta.namespace }}'\n spec:\n replicas: \"{{size}}\"\n selector:\n matchLabels:\n app: memcached\n template:\n metadata:\n labels:\n app: memcached\n spec:\n containers:\n - name: memcached\n command:\n - memcached\n - -m=64\n - -o\n - modern\n - -v\n image: \"docker.io/memcached:1.4.36-alpine\"\n ports:\n - containerPort: 11211\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThis \u003Ccode class=\"literal\">memcached\u003C/code> role ensures a \u003Ccode class=\"literal\">memcached\u003C/code> deployment exist and sets the deployment size.\n\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tSet default values for variables used in your Ansible role by editing the \u003Ccode class=\"literal\">roles/memcached/defaults/main.yml\u003C/code> file:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">---\n# defaults file for Memcached\nsize: 1\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">Memcached\u003C/code> sample resource in the \u003Ccode class=\"literal\">config/samples/cache_v1_memcached.yaml\u003C/code> file with the following structure:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: cache.example.com/v1\nkind: Memcached\nmetadata:\n name: memcached-sample\nspec:\n size: 3\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThe key-value pairs in the custom resource (CR) spec are passed to Ansible as extra variables.\n\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\tThe names of all variables in the \u003Ccode class=\"literal\">spec\u003C/code> field are converted to snake case, meaning lowercase with an underscore, by the Operator before running Ansible. For example, \u003Ccode class=\"literal\">serviceAccount\u003C/code> in the spec becomes \u003Ccode class=\"literal\">service_account\u003C/code> in Ansible.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tYou can disable this case conversion by setting the \u003Ccode class=\"literal\">snakeCaseParameters\u003C/code> option to \u003Ccode class=\"literal\">false\u003C/code> in your \u003Ccode class=\"literal\">watches.yaml\u003C/code> file. It is recommended that you perform some type validation in Ansible on the variables to ensure that your application is receiving expected input.\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/section>\u003Csection class=\"section\" id=\"osdk-run-operator_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.2.5. Running the Operator\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThere are three ways you can use the Operator SDK CLI to build and run your Operator:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRun locally outside the cluster as a Go program.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRun as a deployment on the cluster.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tBundle your Operator and use Operator Lifecycle Manager (OLM) to deploy on the cluster.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"osdk-run-locally_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.2.5.1. Running locally outside the cluster\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can run your Operator project as a Go program outside of the cluster. This is useful for development purposes to speed up deployment and testing.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following command to install the custom resource definitions (CRDs) in the cluster configured in your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file and run the Operator locally:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make install run\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">...\n{\"level\":\"info\",\"ts\":1612589622.7888272,\"logger\":\"ansible-controller\",\"msg\":\"Watching resource\",\"Options.Group\":\"cache.example.com\",\"Options.Version\":\"v1\",\"Options.Kind\":\"Memcached\"}\n{\"level\":\"info\",\"ts\":1612589622.7897573,\"logger\":\"proxy\",\"msg\":\"Starting to serve\",\"Address\":\"127.0.0.1:8888\"}\n{\"level\":\"info\",\"ts\":1612589622.789971,\"logger\":\"controller-runtime.manager\",\"msg\":\"starting metrics server\",\"path\":\"/metrics\"}\n{\"level\":\"info\",\"ts\":1612589622.7899997,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting EventSource\",\"source\":\"kind source: cache.example.com/v1, Kind=Memcached\"}\n{\"level\":\"info\",\"ts\":1612589622.8904517,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting Controller\"}\n{\"level\":\"info\",\"ts\":1612589622.8905244,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting workers\",\"worker count\":8}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-run-deployment_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.2.5.2. Running as a deployment on the cluster\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can run your Operator project as a deployment on your cluster.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands to build and push the Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\tThe name and tag of the image, for example \u003Ccode class=\"literal\">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/code>, in both the commands can also be set in your Makefile. Modify the \u003Ccode class=\"literal\">IMG ?= controller:latest\u003C/code> value to set your default image name.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following command to deploy the Operator:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tBy default, this command creates a namespace with the name of your Operator project in the form \u003Ccode class=\"literal\">&lt;project_name&gt;-system\u003C/code> and is used for the deployment. This command also installs the RBAC manifests from \u003Ccode class=\"literal\">config/rbac\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tVerify that the Operator is running:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployment -n &lt;project_name&gt;-system\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\n&lt;project_name&gt;-controller-manager 1/1 1 1 8m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-bundle-deploy-olm_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.2.5.3. Bundling an Operator and deploying with Operator Lifecycle Manager\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-bundle-operator_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch6 class=\"title\">5.5.2.5.3.1. Bundling an Operator\u003C/h6>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator project initialized by using the Operator SDK\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands in your Operator project directory to build and push your Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate your Operator bundle manifest by running the \u003Ccode class=\"literal\">make bundle\u003C/code> command, which invokes several commands, including the Operator SDK \u003Ccode class=\"literal\">generate bundle\u003C/code> and \u003Ccode class=\"literal\">bundle validate\u003C/code> subcommands:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tBundle manifests for an Operator describe how to display, create, and manage an application. The \u003Ccode class=\"literal\">make bundle\u003C/code> command creates the following files and directories in your Operator project:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA bundle manifests directory named \u003Ccode class=\"literal\">bundle/manifests\u003C/code> that contains a \u003Ccode class=\"literal\">ClusterServiceVersion\u003C/code> object\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA bundle metadata directory named \u003Ccode class=\"literal\">bundle/metadata\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tAll custom resource definitions (CRDs) in a \u003Ccode class=\"literal\">config/crd\u003C/code> directory\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA Dockerfile \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tThese files are then automatically validated by using \u003Ccode class=\"literal\">operator-sdk bundle validate\u003C/code> to ensure the on-disk bundle representation is correct.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tBuild and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tBuild the bundle image. Set \u003Ccode class=\"literal\">BUNDLE_IMG\u003C/code> with the details for the registry, user namespace, and image tag where you intend to push the image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tPush the bundle image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-deploy-olm_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch6 class=\"title\">5.5.2.5.3.2. Deploying an Operator with Operator Lifecycle Manager\u003C/h6>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\t\tOperator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) for all Operator lifecycle management functions without any additional tools.\n\t\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator bundle image built and pushed to a registry\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use \u003Ccode class=\"literal\">apiextensions.k8s.io/v1\u003C/code> CRDs, for example OpenShift Container Platform 4.8)\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tLogged in to the cluster with \u003Ccode class=\"literal\">oc\u003C/code> using an account with \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tEnter the following command to run the Operator on the cluster:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk run bundle \\\n [-n &lt;namespace&gt;] \\\u003Cspan id=\"CO42-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO42-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\t\tBy default, the command installs the Operator in the currently active project in your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file. You can add the \u003Ccode class=\"literal\">-n\u003C/code> flag to set a different namespace scope for the installation.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tThis command performs the following actions:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tCreate an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tCreate a catalog source that points to your new index image, which enables OperatorHub to discover your Operator.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tDeploy your Operator to your cluster by creating an \u003Ccode class=\"literal\">OperatorGroup\u003C/code>, \u003Ccode class=\"literal\">Subscription\u003C/code>, \u003Ccode class=\"literal\">InstallPlan\u003C/code>, and all other required objects, including RBAC.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-create-cr_osdk-ansible-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.2.6. Creating a custom resource\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAfter your Operator is installed, you can test it by creating a custom resource (CR) that is now provided on the cluster by the Operator.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tExample Memcached Operator, which provides the \u003Ccode class=\"literal\">Memcached\u003C/code> CR, installed on a cluster\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tChange to the namespace where your Operator is installed. For example, if you deployed the Operator using the \u003Ccode class=\"literal\">make deploy\u003C/code> command:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc project memcached-operator-system\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tEdit the sample \u003Ccode class=\"literal\">Memcached\u003C/code> CR manifest at \u003Ccode class=\"literal\">config/samples/cache_v1_memcached.yaml\u003C/code> to contain the following specification:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: cache.example.com/v1\nkind: Memcached\nmetadata:\n name: memcached-sample\n...\nspec:\n...\n size: 3\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate the CR:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/cache_v1_memcached.yaml\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tEnsure that the \u003Ccode class=\"literal\">Memcached\u003C/code> Operator creates the deployment for the sample CR with the correct size:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployments\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\nmemcached-operator-controller-manager 1/1 1 1 8m\nmemcached-sample 3/3 3 3 1m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCheck the pods and CR status to confirm the status is updated with the Memcached pod names.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCheck the pods:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get pods\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY STATUS RESTARTS AGE\nmemcached-sample-6fd7c98d8-7dqdr 1/1 Running 0 1m\nmemcached-sample-6fd7c98d8-g5k7v 1/1 Running 0 1m\nmemcached-sample-6fd7c98d8-m7vn7 1/1 Running 0 1m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCheck the CR status:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get memcached/memcached-sample -o yaml\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: cache.example.com/v1\nkind: Memcached\nmetadata:\n...\n name: memcached-sample\n...\nspec:\n size: 3\nstatus:\n nodes:\n - memcached-sample-6fd7c98d8-7dqdr\n - memcached-sample-6fd7c98d8-g5k7v\n - memcached-sample-6fd7c98d8-m7vn7\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUpdate the deployment size.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tUpdate \u003Ccode class=\"literal\">config/samples/cache_v1_memcached.yaml\u003C/code> file to change the \u003Ccode class=\"literal\">spec.size\u003C/code> field in the \u003Ccode class=\"literal\">Memcached\u003C/code> CR from \u003Ccode class=\"literal\">3\u003C/code> to \u003Ccode class=\"literal\">5\u003C/code>:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc patch memcached memcached-sample \\\n -p '{\"spec\":{\"size\": 5}}' \\\n --type=merge\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tConfirm that the Operator changes the deployment size:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployments\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\nmemcached-operator-controller-manager 1/1 1 1 10m\nmemcached-sample 5/5 5 5 3m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tClean up the resources that have been created as part of this tutorial.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tIf you used the \u003Ccode class=\"literal\">make deploy\u003C/code> command to test the Operator, run the following command:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make undeploy\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tIf you used the \u003Ccode class=\"literal\">operator-sdk run bundle\u003C/code> command to test the Operator, run the following command:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk cleanup &lt;project_name&gt;\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section _additional-resources\" id=\"osdk-ansible-tutorial-addtl-resources\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.2.7. Additional resources\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-project-layout\">Project layout for Ansible-based Operators\u003C/a> to learn about the directory structures created by the Operator SDK.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-project-layout\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.5.3. Project layout for Ansible-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk\u003C/code> CLI can generate, or \u003Cspan class=\"emphasis\">\u003Cem>scaffold\u003C/em>\u003C/span>, a number of packages and files for each Operator project.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-ansible-project-layout_osdk-ansible-project-layout\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.3.1. Ansible-based project layout\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAnsible-based Operator projects generated using the \u003Ccode class=\"literal\">operator-sdk init --plugins ansible\u003C/code> command contain the following directories and files:\n\t\t\t\t\t\u003C/p>\u003Crh-table>\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccolgroup>\u003Ccol style=\"width: 20%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 80%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209515370688\" scope=\"col\">File or directory\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209515369600\" scope=\"col\">Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tDockerfile for building the container image for the Operator.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Makefile\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tTargets for building, publishing, deploying the container image that wraps the Operator binary, and targets for installing and uninstalling the custom resource definition (CRD).\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">PROJECT\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tYAML file containing metadata information for the Operator.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/crd\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tBase CRD files and the \u003Ccode class=\"literal\">kustomization.yaml\u003C/code> file settings.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/default\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tCollects all Operator manifests for deployment. Use by the \u003Ccode class=\"literal\">make deploy\u003C/code> command.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/manager\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tController manager deployment.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/prometheus\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">ServiceMonitor\u003C/code> resource for monitoring the Operator.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/rbac\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRole and role binding for leader election and authentication proxy.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/samples\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSample resources created for the CRDs.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config/testing\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSample configurations for testing.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">playbooks/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA subdirectory for the playbooks to run.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">roles/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSubdirectory for the roles tree to run.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">watches.yaml\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tGroup/version/kind (GVK) of the resources to watch, and the Ansible invocation method. New entries are added by using the \u003Ccode class=\"literal\">create api\u003C/code> command.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">requirements.yml\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tYAML file containing the Ansible collections and role dependencies to install during a build.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515370688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">molecule/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209515369600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tMolecule scenarios for end-to-end testing of your role and Operator.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.5.4. Ansible support in Operator SDK\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-ansible-custom-resource-files_osdk-ansible-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.4.1. Custom resource files\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOperators use the Kubernetes extension mechanism, custom resource definitions (CRDs), so your custom resource (CR) looks and acts just like the built-in, native Kubernetes objects.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tThe CR file format is a Kubernetes resource file. The object has mandatory and optional fields:\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209487797264\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.1. Custom resource fields\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 30%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 70%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487792432\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487791344\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487792432\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">apiVersion\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487791344\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tVersion of the CR to be created.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487792432\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487791344\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKind of the CR to be created.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487792432\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">metadata\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487791344\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKubernetes-specific metadata to be created.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487792432\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec\u003C/code> (optional)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487791344\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKey-value list of variables which are passed to Ansible. This field is empty by default.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487792432\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">status\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487791344\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSummarizes the current state of the object. For Ansible-based Operators, the \u003Ca class=\"link\" href=\"https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource\">\u003Ccode class=\"literal\">status\u003C/code> subresource\u003C/a> is enabled for CRDs and managed by the \u003Ccode class=\"literal\">operator_sdk.util.k8s_status\u003C/code> Ansible module by default, which includes \u003Ccode class=\"literal\">condition\u003C/code> information to the CR \u003Ccode class=\"literal\">status\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487792432\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">annotations\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487791344\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKubernetes-specific annotations to be appended to the CR.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\t\tThe following list of CR annotations modify the behavior of the Operator:\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209487761008\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.2. Ansible-based Operator annotations\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 30%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 70%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487756160\" scope=\"col\">Annotation\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487755072\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487756160\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">ansible.operator-sdk/reconcile-period\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487755072\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSpecifies the reconciliation interval for the CR. This value is parsed using the standard Golang package \u003Ca class=\"link\" href=\"https://golang.org/pkg/time/\">\u003Ccode class=\"literal\">time\u003C/code>\u003C/a>. Specifically, \u003Ca class=\"link\" href=\"https://golang.org/pkg/time/#ParseDuration\">\u003Ccode class=\"literal\">ParseDuration\u003C/code>\u003C/a> is used which applies the default suffix of \u003Ccode class=\"literal\">s\u003C/code>, giving the value in seconds.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example Ansible-based Operator annotation\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: \"test1.example.com/v1alpha1\"\nkind: \"Test1\"\nmetadata:\n name: \"example\"\nannotations:\n ansible.operator-sdk/reconcile-period: \"30s\"\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-watches-file_osdk-ansible-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.4.2. watches.yaml file\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tA \u003Cspan class=\"emphasis\">\u003Cem>group/version/kind (GVK)\u003C/em>\u003C/span> is a unique identifier for a Kubernetes API. The \u003Ccode class=\"literal\">watches.yaml\u003C/code> file contains a list of mappings from custom resources (CRs), identified by its GVK, to an Ansible role or playbook. The Operator expects this mapping file in a predefined location at \u003Ccode class=\"literal\">/opt/ansible/watches.yaml\u003C/code>.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209487739776\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.3. watches.yaml file mappings\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 30%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 70%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487734624\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487733536\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487734624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">group\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487733536\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tGroup of CR to watch.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487734624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">version\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487733536\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tVersion of CR to watch.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487734624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487733536\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKind of CR to watch\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487734624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">role\u003C/code> (default)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487733536\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tPath to the Ansible role added to the container. For example, if your \u003Ccode class=\"literal\">roles\u003C/code> directory is at \u003Ccode class=\"literal\">/opt/ansible/roles/\u003C/code> and your role is named \u003Ccode class=\"literal\">busybox\u003C/code>, this value would be \u003Ccode class=\"literal\">/opt/ansible/roles/busybox\u003C/code>. This field is mutually exclusive with the \u003Ccode class=\"literal\">playbook\u003C/code> field.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487734624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">playbook\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487733536\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tPath to the Ansible playbook added to the container. This playbook is expected to be a way to call roles. This field is mutually exclusive with the \u003Ccode class=\"literal\">role\u003C/code> field.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487734624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">reconcilePeriod\u003C/code> (optional)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487733536\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe reconciliation interval, how often the role or playbook is run, for a given CR.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487734624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">manageStatus\u003C/code> (optional)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487733536\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tWhen set to \u003Ccode class=\"literal\">true\u003C/code> (default), the Operator manages the status of the CR generically. When set to \u003Ccode class=\"literal\">false\u003C/code>, the status of the CR is managed elsewhere, by the specified role or playbook or in a separate controller.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example \u003Ccode class=\"literal\">watches.yaml\u003C/code> file\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">- version: v1alpha1 \u003Cspan id=\"CO43-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n group: test1.example.com\n kind: Test1\n role: /opt/ansible/roles/Test1\n\n- version: v1alpha1 \u003Cspan id=\"CO43-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\n group: test2.example.com\n kind: Test2\n playbook: /opt/ansible/playbook.yml\n\n- version: v1alpha1 \u003Cspan id=\"CO43-3\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">3\u003C/span>\n group: test3.example.com\n kind: Test3\n playbook: /opt/ansible/test3.yml\n reconcilePeriod: 0\n manageStatus: false\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO43-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\tSimple example mapping \u003Ccode class=\"literal\">Test1\u003C/code> to the \u003Ccode class=\"literal\">test1\u003C/code> role.\n\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO43-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\tSimple example mapping \u003Ccode class=\"literal\">Test2\u003C/code> to a playbook.\n\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO43-3\">\u003Cspan class=\"callout\">3\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\tMore complex example for the \u003Ccode class=\"literal\">Test3\u003C/code> kind. Disables re-queuing and managing the CR status in the playbook.\n\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Csection class=\"section\" id=\"osdk-ansible-watches-file-advanced_osdk-ansible-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.4.2.1. Advanced options\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tAdvanced features can be enabled by adding them to your \u003Ccode class=\"literal\">watches.yaml\u003C/code> file per GVK. They can go below the \u003Ccode class=\"literal\">group\u003C/code>, \u003Ccode class=\"literal\">version\u003C/code>, \u003Ccode class=\"literal\">kind\u003C/code> and \u003Ccode class=\"literal\">playbook\u003C/code> or \u003Ccode class=\"literal\">role\u003C/code> fields.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tSome features can be overridden per resource using an annotation on that CR. The options that can be overridden have the annotation specified below.\n\t\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209487680800\">\u003Ctable class=\"gt-4-cols lt-7-rows\">\u003Ccaption>Table 5.4. Advanced watches.yaml file options\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 17%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 33%; \" class=\"col_3\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 17%; \" class=\"col_4\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 8%; \" class=\"col_5\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487673168\" scope=\"col\">Feature\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487672080\" scope=\"col\">YAML key\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487670992\" scope=\"col\">Description\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487669904\" scope=\"col\">Annotation for override\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487668816\" scope=\"col\">Default value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487673168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tReconcile period\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487672080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">reconcilePeriod\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487670992\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tTime between reconcile runs for a particular CR.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487669904\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">ansible.operator-sdk/reconcile-period\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487668816\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">1m\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487673168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tManage status\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487672080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">manageStatus\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487670992\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tAllows the Operator to manage the \u003Ccode class=\"literal\">conditions\u003C/code> section of each CR \u003Ccode class=\"literal\">status\u003C/code> section.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487669904\"> \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487668816\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">true\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487673168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tWatch dependent resources\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487672080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">watchDependentResources\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487670992\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tAllows the Operator to dynamically watch resources that are created by Ansible.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487669904\"> \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487668816\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">true\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487673168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tWatch cluster-scoped resources\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487672080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">watchClusterScopedResources\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487670992\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tAllows the Operator to watch cluster-scoped resources that are created by Ansible.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487669904\"> \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487668816\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">false\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487673168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tMax runner artifacts\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487672080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">maxRunnerArtifacts\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487670992\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tManages the number of \u003Ca class=\"link\" href=\"https://ansible-runner.readthedocs.io/en/latest/intro.html#runner-artifacts-directory-hierarchy\">artifact directories\u003C/a> that Ansible Runner keeps in the Operator container for each individual resource.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487669904\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">ansible.operator-sdk/max-runner-artifacts\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487668816\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">20\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example watches.yml file with advanced options\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">- version: v1alpha1\n group: app.example.com\n kind: AppService\n playbook: /opt/ansible/playbook.yml\n maxRunnerArtifacts: 30\n reconcilePeriod: 5s\n manageStatus: False\n watchDependentResources: False\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-extra-variables_osdk-ansible-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.4.3. Extra variables sent to Ansible\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tExtra variables can be sent to Ansible, which are then managed by the Operator. The \u003Ccode class=\"literal\">spec\u003C/code> section of the custom resource (CR) passes along the key-value pairs as extra variables. This is equivalent to extra variables passed in to the \u003Ccode class=\"literal\">ansible-playbook\u003C/code> command.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tThe Operator also passes along additional variables under the \u003Ccode class=\"literal\">meta\u003C/code> field for the name of the CR and the namespace of the CR.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tFor the following CR example:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: \"app.example.com/v1alpha1\"\nkind: \"Database\"\nmetadata:\n name: \"example\"\nspec:\n message: \"Hello world 2\"\n newParameter: \"newParam\"\u003C/pre>\u003Cp>\n\t\t\t\t\t\tThe structure passed to Ansible as extra variables is:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-json\">{ \"meta\": {\n \"name\": \"&lt;cr_name&gt;\",\n \"namespace\": \"&lt;cr_namespace&gt;\",\n },\n \"message\": \"Hello world 2\",\n \"new_parameter\": \"newParam\",\n \"_app_example_com_database\": {\n &lt;full_crd&gt;\n },\n}\u003C/pre>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">message\u003C/code> and \u003Ccode class=\"literal\">newParameter\u003C/code> fields are set in the top level as extra variables, and \u003Ccode class=\"literal\">meta\u003C/code> provides the relevant metadata for the CR as defined in the Operator. The \u003Ccode class=\"literal\">meta\u003C/code> fields can be accessed using dot notation in Ansible, for example:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">---\n- debug:\n msg: \"name: {{ ansible_operator_meta.name }}, {{ ansible_operator_meta.namespace }}\"\u003C/pre>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-runner-directory_osdk-ansible-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.4.4. Ansible Runner directory\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAnsible Runner keeps information about Ansible runs in the container. This is located at \u003Ccode class=\"literal\">/tmp/ansible-operator/runner/&lt;group&gt;/&lt;version&gt;/&lt;kind&gt;/&lt;namespace&gt;/&lt;name&gt;\u003C/code>.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tTo learn more about the \u003Ccode class=\"literal\">runner\u003C/code> directory, see the \u003Ca class=\"link\" href=\"https://ansible-runner.readthedocs.io/en/latest/index.html\">Ansible Runner documentation\u003C/a>.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-k8s-collection\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.5.5. Kubernetes Collection for Ansible\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tTo manage the lifecycle of your application on Kubernetes using Ansible, you can use the \u003Ca class=\"link\" href=\"https://galaxy.ansible.com/community/kubernetes\">Kubernetes Collection for Ansible\u003C/a>. This collection of Ansible modules allows a developer to either leverage their existing Kubernetes resource files written in YAML or express the lifecycle management in native Ansible.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tOne of the biggest benefits of using Ansible in conjunction with existing Kubernetes resource files is the ability to use Jinja templating so that you can customize resources with the simplicity of a few variables in Ansible.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThis section goes into detail on usage of the Kubernetes Collection. To get started, install the collection on your local workstation and test it using a playbook before moving on to using it within an Operator.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-ansible-installing-k8s-collection_osdk-ansible-k8s-collection\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.5.1. Installing the Kubernetes Collection for Ansible\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tYou can install the Kubernetes Collection for Ansible on your local workstation.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tInstall Ansible 2.9+:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ sudo dnf install ansible\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tInstall the \u003Ca class=\"link\" href=\"https://github.com/openshift/openshift-restclient-python\">OpenShift python client\u003C/a> package:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ pip3 install openshift\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tInstall the Kubernetes Collection using one of the following methods:\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tYou can install the collection directly from Ansible Galaxy:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ ansible-galaxy collection install community.kubernetes\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tIf you have already initialized your Operator, you might have a \u003Ccode class=\"literal\">requirements.yml\u003C/code> file at the top level of your project. This file specifies Ansible dependencies that must be installed for your Operator to function. By default, this file installs the \u003Ccode class=\"literal\">community.kubernetes\u003C/code> collection as well as the \u003Ccode class=\"literal\">operator_sdk.util\u003C/code> collection, which provides modules and plugins for Operator-specific fuctions.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tTo install the dependent modules from the \u003Ccode class=\"literal\">requirements.yml\u003C/code> file:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ ansible-galaxy collection install -r requirements.yml\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-k8s-local_osdk-ansible-k8s-collection\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.5.2. Testing the Kubernetes Collection locally\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOperator developers can run the Ansible code from their local machine as opposed to running and rebuilding the Operator each time.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tInitialize an Ansible-based Operator project and create an API that has a generated Ansible role by using the Operator SDK\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tInstall the Kubernetes Collection for Ansible\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tIn your Ansible-based Operator project directory, modify the \u003Ccode class=\"literal\">roles/&lt;kind&gt;/tasks/main.yml\u003C/code> file with the Ansible logic that you want. The \u003Ccode class=\"literal\">roles/&lt;kind&gt;/\u003C/code> directory is created when you use the \u003Ccode class=\"literal\">--generate-role\u003C/code> flag while creating an API. The \u003Ccode class=\"literal\">&lt;kind&gt;\u003C/code> replaceable matches the kind that you specified for the API.\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThe following example creates and deletes a config map based on the value of a variable named \u003Ccode class=\"literal\">state\u003C/code>:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">---\n- name: set ConfigMap example-config to {{ state }}\n community.kubernetes.k8s:\n api_version: v1\n kind: ConfigMap\n name: example-config\n namespace: default \u003Cspan id=\"CO44-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n state: \"{{ state }}\"\n ignore_errors: true \u003Cspan id=\"CO44-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO44-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\tChange this value if you want the config map to be created in a different namespace from \u003Ccode class=\"literal\">default\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO44-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\tSetting \u003Ccode class=\"literal\">ignore_errors: true\u003C/code> ensures that deleting a nonexistent config map does not fail.\n\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tModify the \u003Ccode class=\"literal\">roles/&lt;kind&gt;/defaults/main.yml\u003C/code> file to set \u003Ccode class=\"literal\">state\u003C/code> to \u003Ccode class=\"literal\">present\u003C/code> by default:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">---\nstate: present\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate an Ansible playbook by creating a \u003Ccode class=\"literal\">playbook.yml\u003C/code> file in the top-level of your project directory, and include your \u003Ccode class=\"literal\">&lt;kind&gt;\u003C/code> role:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">---\n- hosts: localhost\n roles:\n - &lt;kind&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the playbook:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ ansible-playbook playbook.yml\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'\n\nPLAY [localhost] ********************************************************************************\n\nTASK [Gathering Facts] ********************************************************************************\nok: [localhost]\n\nTASK [memcached : set ConfigMap example-config to present] ********************************************************************************\nchanged: [localhost]\n\nPLAY RECAP ********************************************************************************\nlocalhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tVerify that the config map was created:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get configmaps\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME DATA AGE\nexample-config 0 2m1s\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRerun the playbook setting \u003Ccode class=\"literal\">state\u003C/code> to \u003Ccode class=\"literal\">absent\u003C/code>:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ ansible-playbook playbook.yml --extra-vars state=absent\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'\n\nPLAY [localhost] ********************************************************************************\n\nTASK [Gathering Facts] ********************************************************************************\nok: [localhost]\n\nTASK [memcached : set ConfigMap example-config to absent] ********************************************************************************\nchanged: [localhost]\n\nPLAY RECAP ********************************************************************************\nlocalhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tVerify that the config map was deleted:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get configmaps\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-k8s-collection-next-steps\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.5.3. Next steps\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-inside-operator\">Using Ansible inside an Operator\u003C/a> for details on triggering your custom Ansible logic inside of an Operator when a custom resource (CR) changes.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.5.6. Using Ansible inside an Operator\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tAfter you are familiar with \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-ansible-k8s-collection\">using the Kubernetes Collection for Ansible locally\u003C/a>, you can trigger the same Ansible logic inside of an Operator when a custom resource (CR) changes. This example maps an Ansible role to a specific Kubernetes resource that the Operator watches. This mapping is done in the \u003Ccode class=\"literal\">watches.yaml\u003C/code> file.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-ansible-custom-resource-files_osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.6.1. Custom resource files\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOperators use the Kubernetes extension mechanism, custom resource definitions (CRDs), so your custom resource (CR) looks and acts just like the built-in, native Kubernetes objects.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tThe CR file format is a Kubernetes resource file. The object has mandatory and optional fields:\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209487522880\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.5. Custom resource fields\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 30%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 70%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487518048\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487516960\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487518048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">apiVersion\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487516960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tVersion of the CR to be created.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487518048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487516960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKind of the CR to be created.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487518048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">metadata\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487516960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKubernetes-specific metadata to be created.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487518048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec\u003C/code> (optional)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487516960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKey-value list of variables which are passed to Ansible. This field is empty by default.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487518048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">status\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487516960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSummarizes the current state of the object. For Ansible-based Operators, the \u003Ca class=\"link\" href=\"https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource\">\u003Ccode class=\"literal\">status\u003C/code> subresource\u003C/a> is enabled for CRDs and managed by the \u003Ccode class=\"literal\">operator_sdk.util.k8s_status\u003C/code> Ansible module by default, which includes \u003Ccode class=\"literal\">condition\u003C/code> information to the CR \u003Ccode class=\"literal\">status\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487518048\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">annotations\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487516960\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tKubernetes-specific annotations to be appended to the CR.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\t\tThe following list of CR annotations modify the behavior of the Operator:\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209487486640\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.6. Ansible-based Operator annotations\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 30%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 70%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487481792\" scope=\"col\">Annotation\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487480704\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487481792\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">ansible.operator-sdk/reconcile-period\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487480704\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSpecifies the reconciliation interval for the CR. This value is parsed using the standard Golang package \u003Ca class=\"link\" href=\"https://golang.org/pkg/time/\">\u003Ccode class=\"literal\">time\u003C/code>\u003C/a>. Specifically, \u003Ca class=\"link\" href=\"https://golang.org/pkg/time/#ParseDuration\">\u003Ccode class=\"literal\">ParseDuration\u003C/code>\u003C/a> is used which applies the default suffix of \u003Ccode class=\"literal\">s\u003C/code>, giving the value in seconds.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example Ansible-based Operator annotation\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: \"test1.example.com/v1alpha1\"\nkind: \"Test1\"\nmetadata:\n name: \"example\"\nannotations:\n ansible.operator-sdk/reconcile-period: \"30s\"\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-inside-operator-local_osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.6.2. Testing an Ansible-based Operator locally\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tYou can test the logic inside of an Ansible-based Operator running locally by using the \u003Ccode class=\"literal\">make run\u003C/code> command from the top-level directory of your Operator project. The \u003Ccode class=\"literal\">make run\u003C/code> Makefile target runs the \u003Ccode class=\"literal\">ansible-operator\u003C/code> binary locally, which reads from the \u003Ccode class=\"literal\">watches.yaml\u003C/code> file and uses your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file to communicate with a Kubernetes cluster just as the \u003Ccode class=\"literal\">k8s\u003C/code> modules do.\n\t\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\tYou can customize the roles path by setting the environment variable \u003Ccode class=\"literal\">ANSIBLE_ROLES_PATH\u003C/code> or by using the \u003Ccode class=\"literal\">ansible-roles-path\u003C/code> flag. If the role is not found in the \u003Ccode class=\"literal\">ANSIBLE_ROLES_PATH\u003C/code> value, the Operator looks for it in \u003Ccode class=\"literal\">{{current directory}}/roles\u003C/code>.\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://ansible-runner.readthedocs.io/en/latest/install.html\">Ansible Runner\u003C/a> version v1.1.0+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://github.com/ansible/ansible-runner-http\">Ansible Runner HTTP Event Emitter plugin\u003C/a> version v1.0.0+\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tPerformed the previous steps for testing the Kubernetes Collection locally\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tInstall your custom resource definition (CRD) and proper role-based access control (RBAC) definitions for your custom resource (CR):\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make install\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">/usr/bin/kustomize build config/crd | kubectl apply -f -\ncustomresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">make run\u003C/code> command:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make run\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">/home/user/memcached-operator/bin/ansible-operator run\n{\"level\":\"info\",\"ts\":1612739145.2871568,\"logger\":\"cmd\",\"msg\":\"Version\",\"Go Version\":\"go1.15.5\",\"GOOS\":\"linux\",\"GOARCH\":\"amd64\",\"ansible-operator\":\"v1.8.0\",\"commit\":\"1abf57985b43bf6a59dcd18147b3c574fa57d3f6\"}\n...\n{\"level\":\"info\",\"ts\":1612739148.347306,\"logger\":\"controller-runtime.metrics\",\"msg\":\"metrics server is starting to listen\",\"addr\":\":8080\"}\n{\"level\":\"info\",\"ts\":1612739148.3488882,\"logger\":\"watches\",\"msg\":\"Environment variable not set; using default value\",\"envVar\":\"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM\",\"default\":2}\n{\"level\":\"info\",\"ts\":1612739148.3490262,\"logger\":\"cmd\",\"msg\":\"Environment variable not set; using default value\",\"Namespace\":\"\",\"envVar\":\"ANSIBLE_DEBUG_LOGS\",\"ANSIBLE_DEBUG_LOGS\":false}\n{\"level\":\"info\",\"ts\":1612739148.3490646,\"logger\":\"ansible-controller\",\"msg\":\"Watching resource\",\"Options.Group\":\"cache.example.com\",\"Options.Version\":\"v1\",\"Options.Kind\":\"Memcached\"}\n{\"level\":\"info\",\"ts\":1612739148.350217,\"logger\":\"proxy\",\"msg\":\"Starting to serve\",\"Address\":\"127.0.0.1:8888\"}\n{\"level\":\"info\",\"ts\":1612739148.3506632,\"logger\":\"controller-runtime.manager\",\"msg\":\"starting metrics server\",\"path\":\"/metrics\"}\n{\"level\":\"info\",\"ts\":1612739148.350784,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting EventSource\",\"source\":\"kind source: cache.example.com/v1, Kind=Memcached\"}\n{\"level\":\"info\",\"ts\":1612739148.5511978,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting Controller\"}\n{\"level\":\"info\",\"ts\":1612739148.5512562,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting workers\",\"worker count\":8}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tWith the Operator now watching your CR for events, the creation of a CR will trigger your Ansible role to run.\n\t\t\t\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\tConsider an example \u003Ccode class=\"literal\">config/samples/&lt;gvk&gt;.yaml\u003C/code> CR manifest:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: &lt;group&gt;.example.com/v1alpha1\nkind: &lt;kind&gt;\nmetadata:\n name: \"&lt;kind&gt;-sample\"\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\t\t\tBecause the \u003Ccode class=\"literal\">spec\u003C/code> field is not set, Ansible is invoked with no extra variables. Passing extra variables from a CR to Ansible is covered in another section. It is important to set reasonable defaults for the Operator.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate an instance of your CR with the default variable \u003Ccode class=\"literal\">state\u003C/code> set to \u003Ccode class=\"literal\">present\u003C/code>:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/&lt;gvk&gt;.yaml\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCheck that the \u003Ccode class=\"literal\">example-config\u003C/code> config map was created:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get configmaps\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME STATUS AGE\nexample-config Active 3s\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tModify your \u003Ccode class=\"literal\">config/samples/&lt;gvk&gt;.yaml\u003C/code> file to set the \u003Ccode class=\"literal\">state\u003C/code> field to \u003Ccode class=\"literal\">absent\u003C/code>. For example:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: cache.example.com/v1\nkind: Memcached\nmetadata:\n name: memcached-sample\nspec:\n state: absent\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tApply the changes:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/&lt;gvk&gt;.yaml\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tConfirm that the config map is deleted:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get configmap\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-run-deployment_osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.6.3. Testing an Ansible-based Operator on the cluster\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAfter you have tested your custom Ansible logic locally inside of an Operator, you can test the Operator inside of a pod on an OpenShift Container Platform cluster, which is prefered for production use.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tYou can run your Operator project as a deployment on your cluster.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands to build and push the Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tThe name and tag of the image, for example \u003Ccode class=\"literal\">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/code>, in both the commands can also be set in your Makefile. Modify the \u003Ccode class=\"literal\">IMG ?= controller:latest\u003C/code> value to set your default image name.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the following command to deploy the Operator:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tBy default, this command creates a namespace with the name of your Operator project in the form \u003Ccode class=\"literal\">&lt;project_name&gt;-system\u003C/code> and is used for the deployment. This command also installs the RBAC manifests from \u003Ccode class=\"literal\">config/rbac\u003C/code>.\n\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tVerify that the Operator is running:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployment -n &lt;project_name&gt;-system\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\n&lt;project_name&gt;-controller-manager 1/1 1 1 8m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-inside-operator-logs_osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.6.4. Ansible logs\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAnsible-based Operators provide logs about the Ansible run, which can be useful for debugging your Ansible tasks. The logs can also contain detailed information about the internals of the Operator and its interactions with Kubernetes.\n\t\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-ansible-inside-operator-logs-view_osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.6.4.1. Viewing Ansible logs\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tAnsible-based Operator running as a deployment on a cluster\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tTo view logs from an Ansible-based Operator, run the following command:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc logs deployment/&lt;project_name&gt;-controller-manager \\\n -c manager \\\u003Cspan id=\"CO45-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n -n &lt;namespace&gt; \u003Cspan id=\"CO45-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO45-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tView logs from the \u003Ccode class=\"literal\">manager\u003C/code> container.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO45-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tIf you used the \u003Ccode class=\"literal\">make deploy\u003C/code> command to run the Operator as a deployment, use the \u003Ccode class=\"literal\">&lt;project_name&gt;-system\u003C/code> namespace.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">{\"level\":\"info\",\"ts\":1612732105.0579333,\"logger\":\"cmd\",\"msg\":\"Version\",\"Go Version\":\"go1.15.5\",\"GOOS\":\"linux\",\"GOARCH\":\"amd64\",\"ansible-operator\":\"v1.8.0\",\"commit\":\"1abf57985b43bf6a59dcd18147b3c574fa57d3f6\"}\n{\"level\":\"info\",\"ts\":1612732105.0587437,\"logger\":\"cmd\",\"msg\":\"WATCH_NAMESPACE environment variable not set. Watching all namespaces.\",\"Namespace\":\"\"}\nI0207 21:08:26.110949 7 request.go:645] Throttling request took 1.035521578s, request: GET:https://172.30.0.1:443/apis/flowcontrol.apiserver.k8s.io/v1alpha1?timeout=32s\n{\"level\":\"info\",\"ts\":1612732107.768025,\"logger\":\"controller-runtime.metrics\",\"msg\":\"metrics server is starting to listen\",\"addr\":\"127.0.0.1:8080\"}\n{\"level\":\"info\",\"ts\":1612732107.768796,\"logger\":\"watches\",\"msg\":\"Environment variable not set; using default value\",\"envVar\":\"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM\",\"default\":2}\n{\"level\":\"info\",\"ts\":1612732107.7688773,\"logger\":\"cmd\",\"msg\":\"Environment variable not set; using default value\",\"Namespace\":\"\",\"envVar\":\"ANSIBLE_DEBUG_LOGS\",\"ANSIBLE_DEBUG_LOGS\":false}\n{\"level\":\"info\",\"ts\":1612732107.7688901,\"logger\":\"ansible-controller\",\"msg\":\"Watching resource\",\"Options.Group\":\"cache.example.com\",\"Options.Version\":\"v1\",\"Options.Kind\":\"Memcached\"}\n{\"level\":\"info\",\"ts\":1612732107.770032,\"logger\":\"proxy\",\"msg\":\"Starting to serve\",\"Address\":\"127.0.0.1:8888\"}\nI0207 21:08:27.770185 7 leaderelection.go:243] attempting to acquire leader lease memcached-operator-system/memcached-operator...\n{\"level\":\"info\",\"ts\":1612732107.770202,\"logger\":\"controller-runtime.manager\",\"msg\":\"starting metrics server\",\"path\":\"/metrics\"}\nI0207 21:08:27.784854 7 leaderelection.go:253] successfully acquired lease memcached-operator-system/memcached-operator\n{\"level\":\"info\",\"ts\":1612732107.7850506,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting EventSource\",\"source\":\"kind source: cache.example.com/v1, Kind=Memcached\"}\n{\"level\":\"info\",\"ts\":1612732107.8853772,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting Controller\"}\n{\"level\":\"info\",\"ts\":1612732107.8854098,\"logger\":\"controller-runtime.manager.controller.memcached-controller\",\"msg\":\"Starting workers\",\"worker count\":4}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-inside-operator-logs-full-result_osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.6.4.2. Enabling full Ansible results in logs\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can set the environment variable \u003Ccode class=\"literal\">ANSIBLE_DEBUG_LOGS\u003C/code> to \u003Ccode class=\"literal\">True\u003C/code> to enable checking the full Ansible result in logs, which can be helpful when debugging.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tEdit the \u003Ccode class=\"literal\">config/manager/manager.yaml\u003C/code> and \u003Ccode class=\"literal\">config/default/manager_auth_proxy_patch.yaml\u003C/code> files to include the following configuration:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\"> containers:\n - name: manager\n env:\n - name: ANSIBLE_DEBUG_LOGS\n value: \"True\"\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-inside-operator-logs-verbose_osdk-ansible-inside-operator\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.5.6.4.3. Enabling verbose debugging in logs\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tWhile developing an Ansible-based Operator, it can be helpful to enable additional debugging in logs.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAdd the \u003Ccode class=\"literal\">ansible.sdk.operatorframework.io/verbosity\u003C/code> annotation to your custom resource to enable the verbosity level that you want. For example:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">apiVersion: \"cache.example.com/v1alpha1\"\nkind: \"Memcached\"\nmetadata:\n name: \"example-memcached\"\n annotations:\n \"ansible.sdk.operatorframework.io/verbosity\": \"4\"\nspec:\n size: 4\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-cr-status\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.5.7. Custom resource status management\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-ansible-cr-status-about_osdk-ansible-cr-mgmt\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.7.1. About custom resource status in Ansible-based Operators\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAnsible-based Operators automatically update custom resource (CR) \u003Ca class=\"link\" href=\"https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource\">\u003Ccode class=\"literal\">status\u003C/code> subresources\u003C/a> with generic information about the previous Ansible run. This includes the number of successful and failed tasks and relevant error messages as shown:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">status:\n conditions:\n - ansibleResult:\n changed: 3\n completion: 2018-12-03T13:45:57.13329\n failures: 1\n ok: 6\n skipped: 0\n lastTransitionTime: 2018-12-03T13:45:57Z\n message: 'Status code was -1 and not [200]: Request failed: &lt;urlopen error [Errno\n 113] No route to host&gt;'\n reason: Failed\n status: \"True\"\n type: Failure\n - lastTransitionTime: 2018-12-03T13:46:13Z\n message: Running reconciliation\n reason: Running\n status: \"True\"\n type: Running\u003C/pre>\u003Cp>\n\t\t\t\t\t\tAnsible-based Operators also allow Operator authors to supply custom status values with the \u003Ccode class=\"literal\">k8s_status\u003C/code> Ansible module, which is included in the \u003Ca class=\"link\" href=\"https://galaxy.ansible.com/operator_sdk/util\">\u003Ccode class=\"literal\">operator_sdk.util\u003C/code> collection\u003C/a>. This allows the author to update the \u003Ccode class=\"literal\">status\u003C/code> from within Ansible with any key-value pair as desired.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tBy default, Ansible-based Operators always include the generic Ansible run output as shown above. If you would prefer your application did \u003Cspan class=\"emphasis\">\u003Cem>not\u003C/em>\u003C/span> update the status with Ansible output, you can track the status manually from your application.\n\t\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-ansible-cr-status-manual_osdk-ansible-cr-mgmt\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.5.7.2. Tracking custom resource status manually\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tYou can use the \u003Ccode class=\"literal\">operator_sdk.util\u003C/code> collection to modify your Ansible-based Operator to track custom resource (CR) status manually from your application.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tAnsible-based Operator project created by using the Operator SDK\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">watches.yaml\u003C/code> file with a \u003Ccode class=\"literal\">manageStatus\u003C/code> field set to \u003Ccode class=\"literal\">false\u003C/code>:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">- version: v1\n group: api.example.com\n kind: &lt;kind&gt;\n role: &lt;role&gt;\n manageStatus: false\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUse the \u003Ccode class=\"literal\">operator_sdk.util.k8s_status\u003C/code> Ansible module to update the subresource. For example, to update with key \u003Ccode class=\"literal\">test\u003C/code> and value \u003Ccode class=\"literal\">data\u003C/code>, \u003Ccode class=\"literal\">operator_sdk.util\u003C/code> can be used as shown:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">- operator_sdk.util.k8s_status:\n api_version: app.example.com/v1\n kind: &lt;kind&gt;\n name: \"{{ ansible_operator_meta.name }}\"\n namespace: \"{{ ansible_operator_meta.namespace }}\"\n status:\n test: data\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tYou can declare collections in the \u003Ccode class=\"literal\">meta/main.yml\u003C/code> file for the role, which is included for scaffolded Ansible-based Operators:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">collections:\n - operator_sdk.util\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tAfter declaring collections in the role meta, you can invoke the \u003Ccode class=\"literal\">k8s_status\u003C/code> module directly:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">k8s_status:\n ...\n status:\n key1: value1\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"helm-based-operators\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.6. Helm-based Operators\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-helm-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.6.1. Getting started with Operator SDK for Helm-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe Operator SDK includes options for generating an Operator project that leverages existing \u003Ca class=\"link\" href=\"https://helm.sh/docs/\">Helm\u003C/a> charts to deploy Kubernetes resources as a unified application, without having to write any Go code.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tTo demonstrate the basics of setting up and running an \u003Ca class=\"link\" href=\"https://helm.sh/docs/\">Helm\u003C/a>-based Operator using tools and libraries provided by the Operator SDK, Operator developers can build an example Helm-based Operator for Nginx and deploy it to a cluster.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-common-prereqs_osdk-helm-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.1.1. Prerequisites\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli\">Operator SDK CLI installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli\">OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tLogged into an OpenShift Container Platform 4.8 cluster with \u003Ccode class=\"literal\">oc\u003C/code> with an account that has \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tTo allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-quickstart_osdk-helm-quickstart\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.1.2. Creating and deploying Helm-based Operators\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tYou can build and deploy a simple Helm-based Operator for Nginx by using the Operator SDK.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create a project.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate your project directory:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ mkdir nginx-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tChange into the project directory:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ cd nginx-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command with the \u003Ccode class=\"literal\">helm\u003C/code> plugin to initialize the project:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk init \\\n --plugins=helm\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create an API.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate a simple Nginx API:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk create api \\\n --group demo \\\n --version v1 \\\n --kind Nginx\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThis API uses the built-in Helm chart boilerplate from the \u003Ccode class=\"literal\">helm create\u003C/code> command.\n\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Build and push the Operator image.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUse the default \u003Ccode class=\"literal\">Makefile\u003C/code> targets to build and push your Operator. Set \u003Ccode class=\"literal\">IMG\u003C/code> with a pull spec for your image that uses a registry you can push to:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Run the Operator.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tInstall the CRD:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make install\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tDeploy the project to the cluster. Set \u003Ccode class=\"literal\">IMG\u003C/code> to the image that you pushed:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Add a security context constraint (SCC).\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThe Nginx service account requires privileged access to run in OpenShift Container Platform. Add the following SCC to the service account for the \u003Ccode class=\"literal\">nginx-sample\u003C/code> pod:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc adm policy add-scc-to-user \\\n anyuid system:serviceaccount:nginx-operator-system:nginx-sample\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Create a sample custom resource (CR).\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate a sample CR:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/demo_v1_nginx.yaml \\\n -n nginx-operator-system\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tWatch for the CR to reconcile the Operator:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc logs deployment.apps/nginx-operator-controller-manager \\\n -c manager \\\n -n nginx-operator-system\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\u003Cspan class=\"strong strong\">\u003Cstrong>Clean up.\u003C/strong>\u003C/span>\n\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the following command to clean up the resources that have been created as part of this procedure:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make undeploy\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-helm-quickstart-next-steps\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.1.3. Next steps\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-helm-tutorial\">Operator SDK tutorial for Helm-based Operators\u003C/a> for a more in-depth walkthrough on building a Helm-based Operator.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.6.2. Operator SDK tutorial for Helm-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator developers can take advantage of \u003Ca class=\"link\" href=\"https://helm.sh/docs/\">Helm\u003C/a> support in the Operator SDK to build an example Helm-based Operator for Nginx and manage its lifecycle. This tutorial walks through the following process:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tCreate a Nginx deployment\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tEnsure that the deployment size is the same as specified by the \u003Ccode class=\"literal\">Nginx\u003C/code> custom resource (CR) spec\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">Nginx\u003C/code> CR status using the status writer with the names of the \u003Ccode class=\"literal\">nginx\u003C/code> pods\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\tThis process is accomplished using two centerpieces of the Operator Framework:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">Operator SDK\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk\u003C/code> CLI tool and \u003Ccode class=\"literal\">controller-runtime\u003C/code> library API\n\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">Operator Lifecycle Manager (OLM)\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tInstallation, upgrade, and role-based access control (RBAC) of Operators on a cluster\n\t\t\t\t\t\t\t\u003C/dd>\u003C/dl>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tThis tutorial goes into greater detail than \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-helm-quickstart\">Getting started with Operator SDK for Helm-based Operators\u003C/a>.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Csection class=\"section\" id=\"osdk-common-prereqs_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.2.1. Prerequisites\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-installing-cli\">Operator SDK CLI installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/cli_tools/#getting-started-cli\">OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tLogged into an OpenShift Container Platform 4.8 cluster with \u003Ccode class=\"literal\">oc\u003C/code> with an account that has \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tTo allow the cluster pull the image, the repository where you push your image must be set as public, or you must configure an image pull secret\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-create-project_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.2.2. Creating a project\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tUse the Operator SDK CLI to create a project called \u003Ccode class=\"literal\">nginx-operator\u003C/code>.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate a directory for the project:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ mkdir -p $HOME/projects/nginx-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tChange to the directory:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ cd $HOME/projects/nginx-operator\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tRun the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command with the \u003Ccode class=\"literal\">helm\u003C/code> plugin to initialize the project:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk init \\\n --plugins=helm \\\n --domain=example.com \\\n --group=demo \\\n --version=v1 \\\n --kind=Nginx\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\tBy default, the \u003Ccode class=\"literal\">helm\u003C/code> plugin initializes a project using a boilerplate Helm chart. You can use additional flags, such as the \u003Ccode class=\"literal\">--helm-chart\u003C/code> flag, to initialize a project using an existing Helm chart.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">init\u003C/code> command creates the \u003Ccode class=\"literal\">nginx-operator\u003C/code> project specifically for watching a resource with API version \u003Ccode class=\"literal\">example.com/v1\u003C/code> and kind \u003Ccode class=\"literal\">Nginx\u003C/code>.\n\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tFor Helm-based projects, the \u003Ccode class=\"literal\">init\u003C/code> command generates the RBAC rules in the \u003Ccode class=\"literal\">config/rbac/role.yaml\u003C/code> file based on the resources that would be deployed by the default manifest for the chart. Verify that the rules generated in this file meet the permission requirements of the Operator.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ol>\u003C/div>\u003Csection class=\"section\" id=\"osdk-helm-existing-chart_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.6.2.2.1. Existing Helm charts\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tInstead of creating your project with a boilerplate Helm chart, you can alternatively use an existing chart, either from your local file system or a remote chart repository, by using the following flags:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--helm-chart\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--helm-chart-repo\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--helm-chart-version\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tIf the \u003Ccode class=\"literal\">--helm-chart\u003C/code> flag is specified, the \u003Ccode class=\"literal\">--group\u003C/code>, \u003Ccode class=\"literal\">--version\u003C/code>, and \u003Ccode class=\"literal\">--kind\u003C/code> flags become optional. If left unset, the following default values are used:\n\t\t\t\t\t\t\u003C/p>\u003Crh-table>\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccolgroup>\u003Ccol style=\"width: 50%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 50%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487210848\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487209760\" scope=\"col\">Value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487210848\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--domain\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487209760\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">my.domain\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487210848\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--group\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487209760\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">charts\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487210848\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--version\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487209760\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">v1\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487210848\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487209760\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tDeduced from the specified chart\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\t\t\tIf the \u003Ccode class=\"literal\">--helm-chart\u003C/code> flag specifies a local chart archive, for example \u003Ccode class=\"literal\">example-chart-1.2.0.tgz\u003C/code>, or directory, the chart is validated and unpacked or copied into the project. Otherwise, the Operator SDK attempts to fetch the chart from a remote repository.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tIf a custom repository URL is not specified by the \u003Ccode class=\"literal\">--helm-chart-repo\u003C/code> flag, the following chart reference formats are supported:\n\t\t\t\t\t\t\u003C/p>\u003Crh-table>\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccolgroup>\u003Ccol style=\"width: 20%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 80%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487182720\" scope=\"col\">Format\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487181632\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487182720\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">&lt;repo_name&gt;/&lt;chart_name&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487181632\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tFetch the Helm chart named \u003Ccode class=\"literal\">&lt;chart_name&gt;\u003C/code> from the helm chart repository named \u003Ccode class=\"literal\">&lt;repo_name&gt;\u003C/code>, as specified in the \u003Ccode class=\"literal\">$HELM_HOME/repositories/repositories.yaml\u003C/code> file. Use the \u003Ccode class=\"literal\">helm repo add\u003C/code> command to configure this file.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487182720\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">&lt;url&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487181632\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tFetch the Helm chart archive at the specified URL.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\t\t\tIf a custom repository URL is specified by \u003Ccode class=\"literal\">--helm-chart-repo\u003C/code>, the following chart reference format is supported:\n\t\t\t\t\t\t\u003C/p>\u003Crh-table>\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccolgroup>\u003Ccol style=\"width: 20%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 80%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487163712\" scope=\"col\">Format\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209487162624\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487163712\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">&lt;chart_name&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209487162624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tFetch the Helm chart named \u003Ccode class=\"literal\">&lt;chart_name&gt;\u003C/code> in the Helm chart repository specified by the \u003Ccode class=\"literal\">--helm-chart-repo\u003C/code> URL value.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\t\t\tIf the \u003Ccode class=\"literal\">--helm-chart-version\u003C/code> flag is unset, the Operator SDK fetches the latest available version of the Helm chart. Otherwise, it fetches the specified version. The optional \u003Ccode class=\"literal\">--helm-chart-version\u003C/code> flag is not used when the chart specified with the \u003Ccode class=\"literal\">--helm-chart\u003C/code> flag refers to a specific version, for example when it is a local path or a URL.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tFor more details and examples, run:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk init --plugins helm --help\u003C/pre>\u003C/section>\u003Csection class=\"section\" id=\"osdk-project-file_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.6.2.2.2. PROJECT file\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tAmong the files generated by the \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command is a Kubebuilder \u003Ccode class=\"literal\">PROJECT\u003C/code> file. Subsequent \u003Ccode class=\"literal\">operator-sdk\u003C/code> commands, as well as \u003Ccode class=\"literal\">help\u003C/code> output, that are run from the project root read this file and are aware that the project type is Helm. For example:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">domain: example.com\nlayout: helm.sdk.operatorframework.io/v1\nprojectName: helm-operator\nresources:\n- group: demo\n kind: Nginx\n version: v1\nversion: 3\u003C/pre>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-helm-logic_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.2.3. Understanding the Operator logic\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tFor this example, the \u003Ccode class=\"literal\">nginx-operator\u003C/code> project executes the following reconciliation logic for each \u003Ccode class=\"literal\">Nginx\u003C/code> custom resource (CR):\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tCreate an Nginx deployment if it does not exist.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tCreate an Nginx service if it does not exist.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tCreate an Nginx ingress if it is enabled and does not exist.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tEnsure that the deployment, service, and optional ingress match the desired configuration as specified by the \u003Ccode class=\"literal\">Nginx\u003C/code> CR, for example the replica count, image, and service type.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\t\tBy default, the \u003Ccode class=\"literal\">nginx-operator\u003C/code> project watches \u003Ccode class=\"literal\">Nginx\u003C/code> resource events as shown in the \u003Ccode class=\"literal\">watches.yaml\u003C/code> file and executes Helm releases using the specified chart:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\"># Use the 'create api' subcommand to add watches to this file.\n- group: demo\n version: v1\n kind: Nginx\n chart: helm-charts/nginx\n# +kubebuilder:scaffold:watch\u003C/pre>\u003Csection class=\"section\" id=\"osdk-helm-sample-chart_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.6.2.3.1. Sample Helm chart\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tWhen a Helm Operator project is created, the Operator SDK creates a sample Helm chart that contains a set of templates for a simple Nginx release.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tFor this example, templates are available for deployment, service, and ingress resources, along with a \u003Ccode class=\"literal\">NOTES.txt\u003C/code> template, which Helm chart developers use to convey helpful information about a release.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tIf you are not already familiar with Helm charts, review the \u003Ca class=\"link\" href=\"https://docs.helm.sh/developing_charts/\">Helm developer documentation\u003C/a>.\n\t\t\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-helm-modify-cr_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.6.2.3.2. Modifying the custom resource spec\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tHelm uses a concept called \u003Ca class=\"link\" href=\"https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing\">values\u003C/a> to provide customizations to the defaults of a Helm chart, which are defined in the \u003Ccode class=\"literal\">values.yaml\u003C/code> file.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tYou can override these defaults by setting the desired values in the custom resource (CR) spec. You can use the number of replicas as an example.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">helm-charts/nginx/values.yaml\u003C/code> file has a value called \u003Ccode class=\"literal\">replicaCount\u003C/code> set to \u003Ccode class=\"literal\">1\u003C/code> by default. To have two Nginx instances in your deployment, your CR spec must contain \u003Ccode class=\"literal\">replicaCount: 2\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tEdit the \u003Ccode class=\"literal\">config/samples/demo_v1_nginx.yaml\u003C/code> file to set \u003Ccode class=\"literal\">replicaCount: 2\u003C/code>:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: demo.example.com/v1\nkind: Nginx\nmetadata:\n name: nginx-sample\n...\nspec:\n...\n replicaCount: 2\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tSimilarly, the default service port is set to \u003Ccode class=\"literal\">80\u003C/code>. To use \u003Ccode class=\"literal\">8080\u003C/code>, edit the \u003Ccode class=\"literal\">config/samples/demo_v1_nginx.yaml\u003C/code> file to set \u003Ccode class=\"literal\">spec.port: 8080\u003C/code>,which adds the service port override:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: demo.example.com/v1\nkind: Nginx\nmetadata:\n name: nginx-sample\nspec:\n replicaCount: 2\n service:\n port: 8080\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tThe Helm Operator applies the entire spec as if it was the contents of a values file, just like the \u003Ccode class=\"literal\">helm install -f ./overrides.yaml\u003C/code> command.\n\t\t\t\t\t\t\u003C/p>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-run-operator_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.2.4. Running the Operator\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThere are three ways you can use the Operator SDK CLI to build and run your Operator:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRun locally outside the cluster as a Go program.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRun as a deployment on the cluster.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tBundle your Operator and use Operator Lifecycle Manager (OLM) to deploy on the cluster.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"osdk-run-locally_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.6.2.4.1. Running locally outside the cluster\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can run your Operator project as a Go program outside of the cluster. This is useful for development purposes to speed up deployment and testing.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following command to install the custom resource definitions (CRDs) in the cluster configured in your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file and run the Operator locally:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make install run\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">...\n{\"level\":\"info\",\"ts\":1612652419.9289865,\"logger\":\"controller-runtime.metrics\",\"msg\":\"metrics server is starting to listen\",\"addr\":\":8080\"}\n{\"level\":\"info\",\"ts\":1612652419.9296563,\"logger\":\"helm.controller\",\"msg\":\"Watching resource\",\"apiVersion\":\"demo.example.com/v1\",\"kind\":\"Nginx\",\"namespace\":\"\",\"reconcilePeriod\":\"1m0s\"}\n{\"level\":\"info\",\"ts\":1612652419.929983,\"logger\":\"controller-runtime.manager\",\"msg\":\"starting metrics server\",\"path\":\"/metrics\"}\n{\"level\":\"info\",\"ts\":1612652419.930015,\"logger\":\"controller-runtime.manager.controller.nginx-controller\",\"msg\":\"Starting EventSource\",\"source\":\"kind source: demo.example.com/v1, Kind=Nginx\"}\n{\"level\":\"info\",\"ts\":1612652420.2307851,\"logger\":\"controller-runtime.manager.controller.nginx-controller\",\"msg\":\"Starting Controller\"}\n{\"level\":\"info\",\"ts\":1612652420.2309358,\"logger\":\"controller-runtime.manager.controller.nginx-controller\",\"msg\":\"Starting workers\",\"worker count\":8}\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-run-deployment_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.6.2.4.2. Running as a deployment on the cluster\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tYou can run your Operator project as a deployment on your cluster.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands to build and push the Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\tThe name and tag of the image, for example \u003Ccode class=\"literal\">IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/code>, in both the commands can also be set in your Makefile. Modify the \u003Ccode class=\"literal\">IMG ?= controller:latest\u003C/code> value to set your default image name.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tRun the following command to deploy the Operator:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make deploy IMG=&lt;registry&gt;/&lt;user&gt;/&lt;image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tBy default, this command creates a namespace with the name of your Operator project in the form \u003Ccode class=\"literal\">&lt;project_name&gt;-system\u003C/code> and is used for the deployment. This command also installs the RBAC manifests from \u003Ccode class=\"literal\">config/rbac\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tVerify that the Operator is running:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployment -n &lt;project_name&gt;-system\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\n&lt;project_name&gt;-controller-manager 1/1 1 1 8m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-bundle-deploy-olm_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.6.2.4.3. Bundling an Operator and deploying with Operator Lifecycle Manager\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-bundle-operator_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch6 class=\"title\">5.6.2.4.3.1. Bundling an Operator\u003C/h6>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator project initialized by using the Operator SDK\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands in your Operator project directory to build and push your Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCreate your Operator bundle manifest by running the \u003Ccode class=\"literal\">make bundle\u003C/code> command, which invokes several commands, including the Operator SDK \u003Ccode class=\"literal\">generate bundle\u003C/code> and \u003Ccode class=\"literal\">bundle validate\u003C/code> subcommands:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tBundle manifests for an Operator describe how to display, create, and manage an application. The \u003Ccode class=\"literal\">make bundle\u003C/code> command creates the following files and directories in your Operator project:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA bundle manifests directory named \u003Ccode class=\"literal\">bundle/manifests\u003C/code> that contains a \u003Ccode class=\"literal\">ClusterServiceVersion\u003C/code> object\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA bundle metadata directory named \u003Ccode class=\"literal\">bundle/metadata\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tAll custom resource definitions (CRDs) in a \u003Ccode class=\"literal\">config/crd\u003C/code> directory\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tA Dockerfile \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tThese files are then automatically validated by using \u003Ccode class=\"literal\">operator-sdk bundle validate\u003C/code> to ensure the on-disk bundle representation is correct.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tBuild and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tBuild the bundle image. Set \u003Ccode class=\"literal\">BUNDLE_IMG\u003C/code> with the details for the registry, user namespace, and image tag where you intend to push the image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\t\t\tPush the bundle image:\n\t\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-deploy-olm_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch6 class=\"title\">5.6.2.4.3.2. Deploying an Operator with Operator Lifecycle Manager\u003C/h6>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\t\tOperator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) for all Operator lifecycle management functions without any additional tools.\n\t\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOperator bundle image built and pushed to a registry\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tOLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use \u003Ccode class=\"literal\">apiextensions.k8s.io/v1\u003C/code> CRDs, for example OpenShift Container Platform 4.8)\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\tLogged in to the cluster with \u003Ccode class=\"literal\">oc\u003C/code> using an account with \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tEnter the following command to run the Operator on the cluster:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk run bundle \\\n [-n &lt;namespace&gt;] \\\u003Cspan id=\"CO46-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO46-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\t\tBy default, the command installs the Operator in the currently active project in your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file. You can add the \u003Ccode class=\"literal\">-n\u003C/code> flag to set a different namespace scope for the installation.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tThis command performs the following actions:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tCreate an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tCreate a catalog source that points to your new index image, which enables OperatorHub to discover your Operator.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\tDeploy your Operator to your cluster by creating an \u003Ccode class=\"literal\">OperatorGroup\u003C/code>, \u003Ccode class=\"literal\">Subscription\u003C/code>, \u003Ccode class=\"literal\">InstallPlan\u003C/code>, and all other required objects, including RBAC.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-create-cr_osdk-helm-tutorial\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.2.5. Creating a custom resource\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAfter your Operator is installed, you can test it by creating a custom resource (CR) that is now provided on the cluster by the Operator.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tExample Nginx Operator, which provides the \u003Ccode class=\"literal\">Nginx\u003C/code> CR, installed on a cluster\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tChange to the namespace where your Operator is installed. For example, if you deployed the Operator using the \u003Ccode class=\"literal\">make deploy\u003C/code> command:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc project nginx-operator-system\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tEdit the sample \u003Ccode class=\"literal\">Nginx\u003C/code> CR manifest at \u003Ccode class=\"literal\">config/samples/demo_v1_nginx.yaml\u003C/code> to contain the following specification:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: demo.example.com/v1\nkind: Nginx\nmetadata:\n name: nginx-sample\n...\nspec:\n...\n replicaCount: 3\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tThe Nginx service account requires privileged access to run in OpenShift Container Platform. Add the following security context constraint (SCC) to the service account for the \u003Ccode class=\"literal\">nginx-sample\u003C/code> pod:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc adm policy add-scc-to-user \\\n anyuid system:serviceaccount:nginx-operator-system:nginx-sample\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCreate the CR:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc apply -f config/samples/demo_v1_nginx.yaml\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tEnsure that the \u003Ccode class=\"literal\">Nginx\u003C/code> Operator creates the deployment for the sample CR with the correct size:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployments\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\nnginx-operator-controller-manager 1/1 1 1 8m\nnginx-sample 3/3 3 3 1m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tCheck the pods and CR status to confirm the status is updated with the Nginx pod names.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCheck the pods:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get pods\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY STATUS RESTARTS AGE\nnginx-sample-6fd7c98d8-7dqdr 1/1 Running 0 1m\nnginx-sample-6fd7c98d8-g5k7v 1/1 Running 0 1m\nnginx-sample-6fd7c98d8-m7vn7 1/1 Running 0 1m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tCheck the CR status:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get nginx/nginx-sample -o yaml\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: demo.example.com/v1\nkind: Nginx\nmetadata:\n...\n name: nginx-sample\n...\nspec:\n replicaCount: 3\nstatus:\n nodes:\n - nginx-sample-6fd7c98d8-7dqdr\n - nginx-sample-6fd7c98d8-g5k7v\n - nginx-sample-6fd7c98d8-m7vn7\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tUpdate the deployment size.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tUpdate \u003Ccode class=\"literal\">config/samples/demo_v1_nginx.yaml\u003C/code> file to change the \u003Ccode class=\"literal\">spec.size\u003C/code> field in the \u003Ccode class=\"literal\">Nginx\u003C/code> CR from \u003Ccode class=\"literal\">3\u003C/code> to \u003Ccode class=\"literal\">5\u003C/code>:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc patch nginx nginx-sample \\\n -p '{\"spec\":{\"replicaCount\": 5}}' \\\n --type=merge\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tConfirm that the Operator changes the deployment size:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get deployments\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY UP-TO-DATE AVAILABLE AGE\nnginx-operator-controller-manager 1/1 1 1 10m\nnginx-sample 5/5 5 5 3m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tClean up the resources that have been created as part of this tutorial.\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tIf you used the \u003Ccode class=\"literal\">make deploy\u003C/code> command to test the Operator, run the following command:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make undeploy\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\t\tIf you used the \u003Ccode class=\"literal\">operator-sdk run bundle\u003C/code> command to test the Operator, run the following command:\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk cleanup &lt;project_name&gt;\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section _additional-resources\" id=\"osdk-helm-tutorial-addtl-resources\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.2.6. Additional resources\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-helm-project-layout\">Project layout for Helm-based Operators\u003C/a> to learn about the directory structures created by the Operator SDK.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-helm-project-layout\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.6.3. Project layout for Helm-based Operators\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk\u003C/code> CLI can generate, or \u003Cspan class=\"emphasis\">\u003Cem>scaffold\u003C/em>\u003C/span>, a number of packages and files for each Operator project.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-helm-project-layout_osdk-helm-project-layout\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.3.1. Helm-based project layout\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tHelm-based Operator projects generated using the \u003Ccode class=\"literal\">operator-sdk init --plugins helm\u003C/code> command contain the following directories and files:\n\t\t\t\t\t\u003C/p>\u003Crh-table>\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccolgroup>\u003Ccol style=\"width: 20%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 80%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486943952\" scope=\"col\">File/folders\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486942864\" scope=\"col\">Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486943952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">config\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486942864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://kustomize.io/\">Kustomize\u003C/a> manifests for deploying the Operator on a Kubernetes cluster.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486943952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">helm-charts/\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486942864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tHelm chart initialized with the \u003Ccode class=\"literal\">operator-sdk create api\u003C/code> command.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486943952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486942864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tUsed to build the Operator image with the \u003Ccode class=\"literal\">make docker-build\u003C/code> command.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486943952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">watches.yaml\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486942864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tGroup/version/kind (GVK) and Helm chart location.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486943952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Makefile\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486942864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tTargets used to manage the project.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486943952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">PROJECT\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486942864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tYAML file containing metadata information for the Operator.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-helm-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.6.4. Helm support in Operator SDK\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Csection class=\"section\" id=\"osdk-helm-charts_osdk-helm-support\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.6.4.1. Helm charts\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOne of the Operator SDK options for generating an Operator project includes leveraging an existing Helm chart to deploy Kubernetes resources as a unified application, without having to write any Go code. Such Helm-based Operators are designed to excel at stateless applications that require very little logic when rolled out, because changes should be applied to the Kubernetes objects that are generated as part of the chart. This may sound limiting, but can be sufficient for a surprising amount of use-cases as shown by the proliferation of Helm charts built by the Kubernetes community.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tThe main function of an Operator is to read from a custom object that represents your application instance and have its desired state match what is running. In the case of a Helm-based Operator, the \u003Ccode class=\"literal\">spec\u003C/code> field of the object is a list of configuration options that are typically described in the Helm \u003Ccode class=\"literal\">values.yaml\u003C/code> file. Instead of setting these values with flags using the Helm CLI (for example, \u003Ccode class=\"literal\">helm install -f values.yaml\u003C/code>), you can express them within a custom resource (CR), which, as a native Kubernetes object, enables the benefits of RBAC applied to it and an audit trail.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tFor an example of a simple CR called \u003Ccode class=\"literal\">Tomcat\u003C/code>:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">apiVersion: apache.org/v1alpha1\nkind: Tomcat\nmetadata:\n name: example-app\nspec:\n replicaCount: 2\u003C/pre>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">replicaCount\u003C/code> value, \u003Ccode class=\"literal\">2\u003C/code> in this case, is propagated into the template of the chart where the following is used:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">{{ .Values.replicaCount }}\u003C/pre>\u003Cp>\n\t\t\t\t\t\tAfter an Operator is built and deployed, you can deploy a new instance of an app by creating a new instance of a CR, or list the different instances running in all environments using the \u003Ccode class=\"literal\">oc\u003C/code> command:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get Tomcats --all-namespaces\u003C/pre>\u003Cp>\n\t\t\t\t\t\tThere is no requirement use the Helm CLI or install Tiller; Helm-based Operators import code from the Helm project. All you have to do is have an instance of the Operator running and register the CR with a custom resource definition (CRD). Because it obeys RBAC, you can more easily prevent production changes.\n\t\t\t\t\t\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.7. Defining cluster service versions (CSVs)\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tA \u003Cspan class=\"emphasis\">\u003Cem>cluster service version\u003C/em>\u003C/span> (CSV), defined by a \u003Ccode class=\"literal\">ClusterServiceVersion\u003C/code> object, is a YAML manifest created from Operator metadata that assists Operator Lifecycle Manager (OLM) in running the Operator in a cluster. It is the metadata that accompanies an Operator container image, used to populate user interfaces with information such as its logo, description, and version. It is also a source of technical information that is required to run the Operator, like the RBAC rules it requires and which custom resources (CRs) it manages or depends on.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tThe Operator SDK includes the CSV generator to generate a CSV for the current Operator project, customized using information contained in YAML manifests and Operator source files.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tA CSV-generating command removes the responsibility of Operator authors having in-depth OLM knowledge in order for their Operator to interact with OLM or publish metadata to the Catalog Registry. Further, because the CSV spec will likely change over time as new Kubernetes and OLM features are implemented, the Operator SDK is equipped to easily extend its update system to handle new CSV features going forward.\n\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-how-csv-gen-works_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.1. How CSV generation works\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator bundle manifests, which include cluster service versions (CSVs), describe how to display, create, and manage an application with Operator Lifecycle Manager (OLM). The CSV generator in the Operator SDK, called by the \u003Ccode class=\"literal\">generate bundle\u003C/code> subcommand, is the first step towards publishing your Operator to a catalog and deploying it with OLM. The subcommand requires certain input manifests to construct a CSV manifest; all inputs are read when the command is invoked, along with a CSV base, to idempotently generate or regenerate a CSV.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tTypically, the \u003Ccode class=\"literal\">generate kustomize manifests\u003C/code> subcommand would be run first to generate the input \u003Ca class=\"link\" href=\"https://kustomize.io/\">Kustomize\u003C/a> bases that are consumed by the \u003Ccode class=\"literal\">generate bundle\u003C/code> subcommand. However, the Operator SDK provides the \u003Ccode class=\"literal\">make bundle\u003C/code> command, which automates several tasks, including running the following subcommands in order:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">generate kustomize manifests\u003C/code>\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">generate bundle\u003C/code>\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">bundle validate\u003C/code>\n\t\t\t\t\t\t\u003C/li>\u003C/ol>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-bundle-operator_osdk-working-bundle-images\">Bundling an Operator\u003C/a> for a full procedure that includes generating a bundle and CSV.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"osdk-csv-bundle-files_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.1.1. Generated files and resources\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">make bundle\u003C/code> command creates the following files and directories in your Operator project:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tA bundle manifests directory named \u003Ccode class=\"literal\">bundle/manifests\u003C/code> that contains a \u003Ccode class=\"literal\">ClusterServiceVersion\u003C/code> (CSV) object\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tA bundle metadata directory named \u003Ccode class=\"literal\">bundle/metadata\u003C/code>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tAll custom resource definitions (CRDs) in a \u003Ccode class=\"literal\">config/crd\u003C/code> directory\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tA Dockerfile \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe following resources are typically included in a CSV:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">Role\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\t\tDefines Operator permissions within a namespace.\n\t\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">ClusterRole\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\t\tDefines cluster-wide Operator permissions.\n\t\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">Deployment\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\t\tDefines how an Operand of an Operator is run in pods.\n\t\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">CustomResourceDefinition (CRD)\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\t\tDefines custom resources that your Operator reconciles.\n\t\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">Custom resource examples\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\t\tExamples of resources adhering to the spec of a particular CRD.\n\t\t\t\t\t\t\t\t\u003C/dd>\u003C/dl>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-csv-ver_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.1.2. Version management\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">--version\u003C/code> flag for the \u003Ccode class=\"literal\">generate bundle\u003C/code> subcommand supplies a semantic version for your bundle when creating one for the first time and when upgrading an existing one.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tBy setting the \u003Ccode class=\"literal\">VERSION\u003C/code> variable in your \u003Ccode class=\"literal\">Makefile\u003C/code>, the \u003Ccode class=\"literal\">--version\u003C/code> flag is automatically invoked using that value when the \u003Ccode class=\"literal\">generate bundle\u003C/code> subcommand is run by the \u003Ccode class=\"literal\">make bundle\u003C/code> command. The CSV version is the same as the Operator version, and a new CSV is generated when upgrading Operator versions.\n\t\t\t\t\t\u003C/p>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-manually-defined-csv-fields_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.2. Manually-defined CSV fields\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tMany CSV fields cannot be populated using generated, generic manifests that are not specific to Operator SDK. These fields are mostly human-written metadata about the Operator and various custom resource definitions (CRDs).\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tOperator authors must directly modify their cluster service version (CSV) YAML file, adding personalized data to the following required fields. The Operator SDK gives a warning during CSV generation when a lack of data in any of the required fields is detected.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe following tables detail which manually-defined CSV fields are required and which are optional.\n\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209486850448\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.7. Required\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 20%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 80%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486845616\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486844528\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">metadata.name\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tA unique name for this CSV. Operator version should be included in the name to ensure uniqueness, for example \u003Ccode class=\"literal\">app-operator.v0.1.1\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">metadata.capabilities\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThe capability level according to the Operator maturity model. Options include \u003Ccode class=\"literal\">Basic Install\u003C/code>, \u003Ccode class=\"literal\">Seamless Upgrades\u003C/code>, \u003Ccode class=\"literal\">Full Lifecycle\u003C/code>, \u003Ccode class=\"literal\">Deep Insights\u003C/code>, and \u003Ccode class=\"literal\">Auto Pilot\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.displayName\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tA public name to identify the Operator.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.description\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tA short description of the functionality of the Operator.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.keywords\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tKeywords describing the Operator.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.maintainers\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tHuman or organizational entities maintaining the Operator, with a \u003Ccode class=\"literal\">name\u003C/code> and \u003Ccode class=\"literal\">email\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.provider\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThe provider of the Operator (usually an organization), with a \u003Ccode class=\"literal\">name\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.labels\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tKey-value pairs to be used by Operator internals.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.version\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tSemantic version of the Operator, for example \u003Ccode class=\"literal\">0.1.1\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486845616\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.customresourcedefinitions\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486844528\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tAny CRDs the Operator uses. This field is populated automatically by the Operator SDK if any CRD YAML files are present in \u003Ccode class=\"literal\">deploy/\u003C/code>. However, several fields not in the CRD manifest spec require user input:\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">description\u003C/code>: description of the CRD.\n\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">resources\u003C/code>: any Kubernetes resources leveraged by the CRD, for example \u003Ccode class=\"literal\">Pod\u003C/code> and \u003Ccode class=\"literal\">StatefulSet\u003C/code> objects.\n\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">specDescriptors\u003C/code>: UI hints for inputs and outputs of the Operator.\n\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Crh-table id=\"idm140209486789520\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.8. Optional\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 20%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 80%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486784688\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486783600\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486784688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.replaces\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486783600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThe name of the CSV being replaced by this CSV.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486784688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.links\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486783600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tURLs (for example, websites and documentation) pertaining to the Operator or application being managed, each with a \u003Ccode class=\"literal\">name\u003C/code> and \u003Ccode class=\"literal\">url\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486784688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.selector\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486783600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tSelectors by which the Operator can pair resources in a cluster.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486784688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.icon\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486783600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tA base64-encoded icon unique to the Operator, set in a \u003Ccode class=\"literal\">base64data\u003C/code> field with a \u003Ccode class=\"literal\">mediatype\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486784688\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">spec.maturity\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486783600\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThe level of maturity the software has achieved at this version. Options include \u003Ccode class=\"literal\">planning\u003C/code>, \u003Ccode class=\"literal\">pre-alpha\u003C/code>, \u003Ccode class=\"literal\">alpha\u003C/code>, \u003Ccode class=\"literal\">beta\u003C/code>, \u003Ccode class=\"literal\">stable\u003C/code>, \u003Ccode class=\"literal\">mature\u003C/code>, \u003Ccode class=\"literal\">inactive\u003C/code>, and \u003Ccode class=\"literal\">deprecated\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\tFurther details on what data each field above should hold are found in the \u003Ca class=\"link\" href=\"https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/building-your-csv.md\">CSV spec\u003C/a>.\n\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tSeveral YAML fields currently requiring user intervention can potentially be parsed from Operator code.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-maturity-model_olm-what-operators-are\">Operator maturity model\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"osdk-csv-manual-annotations_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.2.1. Operator metadata annotations\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOperator developers can manually define certain annotations in the metadata of a cluster service version (CSV) to enable features or highlight capabilities in user interfaces (UIs), such as OperatorHub.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tThe following table lists Operator metadata annotations that can be manually defined using \u003Ccode class=\"literal\">metadata.annotations\u003C/code> fields.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209486746000\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.9. Annotations\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 50%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 50%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486741168\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209486740080\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486741168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">alm-examples\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486740080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tProvide custom resource definition (CRD) templates with a minimum set of configuration. Compatible UIs pre-fill this template for users to further customize.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486741168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">operatorframework.io/initialization-resource\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486740080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSpecify a single required custom resource by adding \u003Ccode class=\"literal\">operatorframework.io/initialization-resource\u003C/code> annotation to the cluster service version (CSV) during Operator installation. The user is then prompted to create the custom resource through a template provided in the CSV. Must include a template that contains a complete YAML definition.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486741168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">operatorframework.io/suggested-namespace\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486740080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSet a suggested namespace where the Operator should be deployed.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486741168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">operators.openshift.io/infrastructure-features\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486740080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tInfrastructure features supported by the Operator. Users can view and filter by these features when discovering Operators through OperatorHub in the web console. Valid, case-sensitive values:\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">disconnected\u003C/code>: Operator supports being mirrored into disconnected catalogs, including all dependencies, and does not require internet access. All related images required for mirroring are listed by the Operator.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">cnf\u003C/code>: Operator provides a Cloud-native Network Functions (CNF) Kubernetes plugin.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">cni\u003C/code>: Operator provides a Container Network Interface (CNI) Kubernetes plugin.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">csi\u003C/code>: Operator provides a Container Storage Interface (CSI) Kubernetes plugin.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">fips\u003C/code>: Operator accepts the FIPS mode of the underlying platform and works on nodes that are booted into FIPS mode.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\n\t\t\t\t\t\t\t\t\t \u003Crh-alert class=\"admonition important\" state=\"warning\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Important\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tThe use of FIPS Validated / Modules in Process cryptographic libraries is only supported on OpenShift Container Platform deployments on the \u003Ccode class=\"literal\">x86_64\u003C/code> architecture.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\n\t\t\t\t\t\t\t\t\t \u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">proxy-aware\u003C/code>: Operator supports running on a cluster behind a proxy. Operator accepts the standard proxy environment variables \u003Ccode class=\"literal\">HTTP_PROXY\u003C/code> and \u003Ccode class=\"literal\">HTTPS_PROXY\u003C/code>, which Operator Lifecycle Manager (OLM) provides to the Operator automatically when the cluster is configured to use a proxy. Required environment variables are passed down to Operands for managed workloads.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486741168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">operators.openshift.io/valid-subscription\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486740080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tFree-form array for listing any specific subscriptions that are required to use the Operator. For example, \u003Ccode class=\"literal\">'[\"3Scale Commercial License\", \"Red Hat Managed Integration\"]'\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486741168\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">operators.operatorframework.io/internal-objects\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209486740080\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tHides CRDs in the UI that are not meant for user manipulation.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Ch6 id=\"osdk-csv-manual-annotations-examples_osdk-generating-csvs\">Example use cases\u003C/h6>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Operator supports disconnected and proxy-aware\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">operators.openshift.io/infrastructure-features: '[\"disconnected\", \"proxy-aware\"]'\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Operator requires an OpenShift Container Platform license\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">operators.openshift.io/valid-subscription: '[\"OpenShift Container Platform\"]'\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Operator requires a 3scale license\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">operators.openshift.io/valid-subscription: '[\"3Scale Commercial License\", \"Red Hat Managed Integration\"]'\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Operator supports disconnected and proxy-aware, and requires an OpenShift Container Platform license\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">operators.openshift.io/infrastructure-features: '[\"disconnected\", \"proxy-aware\"]'\noperators.openshift.io/valid-subscription: '[\"OpenShift Container Platform\"]'\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-crds-templates_osdk-generating-csvs\">CRD templates\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-init-resource_osdk-generating-csvs\">Initializing required custom resources \u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-suggested-namespace_osdk-generating-csvs\">Setting a suggested namespace\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-enabling-operator-for-restricted-network_osdk-generating-csvs\">Enabling your Operator for restricted network environments\u003C/a> (disconnected mode)\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-hiding-internal-objects_osdk-generating-csvs\">Hiding internal objects\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/installing/#installing-fips\">Support for FIPS crytography\u003C/a>\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"olm-enabling-operator-for-restricted-network_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.3. Enabling your Operator for restricted network environments\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tAs an Operator author, your Operator must meet additional requirements to run properly in a restricted network, or disconnected, environment.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Operator requirements for supporting disconnected mode\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIn the cluster service version (CSV) of your Operator:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"circle\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tList any \u003Cspan class=\"emphasis\">\u003Cem>related images\u003C/em>\u003C/span>, or other container images that your Operator might require to perform their functions.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tReference all specified images by a digest (SHA) and not by a tag.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tAll dependencies of your Operator must also support running in a disconnected mode.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tYour Operator must not require any off-cluster resources.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\tFor the CSV requirements, you can make the following changes as the Operator author.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tAn Operator project with a CSV.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tUse SHA references to related images in two places in the CSV for your Operator:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tUpdate \u003Ccode class=\"literal\">spec.relatedImages\u003C/code>:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">...\nspec:\n relatedImages: \u003Cspan id=\"CO47-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n - name: etcd-operator \u003Cspan id=\"CO47-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\n image: quay.io/etcd-operator/operator@sha256:d134a9865524c29fcf75bbc4469013bc38d8a15cb5f41acfddb6b9e492f556e4 \u003Cspan id=\"CO47-3\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">3\u003C/span>\n - name: etcd-image\n image: quay.io/etcd-operator/etcd@sha256:13348c15263bd8838ec1d5fc4550ede9860fcbb0f843e48cbccec07810eebb68\n...\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO47-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tCreate a \u003Ccode class=\"literal\">relatedImages\u003C/code> section and set the list of related images.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO47-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tSpecify a unique identifier for the image.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO47-3\">\u003Cspan class=\"callout\">3\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tSpecify each image by a digest (SHA), not by an image tag.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">env\u003C/code> section in the deployment when declaring environment variables that inject the image that the Operator should use:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">spec:\n install:\n spec:\n deployments:\n - name: etcd-operator-v3.1.1\n spec:\n replicas: 1\n selector:\n matchLabels:\n name: etcd-operator\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n name: etcd-operator\n spec:\n containers:\n - args:\n - /opt/etcd/bin/etcd_operator_run.sh\n env:\n - name: WATCH_NAMESPACE\n valueFrom:\n fieldRef:\n fieldPath: metadata.annotations['olm.targetNamespaces']\n - name: ETCD_OPERATOR_DEFAULT_ETCD_IMAGE \u003Cspan id=\"CO48-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n value: quay.io/etcd-operator/etcd@sha256:13348c15263bd8838ec1d5fc4550ede9860fcbb0f843e48cbccec07810eebb68 \u003Cspan id=\"CO48-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\n - name: ETCD_LOG_LEVEL\n value: INFO\n image: quay.io/etcd-operator/operator@sha256:d134a9865524c29fcf75bbc4469013bc38d8a15cb5f41acfddb6b9e492f556e4 \u003Cspan id=\"CO48-3\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">3\u003C/span>\n imagePullPolicy: IfNotPresent\n livenessProbe:\n httpGet:\n path: /healthy\n port: 8080\n initialDelaySeconds: 10\n periodSeconds: 30\n name: etcd-operator\n readinessProbe:\n httpGet:\n path: /ready\n port: 8080\n initialDelaySeconds: 10\n periodSeconds: 30\n resources: {}\n serviceAccountName: etcd-operator\n strategy: deployment\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO48-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tInject the images referenced by the Operator by using environment variables.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO48-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tSpecify each image by a digest (SHA), not by an image tag.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO48-3\">\u003Cspan class=\"callout\">3\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tAlso reference the Operator container image by a digest (SHA), not by an image tag.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\tWhen configuring probes, the \u003Ccode class=\"literal\">timeoutSeconds\u003C/code> value must be lower than the \u003Ccode class=\"literal\">periodSeconds\u003C/code> value. The \u003Ccode class=\"literal\">timeoutSeconds\u003C/code> default value is \u003Ccode class=\"literal\">1\u003C/code>. The \u003Ccode class=\"literal\">periodSeconds\u003C/code> default value is \u003Ccode class=\"literal\">10\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tAdd the \u003Ccode class=\"literal\">disconnected\u003C/code> annotation, which indicates that the Operator works in a disconnected environment:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">metadata:\n annotations:\n operators.openshift.io/infrastructure-features: '[\"disconnected\"]'\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tOperators can be filtered in OperatorHub by this infrastructure feature.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"olm-enabling-operator-for-multi-arch_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.4. Enabling your Operator for multiple architectures and operating systems\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator Lifecycle Manager (OLM) assumes that all Operators run on Linux hosts. However, as an Operator author, you can specify whether your Operator supports managing workloads on other architectures, if worker nodes are available in the OpenShift Container Platform cluster.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tIf your Operator supports variants other than AMD64 and Linux, you can add labels to the cluster service version (CSV) that provides the Operator to list the supported variants. Labels indicating supported architectures and operating systems are defined by the following:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">labels:\n operatorframework.io/arch.&lt;arch&gt;: supported \u003Cspan id=\"CO49-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n operatorframework.io/os.&lt;os&gt;: supported \u003Cspan id=\"CO49-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO49-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\tSet \u003Ccode class=\"literal\">&lt;arch&gt;\u003C/code> to a supported string.\n\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO49-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\tSet \u003Ccode class=\"literal\">&lt;os&gt;\u003C/code> to a supported string.\n\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tOnly the labels on the channel head of the default channel are considered for filtering package manifests by label. This means, for example, that providing an additional architecture for an Operator in the non-default channel is possible, but that architecture is not available for filtering in the \u003Ccode class=\"literal\">PackageManifest\u003C/code> API.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cp>\n\t\t\t\t\tIf a CSV does not include an \u003Ccode class=\"literal\">os\u003C/code> label, it is treated as if it has the following Linux support label by default:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">labels:\n operatorframework.io/os.linux: supported\u003C/pre>\u003Cp>\n\t\t\t\t\tIf a CSV does not include an \u003Ccode class=\"literal\">arch\u003C/code> label, it is treated as if it has the following AMD64 support label by default:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">labels:\n operatorframework.io/arch.amd64: supported\u003C/pre>\u003Cp>\n\t\t\t\t\tIf an Operator supports multiple node architectures or operating systems, you can add multiple labels, as well.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tAn Operator project with a CSV.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tTo support listing multiple architectures and operating systems, your Operator image referenced in the CSV must be a manifest list image.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tFor the Operator to work properly in restricted network, or disconnected, environments, the image referenced must also be specified using a digest (SHA) and not by a tag.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tAdd a label in the \u003Ccode class=\"literal\">metadata.labels\u003C/code> of your CSV for each supported architecture and operating system that your Operator supports:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">labels:\n operatorframework.io/arch.s390x: supported\n operatorframework.io/os.zos: supported\n operatorframework.io/os.linux: supported \u003Cspan id=\"CO50-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n operatorframework.io/arch.amd64: supported \u003Cspan id=\"CO50-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO50-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003Ca href=\"#CO50-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tAfter you add a new architecture or operating system, you must also now include the default \u003Ccode class=\"literal\">os.linux\u003C/code> and \u003Ccode class=\"literal\">arch.amd64\u003C/code> variants explicitly.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee the \u003Ca class=\"link\" href=\"https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list\">Image Manifest V 2, Schema 2\u003C/a> specification for more information on manifest lists.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"olm-arch-os-support_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.4.1. Architecture and operating system support for Operators\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe following strings are supported in Operator Lifecycle Manager (OLM) on OpenShift Container Platform when labeling or filtering Operators that support multiple architectures and operating systems:\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209535214432\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.10. Architectures supported on OpenShift Container Platform\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 50%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 50%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209535209568\" scope=\"col\">Architecture\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209535208480\" scope=\"col\">String\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535209568\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tAMD64\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535208480\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">amd64\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535209568\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t64-bit PowerPC little-endian\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535208480\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">ppc64le\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535209568\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tIBM Z\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535208480\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">s390x\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Crh-table id=\"idm140209535193920\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.11. Operating systems supported on OpenShift Container Platform\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 50%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 50%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209535189040\" scope=\"col\">Operating system\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209535187952\" scope=\"col\">String\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535189040\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tLinux\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535187952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">linux\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535189040\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tz/OS\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535187952\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">zos\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\tDifferent versions of OpenShift Container Platform and other Kubernetes-based distributions might support a different set of architectures and operating systems.\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-suggested-namespace_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.5. Setting a suggested namespace\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tSome Operators must be deployed in a specific namespace, or with ancillary resources in specific namespaces, to work properly. If resolved from a subscription, Operator Lifecycle Manager (OLM) defaults the namespaced resources of an Operator to the namespace of its subscription.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tAs an Operator author, you can instead express a desired target namespace as part of your cluster service version (CSV) to maintain control over the final namespaces of the resources installed for their Operators. When adding the Operator to a cluster using OperatorHub, this enables the web console to autopopulate the suggested namespace for the cluster administrator during the installation process.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIn your CSV, set the \u003Ccode class=\"literal\">operatorframework.io/suggested-namespace\u003C/code> annotation to your suggested namespace:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">metadata:\n annotations:\n operatorframework.io/suggested-namespace: &lt;namespace&gt; \u003Cspan id=\"CO51-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO51-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tSet your suggested namespace.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-operatorconditions_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.6. Enabling Operator conditions\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator Lifecycle Manager (OLM) provides Operators with a channel to communicate complex states that influence OLM behavior while managing the Operator. By default, OLM creates an \u003Ccode class=\"literal\">OperatorCondition\u003C/code> custom resource definition (CRD) when it installs an Operator. Based on the conditions set in the \u003Ccode class=\"literal\">OperatorCondition\u003C/code> custom resource (CR), the behavior of OLM changes accordingly.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tTo support Operator conditions, an Operator must be able to read the \u003Ccode class=\"literal\">OperatorCondition\u003C/code> CR created by OLM and have the ability to complete the following tasks:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tGet the specific condition.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSet the status of a specific condition.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\tThis can be accomplished by using the \u003Ca class=\"link\" href=\"https://github.com/operator-framework/operator-lib/tree/v0.3.0\">\u003Ccode class=\"literal\">operator-lib\u003C/code>\u003C/a> library. An Operator author can provide a \u003Ca class=\"link\" href=\"https://github.com/kubernetes-sigs/controller-runtime/tree/master/pkg/client\">\u003Ccode class=\"literal\">controller-runtime\u003C/code> client\u003C/a> in their Operator for the library to access the \u003Ccode class=\"literal\">OperatorCondition\u003C/code> CR owned by the Operator in the cluster.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe library provides a generic \u003Ccode class=\"literal\">Conditions\u003C/code> interface, which has the following methods to \u003Ccode class=\"literal\">Get\u003C/code> and \u003Ccode class=\"literal\">Set\u003C/code> a \u003Ccode class=\"literal\">conditionType\u003C/code> in the \u003Ccode class=\"literal\">OperatorCondition\u003C/code> CR:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">\u003Ccode class=\"literal\">Get\u003C/code>\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tTo get the specific condition, the library uses the \u003Ccode class=\"literal\">client.Get\u003C/code> function from \u003Ccode class=\"literal\">controller-runtime\u003C/code>, which requires an \u003Ccode class=\"literal\">ObjectKey\u003C/code> of type \u003Ccode class=\"literal\">types.NamespacedName\u003C/code> present in \u003Ccode class=\"literal\">conditionAccessor\u003C/code>.\n\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">\u003Ccode class=\"literal\">Set\u003C/code>\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tTo update the status of the specific condition, the library uses the \u003Ccode class=\"literal\">client.Update\u003C/code> function from \u003Ccode class=\"literal\">controller-runtime\u003C/code>. An error occurs if the \u003Ccode class=\"literal\">conditionType\u003C/code> is not present in the CRD.\n\t\t\t\t\t\t\t\u003C/dd>\u003C/dl>\u003C/div>\u003Cp>\n\t\t\t\t\tThe Operator is allowed to modify only the \u003Ccode class=\"literal\">status\u003C/code> subresource of the CR. Operators can either delete or update the \u003Ccode class=\"literal\">status.conditions\u003C/code> array to include the condition. For more details on the format and description of the fields present in the conditions, see the upstream \u003Ca class=\"link\" href=\"https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Condition\">Condition GoDocs\u003C/a>.\n\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tOperator SDK v1.8.0 supports \u003Ccode class=\"literal\">operator-lib\u003C/code> v0.3.0.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tAn Operator project generated using the Operator SDK.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\tTo enable Operator conditions in your Operator project:\n\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIn the \u003Ccode class=\"literal\">go.mod\u003C/code> file of your Operator project, add \u003Ccode class=\"literal\">operator-framework/operator-lib\u003C/code> as a required library:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">module github.com/example-inc/memcached-operator\n\ngo 1.15\n\nrequire (\n k8s.io/apimachinery v0.19.2\n k8s.io/client-go v0.19.2\n sigs.k8s.io/controller-runtime v0.7.0\n operator-framework/operator-lib v0.3.0\n)\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tWrite your own constructor in your Operator logic that will result in the following outcomes:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tAccepts a \u003Ccode class=\"literal\">controller-runtime\u003C/code> client.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tAccepts a \u003Ccode class=\"literal\">conditionType\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tReturns a \u003Ccode class=\"literal\">Condition\u003C/code> interface to update or add conditions.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tBecause OLM currently supports the \u003Ccode class=\"literal\">Upgradeable\u003C/code> condition, you can create an interface that has methods to access the \u003Ccode class=\"literal\">Upgradeable\u003C/code> condition. For example:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import (\n ...\n apiv1 \"github.com/operator-framework/api/pkg/operators/v1\"\n)\n\nfunc NewUpgradeable(cl client.Client) (Condition, error) {\n return NewCondition(cl, \"apiv1.OperatorUpgradeable\")\n}\n\ncond, err := NewUpgradeable(cl);\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIn this example, the \u003Ccode class=\"literal\">NewUpgradeable\u003C/code> constructor is further used to create a variable \u003Ccode class=\"literal\">cond\u003C/code> of type \u003Ccode class=\"literal\">Condition\u003C/code>. The \u003Ccode class=\"literal\">cond\u003C/code> variable would in turn have \u003Ccode class=\"literal\">Get\u003C/code> and \u003Ccode class=\"literal\">Set\u003C/code> methods, which can be used for handling the OLM \u003Ccode class=\"literal\">Upgradeable\u003C/code> condition.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ol>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-operatorconditions\">Operator conditions\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"olm-defining-csv-webhook_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.7. Defining webhooks\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tWebhooks allow Operator authors to intercept, modify, and accept or reject resources before they are saved to the object store and handled by the Operator controller. Operator Lifecycle Manager (OLM) can manage the lifecycle of these webhooks when they are shipped alongside your Operator.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe cluster service version (CSV) resource of an Operator can include a \u003Ccode class=\"literal\">webhookdefinitions\u003C/code> section to define the following types of webhooks:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tAdmission webhooks (validating and mutating)\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tConversion webhooks\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tAdd a \u003Ccode class=\"literal\">webhookdefinitions\u003C/code> section to the \u003Ccode class=\"literal\">spec\u003C/code> section of the CSV of your Operator and include any webhook definitions using a \u003Ccode class=\"literal\">type\u003C/code> of \u003Ccode class=\"literal\">ValidatingAdmissionWebhook\u003C/code>, \u003Ccode class=\"literal\">MutatingAdmissionWebhook\u003C/code>, or \u003Ccode class=\"literal\">ConversionWebhook\u003C/code>. The following example contains all three types of webhooks:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>CSV containing webhooks\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\"> apiVersion: operators.coreos.com/v1alpha1\n kind: ClusterServiceVersion\n metadata:\n name: webhook-operator.v0.0.1\n spec:\n customresourcedefinitions:\n owned:\n - kind: WebhookTest\n name: webhooktests.webhook.operators.coreos.io \u003Cspan id=\"CO52-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n version: v1\n install:\n spec:\n deployments:\n - name: webhook-operator-webhook\n ...\n ...\n ...\n strategy: deployment\n installModes:\n - supported: false\n type: OwnNamespace\n - supported: false\n type: SingleNamespace\n - supported: false\n type: MultiNamespace\n - supported: true\n type: AllNamespaces\n webhookdefinitions:\n - type: ValidatingAdmissionWebhook \u003Cspan id=\"CO52-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\n admissionReviewVersions:\n - v1beta1\n - v1\n containerPort: 443\n targetPort: 4343\n deploymentName: webhook-operator-webhook\n failurePolicy: Fail\n generateName: vwebhooktest.kb.io\n rules:\n - apiGroups:\n - webhook.operators.coreos.io\n apiVersions:\n - v1\n operations:\n - CREATE\n - UPDATE\n resources:\n - webhooktests\n sideEffects: None\n webhookPath: /validate-webhook-operators-coreos-io-v1-webhooktest\n - type: MutatingAdmissionWebhook \u003Cspan id=\"CO52-3\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">3\u003C/span>\n admissionReviewVersions:\n - v1beta1\n - v1\n containerPort: 443\n targetPort: 4343\n deploymentName: webhook-operator-webhook\n failurePolicy: Fail\n generateName: mwebhooktest.kb.io\n rules:\n - apiGroups:\n - webhook.operators.coreos.io\n apiVersions:\n - v1\n operations:\n - CREATE\n - UPDATE\n resources:\n - webhooktests\n sideEffects: None\n webhookPath: /mutate-webhook-operators-coreos-io-v1-webhooktest\n - type: ConversionWebhook \u003Cspan id=\"CO52-4\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">4\u003C/span>\n admissionReviewVersions:\n - v1beta1\n - v1\n containerPort: 443\n targetPort: 4343\n deploymentName: webhook-operator-webhook\n generateName: cwebhooktest.kb.io\n sideEffects: None\n webhookPath: /convert\n conversionCRDs:\n - webhooktests.webhook.operators.coreos.io \u003Cspan id=\"CO52-5\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">5\u003C/span>\n...\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO52-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tThe CRDs targeted by the conversion webhook must exist here.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO52-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tA validating admission webhook.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO52-3\">\u003Cspan class=\"callout\">3\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tA mutating admission webhook.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO52-4\">\u003Cspan class=\"callout\">4\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tA conversion webhook.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO52-5\">\u003Cspan class=\"callout\">5\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">spec.PreserveUnknownFields\u003C/code> property of each CRD must be set to \u003Ccode class=\"literal\">false\u003C/code> or \u003Ccode class=\"literal\">nil\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/architecture/#admission-webhook-types_admission-plug-ins\">Types of webhook admission plugins\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tKubernetes documentation:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"circle\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook\">Validating admission webhooks\u003C/a>\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook\">Mutating admission webhooks\u003C/a>\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion\">Conversion webhooks\u003C/a>\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"olm-webhook-considerations_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.7.1. Webhook considerations for OLM\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tWhen deploying an Operator with webhooks using Operator Lifecycle Manager (OLM), you must define the following:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">type\u003C/code> field must be set to either \u003Ccode class=\"literal\">ValidatingAdmissionWebhook\u003C/code>, \u003Ccode class=\"literal\">MutatingAdmissionWebhook\u003C/code>, or \u003Ccode class=\"literal\">ConversionWebhook\u003C/code>, or the CSV will be placed in a failed phase.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tThe CSV must contain a deployment whose name is equivalent to the value supplied in the \u003Ccode class=\"literal\">deploymentName\u003C/code> field of the \u003Ccode class=\"literal\">webhookdefinition\u003C/code>.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\t\tWhen the webhook is created, OLM ensures that the webhook only acts upon namespaces that match the Operator group that the Operator is deployed in.\n\t\t\t\t\t\u003C/p>\u003Ch5 id=\"olm-webhook-ca_osdk-generating-csvs\">Certificate authority constraints\u003C/h5>\u003Cp>\n\t\t\t\t\t\tOLM is configured to provide each deployment with a single certificate authority (CA). The logic that generates and mounts the CA into the deployment was originally used by the API service lifecycle logic. As a result:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tThe TLS certificate file is mounted to the deployment at \u003Ccode class=\"literal\">/apiserver.local.config/certificates/apiserver.crt\u003C/code>.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tThe TLS key file is mounted to the deployment at \u003Ccode class=\"literal\">/apiserver.local.config/certificates/apiserver.key\u003C/code>.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Ch5 id=\"olm-admission-webhook-constraints_osdk-generating-csvs\">Admission webhook rules constraints\u003C/h5>\u003Cp>\n\t\t\t\t\t\tTo prevent an Operator from configuring the cluster into an unrecoverable state, OLM places the CSV in the failed phase if the rules defined in an admission webhook intercept any of the following requests:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRequests that target all groups\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRequests that target the \u003Ccode class=\"literal\">operators.coreos.com\u003C/code> group\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tRequests that target the \u003Ccode class=\"literal\">ValidatingWebhookConfigurations\u003C/code> or \u003Ccode class=\"literal\">MutatingWebhookConfigurations\u003C/code> resources\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Ch5 id=\"olm-conversion-webhook-constraints_osdk-generating-csvs\">Conversion webhook constraints\u003C/h5>\u003Cp>\n\t\t\t\t\t\tOLM places the CSV in the failed phase if a conversion webhook definition does not adhere to the following constraints:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tCSVs featuring a conversion webhook can only support the \u003Ccode class=\"literal\">AllNamespaces\u003C/code> install mode.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tThe CRD targeted by the conversion webhook must have its \u003Ccode class=\"literal\">spec.preserveUnknownFields\u003C/code> field set to \u003Ccode class=\"literal\">false\u003C/code> or \u003Ccode class=\"literal\">nil\u003C/code>.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tThe conversion webhook defined in the CSV must target an owned CRD.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tThere can only be one conversion webhook on the entire cluster for a given CRD.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-crds_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.8. Understanding your custom resource definitions (CRDs)\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThere are two types of custom resource definitions (CRDs) that your Operator can use: ones that are \u003Cspan class=\"emphasis\">\u003Cem>owned\u003C/em>\u003C/span> by it and ones that it depends on, which are \u003Cspan class=\"emphasis\">\u003Cem>required\u003C/em>\u003C/span>.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-crds-owned_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.8.1. Owned CRDs\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe custom resource definitions (CRDs) owned by your Operator are the most important part of your CSV. This establishes the link between your Operator and the required RBAC rules, dependency management, and other Kubernetes concepts.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tIt is common for your Operator to use multiple CRDs to link together concepts, such as top-level database configuration in one object and a representation of replica sets in another. Each one should be listed out in the CSV file.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209535045168\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.12. Owned CRD fields\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 22%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 56%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 22%; \" class=\"col_3\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209535039408\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209535038320\" scope=\"col\">Description\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209535037232\" scope=\"col\">Required/optional\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Name\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe full name of your CRD.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Version\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe version of that object API.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe machine readable name of your CRD.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">DisplayName\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA human readable version of your CRD name, for example \u003Ccode class=\"literal\">MongoDB Standalone\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Description\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA short description of how this CRD is used by the Operator or a description of the functionality provided by the CRD.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Group\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe API group that this CRD belongs to, for example \u003Ccode class=\"literal\">database.example.com\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tOptional\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Resources\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tYour CRDs own one or more types of Kubernetes objects. These are listed in the \u003Ccode class=\"literal\">resources\u003C/code> section to inform your users of the objects they might need to troubleshoot or how to connect to the application, such as the service or ingress rule that exposes a database.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003Cp>\n\t\t\t\t\t\t\t\t\t\tIt is recommended to only list out the objects that are important to a human, not an exhaustive list of everything you orchestrate. For example, do not list config maps that store internal state that are not meant to be modified by a user.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tOptional\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535039408\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">SpecDescriptors\u003C/code>, \u003Ccode class=\"literal\">StatusDescriptors\u003C/code>, and \u003Ccode class=\"literal\">ActionDescriptors\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535038320\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThese descriptors are a way to hint UIs with certain inputs or outputs of your Operator that are most important to an end user. If your CRD contains the name of a secret or config map that the user must provide, you can specify that here. These items are linked and highlighted in compatible UIs.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThere are three types of descriptors:\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">SpecDescriptors\u003C/code>: A reference to fields in the \u003Ccode class=\"literal\">spec\u003C/code> block of an object.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">StatusDescriptors\u003C/code>: A reference to fields in the \u003Ccode class=\"literal\">status\u003C/code> block of an object.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">ActionDescriptors\u003C/code>: A reference to actions that can be performed on an object.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\n\t\t\t\t\t\t\t\t\t \u003Cp>\n\t\t\t\t\t\t\t\t\t\tAll descriptors accept the following fields:\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">DisplayName\u003C/code>: A human readable name for the \u003Ccode class=\"literal\">Spec\u003C/code>, \u003Ccode class=\"literal\">Status\u003C/code>, or \u003Ccode class=\"literal\">Action\u003C/code>.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Description\u003C/code>: A short description of the \u003Ccode class=\"literal\">Spec\u003C/code>, \u003Ccode class=\"literal\">Status\u003C/code>, or \u003Ccode class=\"literal\">Action\u003C/code> and how it is used by the Operator.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Path\u003C/code>: A dot-delimited path of the field on the object that this descriptor describes.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">X-Descriptors\u003C/code>: Used to determine which \"capabilities\" this descriptor has and which UI component to use. See the \u003Cspan class=\"strong strong\">\u003Cstrong>openshift/console\u003C/strong>\u003C/span> project for a canonical \u003Ca class=\"link\" href=\"https://github.com/openshift/console/tree/release-4.3/frontend/packages/operator-lifecycle-manager/src/components/descriptors/types.ts\">list of React UI X-Descriptors\u003C/a> for OpenShift Container Platform.\n\t\t\t\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\n\t\t\t\t\t\t\t\t\t \u003Cp>\n\t\t\t\t\t\t\t\t\t\tAlso see the \u003Cspan class=\"strong strong\">\u003Cstrong>openshift/console\u003C/strong>\u003C/span> project for more information on \u003Ca class=\"link\" href=\"https://github.com/openshift/console/tree/release-4.3/frontend/packages/operator-lifecycle-manager/src/components/descriptors\">Descriptors\u003C/a> in general.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209535037232\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tOptional\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\t\tThe following example depicts a \u003Ccode class=\"literal\">MongoDB Standalone\u003C/code> CRD that requires some user input in the form of a secret and config map, and orchestrates services, stateful sets, pods and config maps:\n\t\t\t\t\t\u003C/p>\u003Cdiv id=\"osdk-crds-owned-example_osdk-generating-csvs\" class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example owned CRD\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\"> - displayName: MongoDB Standalone\n group: mongodb.com\n kind: MongoDbStandalone\n name: mongodbstandalones.mongodb.com\n resources:\n - kind: Service\n name: ''\n version: v1\n - kind: StatefulSet\n name: ''\n version: v1beta2\n - kind: Pod\n name: ''\n version: v1\n - kind: ConfigMap\n name: ''\n version: v1\n specDescriptors:\n - description: Credentials for Ops Manager or Cloud Manager.\n displayName: Credentials\n path: credentials\n x-descriptors:\n - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Secret'\n - description: Project this deployment belongs to.\n displayName: Project\n path: project\n x-descriptors:\n - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap'\n - description: MongoDB version to be installed.\n displayName: Version\n path: version\n x-descriptors:\n - 'urn:alm:descriptor:com.tectonic.ui:label'\n statusDescriptors:\n - description: The status of each of the pods for the MongoDB cluster.\n displayName: Pod Status\n path: pods\n x-descriptors:\n - 'urn:alm:descriptor:com.tectonic.ui:podStatuses'\n version: v1\n description: &gt;-\n MongoDB Deployment consisting of only one host. No replication of\n data.\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-crds-required_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.8.2. Required CRDs\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tRelying on other required CRDs is completely optional and only exists to reduce the scope of individual Operators and provide a way to compose multiple Operators together to solve an end-to-end use case.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tAn example of this is an Operator that might set up an application and install an etcd cluster (from an etcd Operator) to use for distributed locking and a Postgres database (from a Postgres Operator) for data storage.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tOperator Lifecycle Manager (OLM) checks against the available CRDs and Operators in the cluster to fulfill these requirements. If suitable versions are found, the Operators are started within the desired namespace and a service account created for each Operator to create, watch, and modify the Kubernetes resources required.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209534954544\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.13. Required CRD fields\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 22%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 56%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 22%; \" class=\"col_3\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534948784\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534947696\" scope=\"col\">Description\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534946608\" scope=\"col\">Required/optional\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534948784\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Name\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534947696\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe full name of the CRD you require.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534946608\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534948784\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Version\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534947696\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe version of that object API.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534946608\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534948784\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534947696\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe Kubernetes object kind.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534946608\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534948784\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">DisplayName\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534947696\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA human readable version of the CRD.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534946608\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534948784\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Description\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534947696\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA summary of how the component fits in your larger architecture.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534946608\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example required CRD\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\"> required:\n - name: etcdclusters.etcd.database.coreos.com\n version: v1beta2\n kind: EtcdCluster\n displayName: etcd Cluster\n description: Represents a cluster of etcd nodes.\u003C/pre>\n\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"olm-dependency-resolution-crd-upgrades_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.8.3. CRD upgrades\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOLM upgrades a custom resource definition (CRD) immediately if it is owned by a singular cluster service version (CSV). If a CRD is owned by multiple CSVs, then the CRD is upgraded when it has satisfied all of the following backward compatible conditions:\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tAll existing serving versions in the current CRD are present in the new CRD.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tAll existing instances, or custom resources, that are associated with the serving versions of the CRD are valid when validated against the validation schema of the new CRD.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"olm-dependency-resolution-adding-new-crd-version_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.7.8.3.1. Adding a new CRD version\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\tTo add a new version of a CRD to your Operator:\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tAdd a new entry in the CRD resource under the \u003Ccode class=\"literal\">versions\u003C/code> section of your CSV.\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tFor example, if the current CRD has a version \u003Ccode class=\"literal\">v1alpha1\u003C/code> and you want to add a new version \u003Ccode class=\"literal\">v1beta1\u003C/code> and mark it as the new storage version, add a new entry for \u003Ccode class=\"literal\">v1beta1\u003C/code>:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">versions:\n - name: v1alpha1\n served: true\n storage: false\n - name: v1beta1 \u003Cspan id=\"CO53-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n served: true\n storage: true\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO53-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tNew entry.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tEnsure the referencing version of the CRD in the \u003Ccode class=\"literal\">owned\u003C/code> section of your CSV is updated if the CSV intends to use the new version:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">customresourcedefinitions:\n owned:\n - name: cluster.example.com\n version: v1beta1 \u003Cspan id=\"CO54-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n kind: cluster\n displayName: Cluster\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO54-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">version\u003C/code>.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tPush the updated CRD and CSV to your bundle.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"olm-dependency-resolution-removing-crd-version_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.7.8.3.2. Deprecating or removing a CRD version\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tOperator Lifecycle Manager (OLM) does not allow a serving version of a custom resource definition (CRD) to be removed right away. Instead, a deprecated version of the CRD must be first disabled by setting the \u003Ccode class=\"literal\">served\u003C/code> field in the CRD to \u003Ccode class=\"literal\">false\u003C/code>. Then, the non-serving version can be removed on the subsequent CRD upgrade.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\tTo deprecate and remove a specific version of a CRD:\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tMark the deprecated version as non-serving to indicate this version is no longer in use and may be removed in a subsequent upgrade. For example:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">versions:\n - name: v1alpha1\n served: false \u003Cspan id=\"CO55-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n storage: true\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO55-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tSet to \u003Ccode class=\"literal\">false\u003C/code>.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tSwitch the \u003Ccode class=\"literal\">storage\u003C/code> version to a serving version if the version to be deprecated is currently the \u003Ccode class=\"literal\">storage\u003C/code> version. For example:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">versions:\n - name: v1alpha1\n served: false\n storage: false \u003Cspan id=\"CO56-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n - name: v1beta1\n served: true\n storage: true \u003Cspan id=\"CO56-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO56-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003Ca href=\"#CO56-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tUpdate the \u003Ccode class=\"literal\">storage\u003C/code> fields accordingly.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\tTo remove a specific version that is or was the \u003Ccode class=\"literal\">storage\u003C/code> version from a CRD, that version must be removed from the \u003Ccode class=\"literal\">storedVersion\u003C/code> in the status of the CRD. OLM will attempt to do this for you if it detects a stored version no longer exists in the new CRD.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tUpgrade the CRD with the above changes.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tIn subsequent upgrade cycles, the non-serving version can be removed completely from the CRD. For example:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">versions:\n - name: v1beta1\n served: true\n storage: true\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tEnsure the referencing CRD version in the \u003Ccode class=\"literal\">owned\u003C/code> section of your CSV is updated accordingly if that version is removed from the CRD.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-crds-templates_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.8.4. CRD templates\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tUsers of your Operator must be made aware of which options are required versus optional. You can provide templates for each of your custom resource definitions (CRDs) with a minimum set of configuration as an annotation named \u003Ccode class=\"literal\">alm-examples\u003C/code>. Compatible UIs will pre-fill this template for users to further customize.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tThe annotation consists of a list of the kind, for example, the CRD name and the corresponding \u003Ccode class=\"literal\">metadata\u003C/code> and \u003Ccode class=\"literal\">spec\u003C/code> of the Kubernetes object.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tThe following full example provides templates for \u003Ccode class=\"literal\">EtcdCluster\u003C/code>, \u003Ccode class=\"literal\">EtcdBackup\u003C/code> and \u003Ccode class=\"literal\">EtcdRestore\u003C/code>:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-yaml\">metadata:\n annotations:\n alm-examples: &gt;-\n [{\"apiVersion\":\"etcd.database.coreos.com/v1beta2\",\"kind\":\"EtcdCluster\",\"metadata\":{\"name\":\"example\",\"namespace\":\"default\"},\"spec\":{\"size\":3,\"version\":\"3.2.13\"}},{\"apiVersion\":\"etcd.database.coreos.com/v1beta2\",\"kind\":\"EtcdRestore\",\"metadata\":{\"name\":\"example-etcd-cluster\"},\"spec\":{\"etcdCluster\":{\"name\":\"example-etcd-cluster\"},\"backupStorageType\":\"S3\",\"s3\":{\"path\":\"&lt;full-s3-path&gt;\",\"awsSecret\":\"&lt;aws-secret&gt;\"}}},{\"apiVersion\":\"etcd.database.coreos.com/v1beta2\",\"kind\":\"EtcdBackup\",\"metadata\":{\"name\":\"example-etcd-cluster-backup\"},\"spec\":{\"etcdEndpoints\":[\"&lt;etcd-cluster-endpoints&gt;\"],\"storageType\":\"S3\",\"s3\":{\"path\":\"&lt;full-s3-path&gt;\",\"awsSecret\":\"&lt;aws-secret&gt;\"}}}]\u003C/pre>\u003C/section>\u003Csection class=\"section\" id=\"osdk-hiding-internal-objects_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.8.5. Hiding internal objects\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tIt is common practice for Operators to use custom resource definitions (CRDs) internally to accomplish a task. These objects are not meant for users to manipulate and can be confusing to users of the Operator. For example, a database Operator might have a \u003Ccode class=\"literal\">Replication\u003C/code> CRD that is created whenever a user creates a Database object with \u003Ccode class=\"literal\">replication: true\u003C/code>.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tAs an Operator author, you can hide any CRDs in the user interface that are not meant for user manipulation by adding the \u003Ccode class=\"literal\">operators.operatorframework.io/internal-objects\u003C/code> annotation to the cluster service version (CSV) of your Operator.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tBefore marking one of your CRDs as internal, ensure that any debugging information or configuration that might be required to manage the application is reflected on the status or \u003Ccode class=\"literal\">spec\u003C/code> block of your CR, if applicable to your Operator.\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tAdd the \u003Ccode class=\"literal\">operators.operatorframework.io/internal-objects\u003C/code> annotation to the CSV of your Operator to specify any internal objects to hide in the user interface:\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Internal object annotation\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: operators.coreos.com/v1alpha1\nkind: ClusterServiceVersion\nmetadata:\n name: my-operator-v1.2.3\n annotations:\n operators.operatorframework.io/internal-objects: '[\"my.internal.crd1.io\",\"my.internal.crd2.io\"]' \u003Cspan id=\"CO57-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n...\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO57-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\tSet any internal CRDs as an array of strings.\n\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-init-resource_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.8.6. Initializing required custom resources\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tAn Operator might require the user to instantiate a custom resource before the Operator can be fully functional. However, it can be challenging for a user to determine what is required or how to define the resource.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tAs an Operator developer, you can specify a single required custom resource by adding \u003Ccode class=\"literal\">operatorframework.io/initialization-resource\u003C/code> to the cluster service version (CSV) during Operator installation. You are then prompted prompted to create the custom resource through a template that is provided in the CSV. The annotation must include a template that contains a complete YAML definition that is required to initialize the resource during installation.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tIf this annotation is defined, after installing the Operator from the OpenShift Container Platform web console, the user is prompted to create the resource using the template provided in the CSV.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tAdd the \u003Ccode class=\"literal\">operatorframework.io/initialization-resource\u003C/code> annotation to the CSV of your Operator to specify a required custom resource. For example, the following annotation requires the creation of a \u003Ccode class=\"literal\">StorageCluster\u003C/code> resource and provides a full YAML definition:\n\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Initialization resource annotation\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: operators.coreos.com/v1alpha1\nkind: ClusterServiceVersion\nmetadata:\n name: my-operator-v1.2.3\n annotations:\n operatorframework.io/initialization-resource: |-\n {\n \"apiVersion\": \"ocs.openshift.io/v1\",\n \"kind\": \"StorageCluster\",\n \"metadata\": {\n \"name\": \"example-storagecluster\"\n },\n \"spec\": {\n \"manageNodes\": false,\n \"monPVCTemplate\": {\n \"spec\": {\n \"accessModes\": [\n \"ReadWriteOnce\"\n ],\n \"resources\": {\n \"requests\": {\n \"storage\": \"10Gi\"\n }\n },\n \"storageClassName\": \"gp2\"\n }\n },\n \"storageDeviceSets\": [\n {\n \"count\": 3,\n \"dataPVCTemplate\": {\n \"spec\": {\n \"accessModes\": [\n \"ReadWriteOnce\"\n ],\n \"resources\": {\n \"requests\": {\n \"storage\": \"1Ti\"\n }\n },\n \"storageClassName\": \"gp2\",\n \"volumeMode\": \"Block\"\n }\n },\n \"name\": \"example-deviceset\",\n \"placement\": {},\n \"portable\": true,\n \"resources\": {}\n }\n ]\n }\n }\n...\u003C/pre>\n\n\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-apiservices_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.7.9. Understanding your API services\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tAs with CRDs, there are two types of API services that your Operator may use: \u003Cspan class=\"emphasis\">\u003Cem>owned\u003C/em>\u003C/span> and \u003Cspan class=\"emphasis\">\u003Cem>required\u003C/em>\u003C/span>.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-apiservices-owned_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.9.1. Owned API services\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tWhen a CSV owns an API service, it is responsible for describing the deployment of the extension \u003Ccode class=\"literal\">api-server\u003C/code> that backs it and the group/version/kind (GVK) it provides.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tAn API service is uniquely identified by the group/version it provides and can be listed multiple times to denote the different kinds it is expected to provide.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209534823136\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.14. Owned API service fields\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 22%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 56%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 22%; \" class=\"col_3\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534817360\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534816272\" scope=\"col\">Description\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534815184\" scope=\"col\">Required/optional\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Group\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tGroup that the API service provides, for example \u003Ccode class=\"literal\">database.example.com\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Version\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tVersion of the API service, for example \u003Ccode class=\"literal\">v1alpha1\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA kind that the API service is expected to provide.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Name\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe plural name for the API service provided.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">DeploymentName\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tName of the deployment defined by your CSV that corresponds to your API service (required for owned API services). During the CSV pending phase, the OLM Operator searches the \u003Ccode class=\"literal\">InstallStrategy\u003C/code> of your CSV for a \u003Ccode class=\"literal\">Deployment\u003C/code> spec with a matching name, and if not found, does not transition the CSV to the \"Install Ready\" phase.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">DisplayName\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA human readable version of your API service name, for example \u003Ccode class=\"literal\">MongoDB Standalone\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Description\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA short description of how this API service is used by the Operator or a description of the functionality provided by the API service.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Resources\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tYour API services own one or more types of Kubernetes objects. These are listed in the resources section to inform your users of the objects they might need to troubleshoot or how to connect to the application, such as the service or ingress rule that exposes a database.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003Cp>\n\t\t\t\t\t\t\t\t\t\tIt is recommended to only list out the objects that are important to a human, not an exhaustive list of everything you orchestrate. For example, do not list config maps that store internal state that are not meant to be modified by a user.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tOptional\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534817360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">SpecDescriptors\u003C/code>, \u003Ccode class=\"literal\">StatusDescriptors\u003C/code>, and \u003Ccode class=\"literal\">ActionDescriptors\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534816272\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tEssentially the same as for owned CRDs.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534815184\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tOptional\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Csection class=\"section\" id=\"osdk-apiservices-resource-creation_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.7.9.1.1. API service resource creation\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tOperator Lifecycle Manager (OLM) is responsible for creating or replacing the service and API service resources for each unique owned API service:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tService pod selectors are copied from the CSV deployment matching the \u003Ccode class=\"literal\">DeploymentName\u003C/code> field of the API service description.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tA new CA key/certificate pair is generated for each installation and the base64-encoded CA bundle is embedded in the respective API service resource.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-apiservices-service-certs_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.7.9.1.2. API service serving certificates\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tOLM handles generating a serving key/certificate pair whenever an owned API service is being installed. The serving certificate has a common name (CN) containing the hostname of the generated \u003Ccode class=\"literal\">Service\u003C/code> resource and is signed by the private key of the CA bundle embedded in the corresponding API service resource.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tThe certificate is stored as a type \u003Ccode class=\"literal\">kubernetes.io/tls\u003C/code> secret in the deployment namespace, and a volume named \u003Ccode class=\"literal\">apiservice-cert\u003C/code> is automatically appended to the volumes section of the deployment in the CSV matching the \u003Ccode class=\"literal\">DeploymentName\u003C/code> field of the API service description.\n\t\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\t\tIf one does not already exist, a volume mount with a matching name is also appended to all containers of that deployment. This allows users to define a volume mount with the expected name to accommodate any custom path requirements. The path of the generated volume mount defaults to \u003Ccode class=\"literal\">/apiserver.local.config/certificates\u003C/code> and any existing volume mounts with the same path are replaced.\n\t\t\t\t\t\t\u003C/p>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-apiservice-required_osdk-generating-csvs\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.7.9.2. Required API services\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOLM ensures all required CSVs have an API service that is available and all expected GVKs are discoverable before attempting installation. This allows a CSV to rely on specific kinds provided by API services it does not own.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209534742976\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.15. Required API service fields\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 22%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 56%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 22%; \" class=\"col_3\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534737200\" scope=\"col\">Field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534736112\" scope=\"col\">Description\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534735024\" scope=\"col\">Required/optional\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534737200\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Group\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534736112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tGroup that the API service provides, for example \u003Ccode class=\"literal\">database.example.com\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534735024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534737200\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Version\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534736112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tVersion of the API service, for example \u003Ccode class=\"literal\">v1alpha1\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534735024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534737200\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Kind\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534736112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA kind that the API service is expected to provide.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534735024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534737200\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">DisplayName\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534736112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA human readable version of your API service name, for example \u003Ccode class=\"literal\">MongoDB Standalone\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534735024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534737200\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Description\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534736112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tA short description of how this API service is used by the Operator or a description of the functionality provided by the API service.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534735024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-working-bundle-images\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.8. Working with bundle images\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tYou can use the Operator SDK to package, deploy, and upgrade Operators in the bundle format for use on Operator Lifecycle Manager (OLM).\n\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-bundle-operator_osdk-working-bundle-images\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.8.1. Bundling an Operator\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and Operator Lifecycle Manager (OLM). You can get your Operator ready for use on OLM by using the Operator SDK to build and push your Operator project as a bundle image.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) v4.8+ installed\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator project initialized by using the Operator SDK\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tIf your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> commands in your Operator project directory to build and push your Operator image. Modify the \u003Ccode class=\"literal\">IMG\u003C/code> argument in the following steps to reference a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tBuild the image:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-build IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe Dockerfile generated by the SDK for the Operator explicitly references \u003Ccode class=\"literal\">GOARCH=amd64\u003C/code> for \u003Ccode class=\"literal\">go build\u003C/code>. This can be amended to \u003Ccode class=\"literal\">GOARCH=$TARGETARCH\u003C/code> for non-AMD64 architectures. Docker will automatically set the environment variable to the value specified by \u003Ccode class=\"literal\">–platform\u003C/code>. With Buildah, the \u003Ccode class=\"literal\">–build-arg\u003C/code> will need to be used for the purpose. For more information, see \u003Ca class=\"link\" href=\"https://sdk.operatorframework.io/docs/advanced-topics/multi-arch/#supporting-multiple-architectures\">Multiple Architectures\u003C/a>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tPush the image to a repository:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make docker-push IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tCreate your Operator bundle manifest by running the \u003Ccode class=\"literal\">make bundle\u003C/code> command, which invokes several commands, including the Operator SDK \u003Ccode class=\"literal\">generate bundle\u003C/code> and \u003Ccode class=\"literal\">bundle validate\u003C/code> subcommands:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle IMG=&lt;registry&gt;/&lt;user&gt;/&lt;operator_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tBundle manifests for an Operator describe how to display, create, and manage an application. The \u003Ccode class=\"literal\">make bundle\u003C/code> command creates the following files and directories in your Operator project:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tA bundle manifests directory named \u003Ccode class=\"literal\">bundle/manifests\u003C/code> that contains a \u003Ccode class=\"literal\">ClusterServiceVersion\u003C/code> object\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tA bundle metadata directory named \u003Ccode class=\"literal\">bundle/metadata\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tAll custom resource definitions (CRDs) in a \u003Ccode class=\"literal\">config/crd\u003C/code> directory\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tA Dockerfile \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tThese files are then automatically validated by using \u003Ccode class=\"literal\">operator-sdk bundle validate\u003C/code> to ensure the on-disk bundle representation is correct.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tBuild and push your bundle image by running the following commands. OLM consumes Operator bundles using an index image, which reference one or more bundle images.\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tBuild the bundle image. Set \u003Ccode class=\"literal\">BUNDLE_IMG\u003C/code> with the details for the registry, user namespace, and image tag where you intend to push the image:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle-build BUNDLE_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tPush the bundle image:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ docker push &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-deploy-olm_osdk-working-bundle-images\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.8.2. Deploying an Operator with Operator Lifecycle Manager\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator Lifecycle Manager (OLM) helps you to install, update, and manage the lifecycle of Operators and their associated services on a Kubernetes cluster. OLM is installed by default on OpenShift Container Platform and runs as a Kubernetes extension so that you can use the web console and the OpenShift CLI (\u003Ccode class=\"literal\">oc\u003C/code>) for all Operator lifecycle management functions without any additional tools.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe Operator bundle format is the default packaging method for Operator SDK and OLM. You can use the Operator SDK to quickly run a bundle image on OLM to ensure that it runs properly.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator bundle image built and pushed to a registry\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use \u003Ccode class=\"literal\">apiextensions.k8s.io/v1\u003C/code> CRDs, for example OpenShift Container Platform 4.8)\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tLogged in to the cluster with \u003Ccode class=\"literal\">oc\u003C/code> using an account with \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tIf your Operator is Go-based, your project must be updated to use supported images for running on OpenShift Container Platform\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tEnter the following command to run the Operator on the cluster:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk run bundle \\\n [-n &lt;namespace&gt;] \\\u003Cspan id=\"CO58-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n &lt;registry&gt;/&lt;user&gt;/&lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO58-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tBy default, the command installs the Operator in the currently active project in your \u003Ccode class=\"literal\">~/.kube/config\u003C/code> file. You can add the \u003Ccode class=\"literal\">-n\u003C/code> flag to set a different namespace scope for the installation.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tThis command performs the following actions:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tCreate an index image referencing your bundle image. The index image is opaque and ephemeral, but accurately reflects how a bundle would be added to a catalog in production.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tCreate a catalog source that points to your new index image, which enables OperatorHub to discover your Operator.\n\t\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\t\tDeploy your Operator to your cluster by creating an \u003Ccode class=\"literal\">OperatorGroup\u003C/code>, \u003Ccode class=\"literal\">Subscription\u003C/code>, \u003Ccode class=\"literal\">InstallPlan\u003C/code>, and all other required objects, including RBAC.\n\t\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-publish-catalog_osdk-working-bundle-images\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.8.3. Publishing a catalog containing a bundled Operator\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tTo install and manage Operators, Operator Lifecycle Manager (OLM) requires that Operator bundles are listed in an index image, which is referenced by a catalog on the cluster. As an Operator author, you can use the Operator SDK to create an index containing the bundle for your Operator and all of its dependencies. This is useful for testing on remote clusters and publishing to container registries.\n\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tThe Operator SDK uses the \u003Ccode class=\"literal\">opm\u003C/code> CLI to facilitate index image creation. Experience with the \u003Ccode class=\"literal\">opm\u003C/code> command is not required. For advanced use cases, the \u003Ccode class=\"literal\">opm\u003C/code> command can be used directly instead of the Operator SDK.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator SDK CLI installed on a development workstation\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator bundle image built and pushed to a registry\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOLM installed on a Kubernetes-based cluster (v1.16.0 or later if you use \u003Ccode class=\"literal\">apiextensions.k8s.io/v1\u003C/code> CRDs, for example OpenShift Container Platform 4.8)\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tLogged in to the cluster with \u003Ccode class=\"literal\">oc\u003C/code> using an account with \u003Ccode class=\"literal\">cluster-admin\u003C/code> permissions\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tRun the following \u003Ccode class=\"literal\">make\u003C/code> command in your Operator project directory to build an index image containing your Operator bundle:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make catalog-build CATALOG_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;index_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\twhere the \u003Ccode class=\"literal\">CATALOG_IMG\u003C/code> argument references a repository that you have access to. You can obtain an account for storing containers at repository sites such as Quay.io.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tPush the built index image to a repository:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make catalog-push CATALOG_IMG=&lt;registry&gt;/&lt;user&gt;/&lt;index_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Crh-alert class=\"admonition tip\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Tip\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\tYou can use Operator SDK \u003Ccode class=\"literal\">make\u003C/code> commands together if you would rather perform multiple actions in sequence at once. For example, if you had not yet built a bundle image for your Operator project, you can build and push both a bundle image and an index image with the following syntax:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle-build bundle-push catalog-build catalog-push \\\n BUNDLE_IMG=&lt;bundle_image_pull_spec&gt; \\\n CATALOG_IMG=&lt;index_image_pull_spec&gt;\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tAlternatively, you can set the \u003Ccode class=\"literal\">IMAGE_TAG_BASE\u003C/code> field in your \u003Ccode class=\"literal\">Makefile\u003C/code> to an existing repository:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">IMAGE_TAG_BASE=quay.io/example/my-operator\u003C/pre>\u003Cp>\n\t\t\t\t\t\t\tYou can then use the following syntax to build and push images with automatically-generated names, such as \u003Ccode class=\"literal\">quay.io/example/my-operator-bundle:v0.0.1\u003C/code> for the bundle image and \u003Ccode class=\"literal\">quay.io/example/my-operator-catalog:v0.0.1\u003C/code> for the index image:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle-build bundle-push catalog-build catalog-push\u003C/pre>\u003C/div>\u003C/rh-alert>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tDefine a \u003Ccode class=\"literal\">CatalogSource\u003C/code> object that references the index image you just generated, and then create the object by using the \u003Ccode class=\"literal\">oc apply\u003C/code> command or web console:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example \u003Ccode class=\"literal\">CatalogSource\u003C/code> YAML\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: operators.coreos.com/v1alpha1\nkind: CatalogSource\nmetadata:\n name: cs-memcached\n namespace: default\nspec:\n displayName: My Test\n publisher: Company\n sourceType: grpc\n image: quay.io/example/memcached-catalog:v0.0.1 \u003Cspan id=\"CO59-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n updateStrategy:\n registryPoll:\n interval: 10m\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO59-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tSet \u003Ccode class=\"literal\">image\u003C/code> to the image pull spec you used previously with the \u003Ccode class=\"literal\">CATALOG_IMG\u003C/code> argument.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tCheck the catalog source:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get catalogsource\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME DISPLAY TYPE PUBLISHER AGE\ncs-memcached My Test grpc Company 4h31m\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Verification\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tInstall the Operator using your catalog:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tDefine an \u003Ccode class=\"literal\">OperatorGroup\u003C/code> object and create it by using the \u003Ccode class=\"literal\">oc apply\u003C/code> command or web console:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example \u003Ccode class=\"literal\">OperatorGroup\u003C/code> YAML\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: operators.coreos.com/v1\nkind: OperatorGroup\nmetadata:\n name: my-test\n namespace: default\nspec:\n targetNamespaces:\n - default\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tDefine a \u003Ccode class=\"literal\">Subscription\u003C/code> object and create it by using the \u003Ccode class=\"literal\">oc apply\u003C/code> command or web console:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example \u003Ccode class=\"literal\">Subscription\u003C/code> YAML\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: operators.coreos.com/v1alpha1\nkind: Subscription\nmetadata:\n name: catalogtest\n namespace: default\nspec:\n channel: \"alpha\"\n installPlanApproval: Manual\n name: catalog\n source: cs-memcached\n sourceNamespace: default\n startingCSV: memcached-operator.v0.0.1\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tVerify the installed Operator is running:\n\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tCheck the Operator group:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get og\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME AGE\nmy-test 4h40m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tCheck the cluster service version (CSV):\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get csv\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME DISPLAY VERSION REPLACES PHASE\nmemcached-operator.v0.0.1 Test 0.0.1 Succeeded\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tCheck the pods for the Operator:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ oc get pods\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">NAME READY STATUS RESTARTS AGE\n9098d908802769fbde8bd45255e69710a9f8420a8f3d814abe88b68f8ervdj6 0/1 Completed 0 4h33m\ncatalog-controller-manager-7fd5b7b987-69s4n 2/2 Running 0 4h32m\ncs-memcached-7622r 1/1 Running 0 4h33m\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-managing-custom-catalogs\">Managing custom catalogs\u003C/a> for details on direct usage of the \u003Ccode class=\"literal\">opm\u003C/code> CLI for more advanced use cases.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-bundle-upgrade-olm_osdk-working-bundle-images\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.8.4. Testing an Operator upgrade on Operator Lifecycle Manager\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tYou can quickly test upgrading your Operator by using Operator Lifecycle Manager (OLM) integration in the Operator SDK, without requiring you to manually manage index images and catalog sources.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">run bundle-upgrade\u003C/code> subcommand automates triggering an installed Operator to upgrade to a later version by specifying a bundle image for the later version.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator installed with OLM either by using the \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand or with traditional OLM installation\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tA bundle image that represents a later version of the installed Operator\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIf your Operator has not already been installed with OLM, install the earlier version either by using the \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand or with traditional OLM installation.\n\t\t\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\tIf the earlier version of the bundle was installed traditionally using OLM, the newer bundle that you intend to upgrade to must not exist in the index image referenced by the catalog source. Otherwise, running the \u003Ccode class=\"literal\">run bundle-upgrade\u003C/code> subcommand will cause the registry pod to fail because the newer bundle is already referenced by the index that provides the package and cluster service version (CSV).\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tFor example, you can use the following \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand for a Memcached Operator by specifying the earlier bundle image:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk run bundle &lt;registry&gt;/&lt;user&gt;/memcached-operator:v0.0.1\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">INFO[0009] Successfully created registry pod: quay-io-demo-memcached-operator-v0-0-1\nINFO[0009] Created CatalogSource: memcached-operator-catalog\nINFO[0010] OperatorGroup \"operator-sdk-og\" created\nINFO[0010] Created Subscription: memcached-operator-v0-0-1-sub\nINFO[0013] Approved InstallPlan install-bqggr for the Subscription: memcached-operator-v0-0-1-sub\nINFO[0013] Waiting for ClusterServiceVersion \"my-project/memcached-operator.v0.0.1\" to reach 'Succeeded' phase\nINFO[0013] Waiting for ClusterServiceVersion \"my-project/memcached-operator.v0.0.1\" to appear\nINFO[0019] Found ClusterServiceVersion \"my-project/memcached-operator.v0.0.1\" phase: Succeeded\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tUpgrade the installed Operator by specifying the bundle image for the later Operator version:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk run bundle-upgrade &lt;registry&gt;/&lt;user&gt;/memcached-operator:v0.0.2\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">INFO[0002] Found existing subscription with name memcached-operator-v0-0-1-sub and namespace my-project\nINFO[0002] Found existing catalog source with name memcached-operator-catalog and namespace my-project\nINFO[0009] Successfully created registry pod: quay-io-demo-memcached-operator-v0-0-2\nINFO[0009] Updated catalog source memcached-operator-catalog with address and annotations\nINFO[0010] Deleted previous registry pod with name \"quay-io-demo-memcached-operator-v0-0-1\"\nINFO[0041] Approved InstallPlan install-gvcjh for the Subscription: memcached-operator-v0-0-1-sub\nINFO[0042] Waiting for ClusterServiceVersion \"my-project/memcached-operator.v0.0.2\" to reach 'Succeeded' phase\nINFO[0042] Found ClusterServiceVersion \"my-project/memcached-operator.v0.0.2\" phase: InstallReady\nINFO[0043] Found ClusterServiceVersion \"my-project/memcached-operator.v0.0.2\" phase: Installing\nINFO[0044] Found ClusterServiceVersion \"my-project/memcached-operator.v0.0.2\" phase: Succeeded\nINFO[0044] Successfully upgraded to \"memcached-operator.v0.0.2\"\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tClean up the installed Operators:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk cleanup memcached-operator\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-adding-operators-to-a-cluster\">Traditional Operator installation with OLM\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-control-compat_osdk-working-bundle-images\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.8.5. Controlling Operator compatibility with OpenShift Container Platform versions\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Crh-alert class=\"admonition important\" state=\"warning\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Important\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tKubernetes periodically deprecates certain APIs that are removed in subsequent releases. If your Operator is using a deprecated API, it might no longer work after the OpenShift Container Platform cluster is upgraded to the Kubernetes version where the API has been removed.\n\t\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\t\tAs an Operator author, it is strongly recommended that you review the \u003Ca class=\"link\" href=\"https://kubernetes.io/docs/reference/using-api/deprecation-guide/\">Deprecated API Migration Guide\u003C/a> in Kubernetes documentation and keep your Operator projects up to date to avoid using deprecated and removed APIs. Ideally, you should update your Operator before the release of a future version of OpenShift Container Platform that would make the Operator incompatible.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cp>\n\t\t\t\t\tWhen an API is removed from an OpenShift Container Platform version, Operators running on that cluster version that are still using removed APIs will no longer work properly. As an Operator author, you should plan to update your Operator projects to accommodate API deprecation and removal to avoid interruptions for users of your Operator.\n\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition tip\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Tip\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\tYou can check the event alerts of your Operators running on OpenShift Container Platform 4.8 and later to find whether there are any warnings about APIs currently in use. The following alerts fire when they detect an API in use that will be removed in the next release:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">\u003Ccode class=\"literal\">APIRemovedInNextReleaseInUse\u003C/code>\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tAPIs that will be removed in the next OpenShift Container Platform release.\n\t\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">\u003Ccode class=\"literal\">APIRemovedInNextEUSReleaseInUse\u003C/code>\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\t\tAPIs that will be removed in the next OpenShift Container Platform \u003Ca class=\"link\" href=\"https://access.redhat.com/support/policy/updates/openshift#ocp4_phases\">Extended Update Support (EUS)\u003C/a> release.\n\t\t\t\t\t\t\t\u003C/dd>\u003C/dl>\u003C/div>\u003C/div>\u003C/rh-alert>\u003Cp>\n\t\t\t\t\tIf a cluster administrator has installed your Operator, before they upgrade to the next version of OpenShift Container Platform, they must ensure a version of your Operator is installed that is compatible with that next cluster version. While it is recommended that you update your Operator projects to no longer use deprecated or removed APIs, if you still need to publish your Operator bundles with removed APIs for continued use on earlier versions of OpenShift Container Platform, ensure that the bundle is configured accordingly.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe following procedure helps prevent administrators from installing versions of your Operator on an incompatible version of OpenShift Container Platform. These steps also prevent administrators from upgrading to a newer version of OpenShift Container Platform that is incompatible with the version of your Operator that is currently installed on their cluster.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThis procedure is also useful when you know that the current version of your Operator will not work well, for any reason, on a specific OpenShift Container Platform version. By defining the cluster versions where the Operator should be distributed, you ensure that the Operator does not appear in a catalog of a cluster version which is outside of the allowed range.\n\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition important\" state=\"warning\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Important\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tOperators that use deprecated APIs can adversely impact critical workloads when cluster administrators upgrade to a future version of OpenShift Container Platform where the API is no longer supported. If your Operator is using deprecated APIs, you should configure the following settings in your Operator project as soon as possible.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tAn existing Operator project\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIf you know that a specific bundle of your Operator is not supported and will not work correctly on OpenShift Container Platform later than a certain cluster version, configure the maximum version of OpenShift Container Platform that your Operator is compatible with. In your Operator project’s cluster service version (CSV), set the \u003Ccode class=\"literal\">olm.maxOpenShiftVersion\u003C/code> annotation to prevent administrators from upgrading their cluster before upgrading the installed Operator to a compatible version:\n\t\t\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition important\" state=\"warning\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Important\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\tYou must use \u003Ccode class=\"literal\">olm.maxOpenShiftVersion\u003C/code> annotation only if your Operator bundle version cannot work in later versions. Be aware that cluster admins cannot upgrade their clusters with your solution installed. If you do not provide later version and a valid upgrade path, cluster admins may uninstall your Operator and can upgrade the cluster version.\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example CSV with \u003Ccode class=\"literal\">olm.maxOpenShiftVersion\u003C/code> annotation\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">apiVersion: operators.coreos.com/v1alpha1\nkind: ClusterServiceVersion\nmetadata:\n annotations:\n \"olm.properties\": '[{\"type\": \"olm.maxOpenShiftVersion\", \"value\": \"&lt;cluster_version&gt;\"}]' \u003Cspan id=\"CO60-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO60-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tSpecify the maximum cluster version of OpenShift Container Platform that your Operator is compatible with. For example, setting \u003Ccode class=\"literal\">value\u003C/code> to \u003Ccode class=\"literal\">4.8\u003C/code> prevents cluster upgrades to OpenShift Container Platform versions later than 4.8 when this bundle is installed on a cluster.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tIf your bundle is intended for distribution in a Red Hat-provided Operator catalog, configure the compatible versions of OpenShift Container Platform for your Operator by setting the following properties. This configuration ensures your Operator is only included in catalogs that target compatible versions of OpenShift Container Platform:\n\t\t\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\t\tThis step is only valid when publishing Operators in Red Hat-provided catalogs. If your bundle is only intended for distribution in a custom catalog, you can skip this step. For more details, see \"Red Hat-provided Operator catalogs\".\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Cdiv class=\"orderedlist\">\u003Col class=\"orderedlist\" type=\"a\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tSet the \u003Ccode class=\"literal\">com.redhat.openshift.versions\u003C/code> annotation in your project’s \u003Ccode class=\"literal\">bundle/metadata/annotations.yaml\u003C/code> file:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example \u003Ccode class=\"literal\">bundle/metadata/annotations.yaml\u003C/code> file with compatible versions\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">com.redhat.openshift.versions: \"v4.6-v4.8\" \u003Cspan id=\"CO61-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO61-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tSet to a range or single version.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\t\tTo prevent your bundle from being carried on to an incompatible version of OpenShift Container Platform, ensure that the index image is generated with the proper \u003Ccode class=\"literal\">com.redhat.openshift.versions\u003C/code> label in your Operator’s bundle image. For example, if your project was generated using the Operator SDK, update the \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code> file:\n\t\t\t\t\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code> with compatible versions\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">LABEL com.redhat.openshift.versions=\"&lt;versions&gt;\" \u003Cspan id=\"CO62-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\u003C/pre>\n\n\t\t\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO62-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\t\t\tSet to a range or single version, for example, \u003Ccode class=\"literal\">v4.6-v4.8\u003C/code>. This setting defines the cluster versions where the Operator should be distributed, and the Operator does not appear in a catalog of a cluster version which is outside of the range.\n\t\t\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003C/li>\u003C/ol>\u003C/div>\u003Cp>\n\t\t\t\t\tYou can now bundle a new version of your Operator and publish the updated version to a catalog for distribution.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://redhat-connect.gitbook.io/certified-operator-guide/ocp-deployment/operator-metadata/bundle-directory/managing-openshift-versions\">Managing OpenShift Versions\u003C/a> in the \u003Cspan class=\"emphasis\">\u003Cem>Certified Operator Build Guide\u003C/em>\u003C/span>\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-upgrading-operators\">Updating installed Operators\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-rh-catalogs\">Red Hat-provided Operator catalogs\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section _additional-resources\" id=\"osdk-working-bundle-images-additional-resources\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.8.6. Additional resources\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-bundle-format_olm-packaging-format\">Operator Framework packaging formats\u003C/a> for details on the bundle format.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-managing-custom-catalogs\">Managing custom catalogs\u003C/a> for details on adding bundle images to index images by using the \u003Ccode class=\"literal\">opm\u003C/code> command.\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-workflow\">Operator Lifecycle Manager workflow\u003C/a> for details on how upgrades work for installed Operators.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.9. Validating Operators using the scorecard tool\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tAs an Operator author, you can use the scorecard tool in the Operator SDK to do the following tasks:\n\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\tValidate that your Operator project is free of syntax errors and packaged correctly\n\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\tReview suggestions about ways you can improve your Operator\n\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"osdk-about-scorecard_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.1. About the scorecard tool\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tWhile the Operator SDK \u003Ccode class=\"literal\">bundle validate\u003C/code> subcommand can validate local bundle directories and remote bundle images for content and structure, you can use the \u003Ccode class=\"literal\">scorecard\u003C/code> command to run tests on your Operator based on a configuration file and test images. These tests are implemented within test images that are configured and constructed to be executed by the scorecard.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe scorecard assumes it is run with access to a configured Kubernetes cluster, such as OpenShift Container Platform. The scorecard runs each test within a pod, from which pod logs are aggregated and test results are sent to the console. The scorecard has built-in basic and Operator Lifecycle Manager (OLM) tests and also provides a means to execute custom test definitions.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Scorecard workflow\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tCreate all resources required by any related custom resources (CRs) and the Operator\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tCreate a proxy container in the deployment of the Operator to record calls to the API server and run tests\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tExamine parameters in the CRs\n\t\t\t\t\t\t\u003C/li>\u003C/ol>\u003C/div>\u003Cp>\n\t\t\t\t\tThe scorecard tests make no assumptions as to the state of the Operator being tested. Creating Operators and CRs for an Operators are beyond the scope of the scorecard itself. Scorecard tests can, however, create whatever resources they require if the tests are designed for resource creation.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>\u003Ccode class=\"literal\">scorecard\u003C/code> command syntax\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; [flags]\u003C/pre>\n\n\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp>\n\t\t\t\t\tThe scorecard requires a positional argument for either the on-disk path to your Operator bundle or the name of a bundle image.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tFor further information about the flags, run:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk scorecard -h\u003C/pre>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard-config_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.2. Scorecard configuration\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe scorecard tool uses a configuration that allows you to configure internal plugins, as well as several global configuration options. Tests are driven by a configuration file named \u003Ccode class=\"literal\">config.yaml\u003C/code>, which is generated by the \u003Ccode class=\"literal\">make bundle\u003C/code> command, located in your \u003Ccode class=\"literal\">bundle/\u003C/code> directory:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">./bundle\n...\n└── tests\n └── scorecard\n └── config.yaml\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example scorecard configuration file\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-yaml\">kind: Configuration\napiversion: scorecard.operatorframework.io/v1alpha3\nmetadata:\n name: config\nstages:\n- parallel: true\n tests:\n - image: quay.io/operator-framework/scorecard-test:v1.8.0\n entrypoint:\n - scorecard-test\n - basic-check-spec\n labels:\n suite: basic\n test: basic-check-spec-test\n - image: quay.io/operator-framework/scorecard-test:v1.8.0\n entrypoint:\n - scorecard-test\n - olm-bundle-validation\n labels:\n suite: olm\n test: olm-bundle-validation-test\u003C/pre>\n\n\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp>\n\t\t\t\t\tThe configuration file defines each test that scorecard can execute. The following fields of the scorecard configuration file define the test as follows:\n\t\t\t\t\u003C/p>\u003Crh-table>\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccolgroup>\u003Ccol style=\"width: 30%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 70%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534436000\" scope=\"col\">Configuration field\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534434912\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534436000\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">image\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534434912\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tTest container image name that implements a test\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534436000\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">entrypoint\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534434912\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tCommand and arguments that are invoked in the test image to execute a test\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534436000\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">labels\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534434912\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tScorecard-defined or custom labels that select which tests to run\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard-tests_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.3. Built-in scorecard tests\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe scorecard ships with pre-defined tests that are arranged into suites: the basic test suite and the Operator Lifecycle Manager (OLM) suite.\n\t\t\t\t\u003C/p>\u003Crh-table id=\"osdk-scorecard-basic-tests_osdk-scorecard\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.16. Basic test suite\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 23%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 54%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 23%; \" class=\"col_3\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534411664\" scope=\"col\">Test\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534410576\" scope=\"col\">Description\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534409488\" scope=\"col\">Short name\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534411664\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tSpec Block Exists\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534410576\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThis test checks the custom resource (CR) created in the cluster to make sure that all CRs have a \u003Ccode class=\"literal\">spec\u003C/code> block.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534409488\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">basic-check-spec-test\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Crh-table id=\"osdk-scorecard-olm-tests_osdk-scorecard\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.17. OLM test suite\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 23%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 54%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 23%; \" class=\"col_3\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534394736\" scope=\"col\">Test\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534393648\" scope=\"col\">Description\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534392560\" scope=\"col\">Short name\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534394736\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tBundle Validation\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534393648\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThis test validates the bundle manifests found in the bundle that is passed into scorecard. If the bundle contents contain errors, then the test result output includes the validator log as well as error messages from the validation library.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534392560\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">olm-bundle-validation-test\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534394736\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tProvided APIs Have Validation\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534393648\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThis test verifies that the custom resource definitions (CRDs) for the provided CRs contain a validation section and that there is validation for each \u003Ccode class=\"literal\">spec\u003C/code> and \u003Ccode class=\"literal\">status\u003C/code> field detected in the CR.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534392560\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">olm-crds-have-validation-test\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534394736\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tOwned CRDs Have Resources Listed\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534393648\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThis test makes sure that the CRDs for each CR provided via the \u003Ccode class=\"literal\">cr-manifest\u003C/code> option have a \u003Ccode class=\"literal\">resources\u003C/code> subsection in the \u003Ccode class=\"literal\">owned\u003C/code> CRDs section of the ClusterServiceVersion (CSV). If the test detects used resources that are not listed in the resources section, it lists them in the suggestions at the end of the test. Users are required to fill out the resources section after initial code generation for this test to pass.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534392560\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">olm-crds-have-resources-test\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534394736\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tSpec Fields With Descriptors\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534393648\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThis test verifies that every field in the CRs \u003Ccode class=\"literal\">spec\u003C/code> sections has a corresponding descriptor listed in the CSV.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534392560\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">olm-spec-descriptors-test\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534394736\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tStatus Fields With Descriptors\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534393648\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tThis test verifies that every field in the CRs \u003Ccode class=\"literal\">status\u003C/code> sections have a corresponding descriptor listed in the CSV.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534392560\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">olm-status-descriptors-test\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard-run_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.4. Running the scorecard tool\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tA default set of Kustomize files are generated by the Operator SDK after running the \u003Ccode class=\"literal\">init\u003C/code> command. The default \u003Ccode class=\"literal\">bundle/tests/scorecard/config.yaml\u003C/code> file that is generated can be immediately used to run the scorecard tool against your Operator, or you can modify this file to your test specifications.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator project generated by using the Operator SDK\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tGenerate or regenerate your bundle manifests and metadata for your Operator:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ make bundle\u003C/pre>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tThis command automatically adds scorecard annotations to your bundle metadata, which is used by the \u003Ccode class=\"literal\">scorecard\u003C/code> command to run tests.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tRun the scorecard against the on-disk path to your Operator bundle or the name of a bundle image:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt;\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard-output_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.5. Scorecard output\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">--output\u003C/code> flag for the \u003Ccode class=\"literal\">scorecard\u003C/code> command specifies the scorecard results output format: either \u003Ccode class=\"literal\">text\u003C/code> or \u003Ccode class=\"literal\">json\u003C/code>.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209534341744\">\u003Cp class=\"title\">\u003Cstrong>Example 5.29. Example JSON output snippet\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-json\">{\n \"apiVersion\": \"scorecard.operatorframework.io/v1alpha3\",\n \"kind\": \"TestList\",\n \"items\": [\n {\n \"kind\": \"Test\",\n \"apiVersion\": \"scorecard.operatorframework.io/v1alpha3\",\n \"spec\": {\n \"image\": \"quay.io/operator-framework/scorecard-test:v1.8.0\",\n \"entrypoint\": [\n \"scorecard-test\",\n \"olm-bundle-validation\"\n ],\n \"labels\": {\n \"suite\": \"olm\",\n \"test\": \"olm-bundle-validation-test\"\n }\n },\n \"status\": {\n \"results\": [\n {\n \"name\": \"olm-bundle-validation\",\n \"log\": \"time=\\\"2020-06-10T19:02:49Z\\\" level=debug msg=\\\"Found manifests directory\\\" name=bundle-test\\ntime=\\\"2020-06-10T19:02:49Z\\\" level=debug msg=\\\"Found metadata directory\\\" name=bundle-test\\ntime=\\\"2020-06-10T19:02:49Z\\\" level=debug msg=\\\"Getting mediaType info from manifests directory\\\" name=bundle-test\\ntime=\\\"2020-06-10T19:02:49Z\\\" level=info msg=\\\"Found annotations file\\\" name=bundle-test\\ntime=\\\"2020-06-10T19:02:49Z\\\" level=info msg=\\\"Could not find optional dependencies file\\\" name=bundle-test\\n\",\n \"state\": \"pass\"\n }\n ]\n }\n }\n ]\n}\u003C/pre>\u003C/div>\u003C/div>\u003Cdiv class=\"example\" id=\"idm140209534338576\">\u003Cp class=\"title\">\u003Cstrong>Example 5.30. Example text output snippet\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-text\">--------------------------------------------------------------------------------\nImage: quay.io/operator-framework/scorecard-test:v1.8.0\nEntrypoint: [scorecard-test olm-bundle-validation]\nLabels:\n\t\"suite\":\"olm\"\n\t\"test\":\"olm-bundle-validation-test\"\nResults:\n\tName: olm-bundle-validation\n\tState: pass\n\tLog:\n\t\ttime=\"2020-07-15T03:19:02Z\" level=debug msg=\"Found manifests directory\" name=bundle-test\n\t\ttime=\"2020-07-15T03:19:02Z\" level=debug msg=\"Found metadata directory\" name=bundle-test\n\t\ttime=\"2020-07-15T03:19:02Z\" level=debug msg=\"Getting mediaType info from manifests directory\" name=bundle-test\n\t\ttime=\"2020-07-15T03:19:02Z\" level=info msg=\"Found annotations file\" name=bundle-test\n\t\ttime=\"2020-07-15T03:19:02Z\" level=info msg=\"Could not find optional dependencies file\" name=bundle-test\u003C/pre>\u003C/div>\u003C/div>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\tThe output format spec matches the \u003Ca class=\"link\" href=\"https://pkg.go.dev/github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3#Test\">\u003Ccode class=\"literal\">Test\u003C/code>\u003C/a> type layout.\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard-select-tests_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.6. Selecting tests\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tScorecard tests are selected by setting the \u003Ccode class=\"literal\">--selector\u003C/code> CLI flag to a set of label strings. If a selector flag is not supplied, then all the tests within the scorecard configuration file are run.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tTests are run serially with test results being aggregated by the scorecard and written to standard output, or \u003Cspan class=\"emphasis\">\u003Cem>stdout\u003C/em>\u003C/span>.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"orderedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Col class=\"orderedlist\" type=\"1\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tTo select a single test, for example \u003Ccode class=\"literal\">basic-check-spec-test\u003C/code>, specify the test by using the \u003Ccode class=\"literal\">--selector\u003C/code> flag:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; \\\n -o text \\\n --selector=test=basic-check-spec-test\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tTo select a suite of tests, for example \u003Ccode class=\"literal\">olm\u003C/code>, specify a label that is used by all of the OLM tests:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; \\\n -o text \\\n --selector=suite=olm\u003C/pre>\u003C/li>\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tTo select multiple tests, specify the test names by using the \u003Ccode class=\"literal\">selector\u003C/code> flag using the following syntax:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk scorecard &lt;bundle_dir_or_image&gt; \\\n -o text \\\n --selector='test in (basic-check-spec-test,olm-bundle-validation-test)'\u003C/pre>\u003C/li>\u003C/ol>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard-parallel_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.7. Enabling parallel testing\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tAs an Operator author, you can define separate stages for your tests using the scorecard configuration file. Stages run sequentially in the order they are defined in the configuration file. A stage contains a list of tests and a configurable \u003Ccode class=\"literal\">parallel\u003C/code> setting.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tBy default, or when a stage explicitly sets \u003Ccode class=\"literal\">parallel\u003C/code> to \u003Ccode class=\"literal\">false\u003C/code>, tests in a stage are run sequentially in the order they are defined in the configuration file. Running tests one at a time is helpful to guarantee that no two tests interact and conflict with each other.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tHowever, if tests are designed to be fully isolated, they can be parallelized.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tTo run a set of isolated tests in parallel, include them in the same stage and set \u003Ccode class=\"literal\">parallel\u003C/code> to \u003Ccode class=\"literal\">true\u003C/code>:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">apiVersion: scorecard.operatorframework.io/v1alpha3\nkind: Configuration\nmetadata:\n name: config\nstages:\n- parallel: true \u003Cspan id=\"CO63-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n tests:\n - entrypoint:\n - scorecard-test\n - basic-check-spec\n image: quay.io/operator-framework/scorecard-test:v1.8.0\n labels:\n suite: basic\n test: basic-check-spec-test\n - entrypoint:\n - scorecard-test\n - olm-bundle-validation\n image: quay.io/operator-framework/scorecard-test:v1.8.0\n labels:\n suite: olm\n test: olm-bundle-validation-test\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO63-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tEnables parallel testing\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tAll tests in a parallel stage are executed simultaneously, and scorecard waits for all of them to finish before proceding to the next stage. This can make your tests run much faster.\n\t\t\t\t\t\t\u003C/p>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-scorecard-custom-tests_osdk-scorecard\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.9.8. Custom scorecard tests\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe scorecard tool can run custom tests that follow these mandated conventions:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tTests are implemented within a container image\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tTests accept an entrypoint which include a command and arguments\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tTests produce \u003Ccode class=\"literal\">v1alpha3\u003C/code> scorecard output in JSON format with no extraneous logging in the test output\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tTests can obtain the bundle contents at a shared mount point of \u003Ccode class=\"literal\">/bundle\u003C/code>\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tTests can access the Kubernetes API using an in-cluster client connection\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cp>\n\t\t\t\t\tWriting custom tests in other programming languages is possible if the test image follows the above guidelines.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe following example shows of a custom test image written in Go:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"example\" id=\"idm140209534297216\">\u003Cp class=\"title\">\u003Cstrong>Example 5.31. Example custom scorecard test\u003C/strong>\u003C/p>\u003Cdiv class=\"example-contents\">\u003Cpre class=\"programlisting language-go\">// Copyright 2020 The Operator-SDK Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tscapiv1alpha3 \"github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3\"\n\tapimanifests \"github.com/operator-framework/api/pkg/manifests\"\n)\n\n// This is the custom scorecard test example binary\n// As with the Redhat scorecard test image, the bundle that is under\n// test is expected to be mounted so that tests can inspect the\n// bundle contents as part of their test implementations.\n// The actual test is to be run is named and that name is passed\n// as an argument to this binary. This argument mechanism allows\n// this binary to run various tests all from within a single\n// test image.\n\nconst PodBundleRoot = \"/bundle\"\n\nfunc main() {\n\tentrypoint := os.Args[1:]\n\tif len(entrypoint) == 0 {\n\t\tlog.Fatal(\"Test name argument is required\")\n\t}\n\n\t// Read the pod's untar'd bundle from a well-known path.\n\tcfg, err := apimanifests.GetBundleFromDir(PodBundleRoot)\n\tif err != nil {\n\t\tlog.Fatal(err.Error())\n\t}\n\n\tvar result scapiv1alpha3.TestStatus\n\n\t// Names of the custom tests which would be passed in the\n\t// `operator-sdk` command.\n\tswitch entrypoint[0] {\n\tcase CustomTest1Name:\n\t\tresult = CustomTest1(cfg)\n\tcase CustomTest2Name:\n\t\tresult = CustomTest2(cfg)\n\tdefault:\n\t\tresult = printValidTests()\n\t}\n\n\t// Convert scapiv1alpha3.TestResult to json.\n\tprettyJSON, err := json.MarshalIndent(result, \"\", \" \")\n\tif err != nil {\n\t\tlog.Fatal(\"Failed to generate json\", err)\n\t}\n\tfmt.Printf(\"%s\\n\", string(prettyJSON))\n\n}\n\n// printValidTests will print out full list of test names to give a hint to the end user on what the valid tests are.\nfunc printValidTests() scapiv1alpha3.TestStatus {\n\tresult := scapiv1alpha3.TestResult{}\n\tresult.State = scapiv1alpha3.FailState\n\tresult.Errors = make([]string, 0)\n\tresult.Suggestions = make([]string, 0)\n\n\tstr := fmt.Sprintf(\"Valid tests for this image include: %s %s\",\n\t\tCustomTest1Name,\n\t\tCustomTest2Name)\n\tresult.Errors = append(result.Errors, str)\n\treturn scapiv1alpha3.TestStatus{\n\t\tResults: []scapiv1alpha3.TestResult{result},\n\t}\n}\n\nconst (\n\tCustomTest1Name = \"customtest1\"\n\tCustomTest2Name = \"customtest2\"\n)\n\n// Define any operator specific custom tests here.\n// CustomTest1 and CustomTest2 are example test functions. Relevant operator specific\n// test logic is to be implemented in similarly.\n\nfunc CustomTest1(bundle *apimanifests.Bundle) scapiv1alpha3.TestStatus {\n\tr := scapiv1alpha3.TestResult{}\n\tr.Name = CustomTest1Name\n\tr.State = scapiv1alpha3.PassState\n\tr.Errors = make([]string, 0)\n\tr.Suggestions = make([]string, 0)\n\talmExamples := bundle.CSV.GetAnnotations()[\"alm-examples\"]\n\tif almExamples == \"\" {\n\t\tfmt.Println(\"no alm-examples in the bundle CSV\")\n\t}\n\n\treturn wrapResult(r)\n}\n\nfunc CustomTest2(bundle *apimanifests.Bundle) scapiv1alpha3.TestStatus {\n\tr := scapiv1alpha3.TestResult{}\n\tr.Name = CustomTest2Name\n\tr.State = scapiv1alpha3.PassState\n\tr.Errors = make([]string, 0)\n\tr.Suggestions = make([]string, 0)\n\talmExamples := bundle.CSV.GetAnnotations()[\"alm-examples\"]\n\tif almExamples == \"\" {\n\t\tfmt.Println(\"no alm-examples in the bundle CSV\")\n\t}\n\treturn wrapResult(r)\n}\n\nfunc wrapResult(r scapiv1alpha3.TestResult) scapiv1alpha3.TestStatus {\n\treturn scapiv1alpha3.TestStatus{\n\t\tResults: []scapiv1alpha3.TestResult{r},\n\t}\n}\u003C/pre>\u003C/div>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-monitoring-prometheus\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.10. Configuring built-in monitoring with Prometheus\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tThis guide describes the built-in monitoring support provided by the Operator SDK using the Prometheus Operator and details usage for Operator authors.\n\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-monitoring-prometheus-operator-support_osdk-monitoring-prometheus\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.10.1. Prometheus Operator support\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\u003Ca class=\"link\" href=\"https://prometheus.io/\">Prometheus\u003C/a> is an open-source systems monitoring and alerting toolkit. The Prometheus Operator creates, configures, and manages Prometheus clusters running on Kubernetes-based clusters, such as OpenShift Container Platform.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tHelper functions exist in the Operator SDK by default to automatically set up metrics in any generated Go-based Operator for use on clusters where the Prometheus Operator is deployed.\n\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-monitoring-prometheus-metrics-helper_osdk-monitoring-prometheus\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.10.2. Metrics helper\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tIn Go-based Operators generated using the Operator SDK, the following function exposes general metrics about the running program:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">func ExposeMetricsPort(ctx context.Context, port int32) (*v1.Service, error)\u003C/pre>\u003Cp>\n\t\t\t\t\tThese metrics are inherited from the \u003Ccode class=\"literal\">controller-runtime\u003C/code> library API. By default, the metrics are served on \u003Ccode class=\"literal\">0.0.0.0:8383/metrics\u003C/code>.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tA \u003Ccode class=\"literal\">Service\u003C/code> object is created with the metrics port exposed, which can be then accessed by Prometheus. The \u003Ccode class=\"literal\">Service\u003C/code> object is garbage collected when the leader pod’s \u003Ccode class=\"literal\">root\u003C/code> owner is deleted.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThe following example is present in the \u003Ccode class=\"literal\">cmd/manager/main.go\u003C/code> file in all Operators generated using the Operator SDK:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import(\n \"github.com/operator-framework/operator-sdk/pkg/metrics\"\n \"machine.openshift.io/controller-runtime/pkg/manager\"\n)\n\nvar (\n // Change the below variables to serve metrics on a different host or port.\n metricsHost = \"0.0.0.0\" \u003Cspan id=\"CO64-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n metricsPort int32 = 8383 \u003Cspan id=\"CO64-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\n)\n...\nfunc main() {\n ...\n // Pass metrics address to controller-runtime manager\n mgr, err := manager.New(cfg, manager.Options{\n Namespace: namespace,\n MetricsBindAddress: fmt.Sprintf(\"%s:%d\", metricsHost, metricsPort),\n })\n\n ...\n // Create Service object to expose the metrics port.\n _, err = metrics.ExposeMetricsPort(ctx, metricsPort)\n if err != nil {\n // handle error\n log.Info(err.Error())\n }\n ...\n}\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO64-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\tThe host that the metrics are exposed on.\n\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO64-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\tThe port that the metrics are exposed on.\n\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003Csection class=\"section\" id=\"osdk-monitoring-prometheus-metrics-helper-modifying-port_osdk-monitoring-prometheus\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.10.2.1. Modifying the metrics port\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOperator authors can modify the port that metrics are exposed on.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tGo-based Operator generated using the Operator SDK\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tKubernetes-based cluster with the Prometheus Operator deployed\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tIn the \u003Ccode class=\"literal\">cmd/manager/main.go\u003C/code> file of the generated Operator, change the value of \u003Ccode class=\"literal\">metricsPort\u003C/code> in the following line:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">var metricsPort int32 = 8383\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-monitoring-prometheus-servicemonitor_osdk-monitoring-prometheus\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.10.3. Service monitors\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tA \u003Ccode class=\"literal\">ServiceMonitor\u003C/code> is a custom resource provided by the Prometheus Operator that discovers the \u003Ccode class=\"literal\">Endpoints\u003C/code> in \u003Ccode class=\"literal\">Service\u003C/code> objects and configures Prometheus to monitor those pods.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tIn Go-based Operators generated using the Operator SDK, the \u003Ccode class=\"literal\">GenerateServiceMonitor()\u003C/code> helper function can take a \u003Ccode class=\"literal\">Service\u003C/code> object and generate a \u003Ccode class=\"literal\">ServiceMonitor\u003C/code> object based on it.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee the \u003Ca class=\"link\" href=\"https://github.com/coreos/prometheus-operator/blob/7a25bf6b6bb2347dacb235659b73bc210117acc7/Documentation/design.md#servicemonitor\">Prometheus Operator documentation\u003C/a> for more information about the \u003Ccode class=\"literal\">ServiceMonitor\u003C/code> custom resource definition (CRD).\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Csection class=\"section\" id=\"osdk-monitoring-prometheus-servicemonitor-creating_osdk-monitoring-prometheus\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.10.3.1. Creating service monitors\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tOperator authors can add service target discovery of created monitoring services using the \u003Ccode class=\"literal\">metrics.CreateServiceMonitor()\u003C/code> helper function, which accepts the newly created service.\n\t\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tGo-based Operator generated using the Operator SDK\n\t\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tKubernetes-based cluster with the Prometheus Operator deployed\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\t\tAdd the \u003Ccode class=\"literal\">metrics.CreateServiceMonitor()\u003C/code> helper function to your Operator code:\n\t\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import(\n \"k8s.io/api/core/v1\"\n \"github.com/operator-framework/operator-sdk/pkg/metrics\"\n \"machine.openshift.io/controller-runtime/pkg/client/config\"\n)\nfunc main() {\n\n ...\n // Populate below with the Service(s) for which you want to create ServiceMonitors.\n services := []*v1.Service{}\n // Create one ServiceMonitor per application per namespace.\n // Change the below value to name of the Namespace you want the ServiceMonitor to be created in.\n ns := \"default\"\n // restConfig is used for talking to the Kubernetes apiserver\n restConfig := config.GetConfig()\n\n // Pass the Service(s) to the helper function, which in turn returns the array of ServiceMonitor objects.\n serviceMonitors, err := metrics.CreateServiceMonitors(restConfig, ns, services)\n if err != nil {\n // Handle errors here.\n }\n ...\n}\u003C/pre>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-leader-election\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.11. Configuring leader election\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tDuring the lifecycle of an Operator, it is possible that there may be more than one instance running at any given time, for example when rolling out an upgrade for the Operator. In such a scenario, it is necessary to avoid contention between multiple Operator instances using leader election. This ensures only one leader instance handles the reconciliation while the other instances are inactive but ready to take over when the leader steps down.\n\t\t\t\u003C/p>\u003Cp>\n\t\t\t\tThere are two different leader election implementations to choose from, each with its own trade-off:\n\t\t\t\u003C/p>\u003Cdiv class=\"variablelist\">\u003Cdl class=\"variablelist\">\u003Cdt>\u003Cspan class=\"term\">Leader-for-life\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\tThe leader pod only gives up leadership, using garbage collection, when it is deleted. This implementation precludes the possibility of two instances mistakenly running as leaders, a state also known as split brain. However, this method can be subject to a delay in electing a new leader. For example, when the leader pod is on an unresponsive or partitioned node, the \u003Ca class=\"link\" href=\"https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/#options\">\u003Ccode class=\"literal\">pod-eviction-timeout\u003C/code>\u003C/a> dictates long how it takes for the leader pod to be deleted from the node and step down, with a default of \u003Ccode class=\"literal\">5m\u003C/code>. See the \u003Ca class=\"link\" href=\"https://godoc.org/github.com/operator-framework/operator-sdk/pkg/leader\">Leader-for-life\u003C/a> Go documentation for more.\n\t\t\t\t\t\t\u003C/dd>\u003Cdt>\u003Cspan class=\"term\">Leader-with-lease\u003C/span>\u003C/dt>\u003Cdd>\n\t\t\t\t\t\t\tThe leader pod periodically renews the leader lease and gives up leadership when it cannot renew the lease. This implementation allows for a faster transition to a new leader when the existing leader is isolated, but there is a possibility of split brain in \u003Ca class=\"link\" href=\"https://github.com/kubernetes/client-go/blob/30b06a83d67458700a5378239df6b96948cb9160/tools/leaderelection/leaderelection.go#L21-L24\">certain situations\u003C/a>. See the \u003Ca class=\"link\" href=\"https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/leaderelection\">Leader-with-lease\u003C/a> Go documentation for more.\n\t\t\t\t\t\t\u003C/dd>\u003C/dl>\u003C/div>\u003Cp>\n\t\t\t\tBy default, the Operator SDK enables the Leader-for-life implementation. Consult the related Go documentation for both approaches to consider the trade-offs that make sense for your use case.\n\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-leader-election-types_osdk-leader-election\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.11.1. Operator leader election examples\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe following examples illustrate how to use the two leader election options for an Operator, Leader-for-life and Leader-with-lease.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-leader-for-life-election_osdk-leader-election\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.11.1.1. Leader-for-life election\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tWith the Leader-for-life election implementation, a call to \u003Ccode class=\"literal\">leader.Become()\u003C/code> blocks the Operator as it retries until it can become the leader by creating the config map named \u003Ccode class=\"literal\">memcached-operator-lock\u003C/code>:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import (\n ...\n \"github.com/operator-framework/operator-sdk/pkg/leader\"\n)\n\nfunc main() {\n ...\n err = leader.Become(context.TODO(), \"memcached-operator-lock\")\n if err != nil {\n log.Error(err, \"Failed to retry for leader lock\")\n os.Exit(1)\n }\n ...\n}\u003C/pre>\u003Cp>\n\t\t\t\t\t\tIf the Operator is not running inside a cluster, \u003Ccode class=\"literal\">leader.Become()\u003C/code> simply returns without error to skip the leader election since it cannot detect the name of the Operator.\n\t\t\t\t\t\u003C/p>\u003C/section>\u003Csection class=\"section\" id=\"osdk-leader-with-lease-election_osdk-leader-election\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.11.1.2. Leader-with-lease election\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe Leader-with-lease implementation can be enabled using the \u003Ca class=\"link\" href=\"https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/manager#Options\">Manager Options\u003C/a> for leader election:\n\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-go\">import (\n ...\n \"sigs.k8s.io/controller-runtime/pkg/manager\"\n)\n\nfunc main() {\n ...\n opts := manager.Options{\n ...\n LeaderElection: true,\n LeaderElectionID: \"memcached-operator-lock\"\n }\n mgr, err := manager.New(cfg, opts)\n ...\n}\u003C/pre>\u003Cp>\n\t\t\t\t\t\tWhen the Operator is not running in a cluster, the Manager returns an error when starting because it cannot detect the namespace of the Operator to create the config map for leader election. You can override this namespace by setting the \u003Ccode class=\"literal\">LeaderElectionNamespace\u003C/code> option for the Manager.\n\t\t\t\t\t\u003C/p>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-pkgman-to-bundle\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.12. Migrating package manifest projects to bundle format\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tSupport for the legacy \u003Cspan class=\"emphasis\">\u003Cem>package manifest format\u003C/em>\u003C/span> for Operators is removed in OpenShift Container Platform 4.8 and later. If you have an Operator project that was initially created using the package manifest format, you can use the Operator SDK to migrate the project to the bundle format. The bundle format is the preferred packaging format for Operator Lifecycle Manager (OLM) starting in OpenShift Container Platform 4.6.\n\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-about-pkg-format-migration_osdk-pkgman-to-bundle\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.12.1. About packaging format migration\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe Operator SDK \u003Ccode class=\"literal\">pkgman-to-bundle\u003C/code> command helps in migrating Operator Lifecycle Manager (OLM) package manifests to bundles. The command takes an input package manifest directory and generates bundles for each of the versions of manifests present in the input directory. You can also then build bundle images for each of the generated bundles.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tFor example, consider the following \u003Ccode class=\"literal\">packagemanifests/\u003C/code> directory for a project in the package manifest format:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example package manifest format layout\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">packagemanifests/\n└── etcd\n ├── 0.0.1\n │ ├── etcdcluster.crd.yaml\n │ └── etcdoperator.clusterserviceversion.yaml\n ├── 0.0.2\n │ ├── etcdbackup.crd.yaml\n │ ├── etcdcluster.crd.yaml\n │ ├── etcdoperator.v0.0.2.clusterserviceversion.yaml\n │ └── etcdrestore.crd.yaml\n └── etcd.package.yaml\u003C/pre>\n\n\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp>\n\t\t\t\t\tAfter running the migration, the following bundles are generated in the \u003Ccode class=\"literal\">bundle/\u003C/code> directory:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example bundle format layout\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">bundle/\n├── bundle-0.0.1\n│   ├── bundle.Dockerfile\n│   ├── manifests\n│   │   ├── etcdcluster.crd.yaml\n│   │   ├── etcdoperator.clusterserviceversion.yaml\n│   ├── metadata\n│   │   └── annotations.yaml\n│   └── tests\n│   └── scorecard\n│   └── config.yaml\n└── bundle-0.0.2\n ├── bundle.Dockerfile\n ├── manifests\n │   ├── etcdbackup.crd.yaml\n │   ├── etcdcluster.crd.yaml\n │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml\n │   ├── etcdrestore.crd.yaml\n ├── metadata\n │   └── annotations.yaml\n └── tests\n └── scorecard\n └── config.yaml\u003C/pre>\n\n\t\t\t\t\t\u003C/p>\u003C/div>\u003Cp>\n\t\t\t\t\tBased on this generated layout, bundle images for both of the bundles are also built with the following names:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">quay.io/example/etcd:0.0.1\u003C/code>\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">quay.io/example/etcd:0.0.2\u003C/code>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-packaging-format\">Operator Framework packaging formats\u003C/a>\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-migrating-pkgman_osdk-pkgman-to-bundle\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.12.2. Migrating a package manifest project to bundle format\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tOperator authors can use the Operator SDK to migrate a package manifest format Operator project to a bundle format project.\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Prerequisites\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator SDK CLI installed\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tOperator project initially generated using the Operator SDK in package manifest format\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Procedure\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tUse the Operator SDK to migrate your package manifest project to the bundle format and generate bundle images:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk pkgman-to-bundle &lt;package_manifests_dir&gt; \\ \u003Cspan id=\"CO65-1\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">1\u003C/span>\n [--output-dir &lt;directory&gt;] \\ \u003Cspan id=\"CO65-2\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">2\u003C/span>\n --image-tag-base &lt;image_name_base&gt; \u003Cspan id=\"CO65-3\">\u003C!--Empty-->\u003C/span>\u003Cspan class=\"callout\">3\u003C/span>\u003C/pre>\u003Cdiv class=\"calloutlist\">\u003Cdl class=\"calloutlist\">\u003Cdt>\u003Ca href=\"#CO65-1\">\u003Cspan class=\"callout\">1\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tSpecify the location of the package manifests directory for the project, such as \u003Ccode class=\"literal\">packagemanifests/\u003C/code> or \u003Ccode class=\"literal\">manifests/\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO65-2\">\u003Cspan class=\"callout\">2\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tOptional: By default, the generated bundles are written locally to disk to the \u003Ccode class=\"literal\">bundle/\u003C/code> directory. You can use the \u003Ccode class=\"literal\">--output-dir\u003C/code> flag to specify an alternative location.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003Cdt>\u003Ca href=\"#CO65-3\">\u003Cspan class=\"callout\">3\u003C/span>\u003C/a> \u003C/dt>\u003Cdd>\u003Cdiv class=\"para\">\n\t\t\t\t\t\t\t\t\tSet the \u003Ccode class=\"literal\">--image-tag-base\u003C/code> flag to provide the base of the image name, such as \u003Ccode class=\"literal\">quay.io/example/etcd\u003C/code>, that will be used for the bundles. Provide the name without a tag, because the tag for the images will be set according to the bundle version. For example, the full bundle image names are generated in the format \u003Ccode class=\"literal\">&lt;image_name_base&gt;:&lt;bundle_version&gt;\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/div>\u003C/dd>\u003C/dl>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003Cdiv class=\"itemizedlist\">\u003Cp class=\"title\">\u003Cstrong>Verification\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\u003Cp class=\"simpara\">\n\t\t\t\t\t\t\tVerify that the generated bundle image runs successfully:\n\t\t\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk run bundle &lt;bundle_image_name&gt;:&lt;tag&gt;\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">INFO[0025] Successfully created registry pod: quay-io-my-etcd-0-9-4\nINFO[0025] Created CatalogSource: etcd-catalog\nINFO[0026] OperatorGroup \"operator-sdk-og\" created\nINFO[0026] Created Subscription: etcdoperator-v0-9-4-sub\nINFO[0031] Approved InstallPlan install-5t58z for the Subscription: etcdoperator-v0-9-4-sub\nINFO[0031] Waiting for ClusterServiceVersion \"default/etcdoperator.v0.9.4\" to reach 'Succeeded' phase\nINFO[0032] Waiting for ClusterServiceVersion \"default/etcdoperator.v0.9.4\" to appear\nINFO[0048] Found ClusterServiceVersion \"default/etcdoperator.v0.9.4\" phase: Pending\nINFO[0049] Found ClusterServiceVersion \"default/etcdoperator.v0.9.4\" phase: Installing\nINFO[0064] Found ClusterServiceVersion \"default/etcdoperator.v0.9.4\" phase: Succeeded\nINFO[0065] OLM has successfully installed \"etcdoperator.v0.9.4\"\u003C/pre>\n\n\t\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch2 class=\"title\">5.13. Operator SDK CLI reference\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\tThe Operator SDK command-line interface (CLI) is a development kit designed to make writing Operators easier.\n\t\t\t\u003C/p>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Operator SDK CLI syntax\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk &lt;command&gt; [&lt;subcommand&gt;] [&lt;argument&gt;] [&lt;flags&gt;]\u003C/pre>\n\n\t\t\t\t\u003C/p>\u003C/div>\u003Cp>\n\t\t\t\tOperator authors with cluster administrator access to a Kubernetes-based cluster (such as OpenShift Container Platform) can use the Operator SDK CLI to develop their own Operators based on Go, Ansible, or Helm. \u003Ca class=\"link\" href=\"https://kubebuilder.io/\">Kubebuilder\u003C/a> is embedded into the Operator SDK as the scaffolding solution for Go-based Operators, which means existing Kubebuilder projects can be used as is with the Operator SDK and continue to work.\n\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-cli-ref-bundle_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.1. bundle\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk bundle\u003C/code> command manages Operator bundle metadata.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-cli-ref-bundle-validate_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.13.1.1. validate\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">bundle validate\u003C/code> subcommand validates an Operator bundle.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209534154016\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.18. bundle validate flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534148864\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534147776\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534148864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534147776\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tHelp output for the \u003Ccode class=\"literal\">bundle validate\u003C/code> subcommand.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534148864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--index-builder\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534147776\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tTool to pull and unpack bundle images. Only used when validating a bundle image. Available options are \u003Ccode class=\"literal\">docker\u003C/code>, which is the default, \u003Ccode class=\"literal\">podman\u003C/code>, or \u003Ccode class=\"literal\">none\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534148864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--list-optional\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534147776\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tList all optional validators available. When set, no validators are run.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534148864\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--select-optional\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534147776\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tLabel selector to select optional validators to run. When run with the \u003Ccode class=\"literal\">--list-optional\u003C/code> flag, lists available optional validators.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-cleanup_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.2. cleanup\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk cleanup\u003C/code> command destroys and removes resources that were created for an Operator that was deployed with the \u003Ccode class=\"literal\">run\u003C/code> command.\n\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209534122816\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.19. cleanup flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534117664\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534116576\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534117664\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534116576\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tHelp output for the \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534117664\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--kubeconfig\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534116576\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tPath to the \u003Ccode class=\"literal\">kubeconfig\u003C/code> file to use for CLI requests.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534117664\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">n\u003C/code>, \u003Ccode class=\"literal\">--namespace\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534116576\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tIf present, namespace in which to run the CLI request.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534117664\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--timeout &lt;duration&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534116576\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tTime to wait for the command to complete before failing. The default value is \u003Ccode class=\"literal\">2m0s\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-completion_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.3. completion\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk completion\u003C/code> command generates shell completions to make issuing CLI commands quicker and easier.\n\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209534092864\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.20. completion subcommands\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534087712\" scope=\"col\">Subcommand\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534086624\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534087712\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">bash\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534086624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tGenerate bash completions.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534087712\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">zsh\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534086624\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tGenerate zsh completions.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Crh-table id=\"idm140209534076160\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.21. completion flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534071008\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534069920\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534071008\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h, --help\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534069920\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tUsage help output.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cp>\n\t\t\t\t\tFor example:\n\t\t\t\t\u003C/p>\u003Cpre class=\"programlisting language-terminal\">$ operator-sdk completion bash\u003C/pre>\u003Cdiv class=\"formalpara\">\u003Cp class=\"title\">\u003Cstrong>Example output\u003C/strong>\u003C/p>\u003Cp>\n\t\t\t\t\t\t\n\u003Cpre class=\"programlisting language-terminal\"># bash completion for operator-sdk -*- shell-script -*-\n...\n# ex: ts=4 sw=4 et filetype=sh\u003C/pre>\n\n\t\t\t\t\t\u003C/p>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-create_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.4. create\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk create\u003C/code> command is used to create, or \u003Cspan class=\"emphasis\">\u003Cem>scaffold\u003C/em>\u003C/span>, a Kubernetes API.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-cli-ref-create-api_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.13.4.1. api\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">create api\u003C/code> subcommand scaffolds a Kubernetes API. The subcommand must be run in a project that was initialized with the \u003Ccode class=\"literal\">init\u003C/code> command.\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209534053600\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.22. create api flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534048448\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534047360\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534048448\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534047360\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tHelp output for the \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-generate_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.5. generate\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk generate\u003C/code> command invokes a specific generator to generate code or manifests.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-cli-ref-generate-bundle_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.13.5.1. bundle\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">generate bundle\u003C/code> subcommand generates a set of bundle manifests, metadata, and a \u003Ccode class=\"literal\">bundle.Dockerfile\u003C/code> file for your Operator project.\n\t\t\t\t\t\u003C/p>\u003Crh-alert class=\"admonition note\" state=\"info\">\u003Cdiv class=\"admonition_header\" slot=\"header\">Note\u003C/div>\u003Cdiv>\u003Cp>\n\t\t\t\t\t\t\tTypically, you run the \u003Ccode class=\"literal\">generate kustomize manifests\u003C/code> subcommand first to generate the input \u003Ca class=\"link\" href=\"https://kustomize.io/\">Kustomize\u003C/a> bases that are used by the \u003Ccode class=\"literal\">generate bundle\u003C/code> subcommand. However, you can use the \u003Ccode class=\"literal\">make bundle\u003C/code> command in an initialized project to automate running these commands in sequence.\n\t\t\t\t\t\t\u003C/p>\u003C/div>\u003C/rh-alert>\u003Crh-table id=\"idm140209534031184\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.23. generate bundle flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534026032\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209534024944\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--channels\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tComma-separated list of channels to which the bundle belongs. The default value is \u003Ccode class=\"literal\">alpha\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--crds-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRoot directory for \u003Ccode class=\"literal\">CustomResoureDefinition\u003C/code> manifests.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--default-channel\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tThe default channel for the bundle.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--deploy-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRoot directory for Operator manifests, such as deployments and RBAC. This directory is different from the directory passed to the \u003Ccode class=\"literal\">--input-dir\u003C/code> flag.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tHelp for \u003Ccode class=\"literal\">generate bundle\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--input-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tDirectory from which to read an existing bundle. This directory is the parent of your bundle \u003Ccode class=\"literal\">manifests\u003C/code> directory and is different from the \u003Ccode class=\"literal\">--deploy-dir\u003C/code> directory.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--kustomize-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tDirectory containing Kustomize bases and a \u003Ccode class=\"literal\">kustomization.yaml\u003C/code> file for bundle manifests. The default path is \u003Ccode class=\"literal\">config/manifests\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--manifests\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tGenerate bundle manifests.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--metadata\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tGenerate bundle metadata and Dockerfile.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--output-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tDirectory to write the bundle to.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--overwrite\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tOverwrite the bundle metadata and Dockerfile if they exist. The default value is \u003Ccode class=\"literal\">true\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--package\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tPackage name for the bundle.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-q\u003C/code>, \u003Ccode class=\"literal\">--quiet\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tRun in quiet mode.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--stdout\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tWrite bundle manifest to standard out.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534026032\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--version\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209534024944\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tSemantic version of the Operator in the generated bundle. Set only when creating a new bundle or upgrading the Operator.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-bundle-operator_osdk-working-bundle-images\">Bundling an Operator\u003C/a> for a full procedure that includes using the \u003Ccode class=\"literal\">make bundle\u003C/code> command to call the \u003Ccode class=\"literal\">generate bundle\u003C/code> subcommand.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-generate-kustomize_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.13.5.2. kustomize\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">generate kustomize\u003C/code> subcommand contains subcommands that generate \u003Ca class=\"link\" href=\"https://kustomize.io/\">Kustomize\u003C/a> data for the Operator.\n\t\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-cli-ref-generate-kustomize-manifests_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch5 class=\"title\">5.13.5.2.1. manifests\u003C/h5>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\t\tThe \u003Ccode class=\"literal\">generate kustomize manifests\u003C/code> subcommand generates or regenerates Kustomize bases and a \u003Ccode class=\"literal\">kustomization.yaml\u003C/code> file in the \u003Ccode class=\"literal\">config/manifests\u003C/code> directory, which are used to build bundle manifests by other Operator SDK commands. This command interactively asks for UI metadata, an important component of manifest bases, by default unless a base already exists or you set the \u003Ccode class=\"literal\">--interactive=false\u003C/code> flag.\n\t\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209533943552\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.24. generate kustomize manifests flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533938384\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533937296\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533938384\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--apis-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533937296\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tRoot directory for API type definitions.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533938384\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533937296\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tHelp for \u003Ccode class=\"literal\">generate kustomize manifests\u003C/code>.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533938384\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--input-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533937296\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tDirectory containing existing Kustomize files.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533938384\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--interactive\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533937296\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tWhen set to \u003Ccode class=\"literal\">false\u003C/code>, if no Kustomize base exists, an interactive command prompt is presented to accept custom metadata.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533938384\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--output-dir\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533937296\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tDirectory where to write Kustomize files.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533938384\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--package\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533937296\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tPackage name.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533938384\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-q\u003C/code>, \u003Ccode class=\"literal\">--quiet\u003C/code>\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533937296\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\tRun in quiet mode.\n\t\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-init_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.6. init\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk init\u003C/code> command initializes an Operator project and generates, or \u003Cspan class=\"emphasis\">\u003Cem>scaffolds\u003C/em>\u003C/span>, a default project directory layout for the given plugin.\n\t\t\t\t\u003C/p>\u003Cp>\n\t\t\t\t\tThis command writes the following files:\n\t\t\t\t\u003C/p>\u003Cdiv class=\"itemizedlist\">\u003Cul class=\"itemizedlist\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tBoilerplate license file\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">PROJECT\u003C/code> file with the domain and repository\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">Makefile\u003C/code> to build the project\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">go.mod\u003C/code> file with project dependencies\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">kustomization.yaml\u003C/code> file for customizing manifests\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tPatch file for customizing images for manager manifests\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tPatch file for enabling Prometheus metrics\n\t\t\t\t\t\t\u003C/li>\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\u003Ccode class=\"literal\">main.go\u003C/code> file to run\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003Crh-table id=\"idm140209533889616\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.25. init flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533884464\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533883376\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533884464\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--help, -h\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533883376\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tHelp output for the \u003Ccode class=\"literal\">init\u003C/code> command.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533884464\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--plugins\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533883376\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tName and optionally version of the plugin to initialize the project with. Available plugins are \u003Ccode class=\"literal\">ansible.sdk.operatorframework.io/v1\u003C/code>, \u003Ccode class=\"literal\">go.kubebuilder.io/v2\u003C/code>, \u003Ccode class=\"literal\">go.kubebuilder.io/v3\u003C/code>, and \u003Ccode class=\"literal\">helm.sdk.operatorframework.io/v1\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533884464\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--project-version\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533883376\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tProject version. Available values are \u003Ccode class=\"literal\">2\u003C/code> and \u003Ccode class=\"literal\">3-alpha\u003C/code>, which is the default.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-run_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.7. run\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk run\u003C/code> command provides options that can launch the Operator in various environments.\n\t\t\t\t\u003C/p>\u003Csection class=\"section\" id=\"osdk-cli-ref-run-bundle_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.13.7.1. bundle\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand deploys an Operator in the bundle format with Operator Lifecycle Manager (OLM).\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209533860368\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.26. run bundle flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533855216\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533854128\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533855216\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--index-image\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533854128\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tIndex image in which to inject a bundle. The default image is \u003Ccode class=\"literal\">quay.io/operator-framework/upstream-opm-builder:latest\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533855216\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--install-mode &lt;install_mode_value&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533854128\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tInstall mode supported by the cluster service version (CSV) of the Operator, for example \u003Ccode class=\"literal\">AllNamespaces\u003C/code> or \u003Ccode class=\"literal\">SingleNamespace\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533855216\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--timeout &lt;duration&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533854128\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tInstall timeout. The default value is \u003Ccode class=\"literal\">2m0s\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533855216\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--kubeconfig\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533854128\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tPath to the \u003Ccode class=\"literal\">kubeconfig\u003C/code> file to use for CLI requests.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533855216\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">n\u003C/code>, \u003Ccode class=\"literal\">--namespace\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533854128\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tIf present, namespace in which to run the CLI request.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533855216\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533854128\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tHelp output for the \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#olm-operatorgroups-membership_olm-understanding-operatorgroups\">Operator group membership\u003C/a> for details on possible install modes.\n\t\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-run-bundle-upgrade_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch4 class=\"title\">5.13.7.2. bundle-upgrade\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\t\tThe \u003Ccode class=\"literal\">run bundle-upgrade\u003C/code> subcommand upgrades an Operator that was previously installed in the bundle format with Operator Lifecycle Manager (OLM).\n\t\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209533817264\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.27. run bundle-upgrade flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533812112\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533811024\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533812112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--timeout &lt;duration&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533811024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tUpgrade timeout. The default value is \u003Ccode class=\"literal\">2m0s\u003C/code>.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533812112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--kubeconfig\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533811024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tPath to the \u003Ccode class=\"literal\">kubeconfig\u003C/code> file to use for CLI requests.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533812112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">n\u003C/code>, \u003Ccode class=\"literal\">--namespace\u003C/code> (string)\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533811024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tIf present, namespace in which to run the CLI request.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533812112\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533811024\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\tHelp output for the \u003Ccode class=\"literal\">run bundle\u003C/code> subcommand.\n\t\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003C/section>\u003C/section>\u003Csection class=\"section\" id=\"osdk-cli-ref-scorecard_osdk-cli-ref\">\u003Cdiv class=\"titlepage\">\u003Cdiv>\u003Cdiv>\u003Ch3 class=\"title\">5.13.8. scorecard\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cp>\n\t\t\t\t\tThe \u003Ccode class=\"literal\">operator-sdk scorecard\u003C/code> command runs the scorecard tool to validate an Operator bundle and provide suggestions for improvements. The command takes one argument, either a bundle image or directory containing manifests and metadata. If the argument holds an image tag, the image must be present remotely.\n\t\t\t\t\u003C/p>\u003Crh-table id=\"idm140209533787008\">\u003Ctable class=\"lt-4-cols lt-7-rows\">\u003Ccaption>Table 5.28. scorecard flags\u003C/caption>\u003Ccolgroup>\u003Ccol style=\"width: 25%; \" class=\"col_1\">\u003C!--Empty-->\u003C/col>\u003Ccol style=\"width: 75%; \" class=\"col_2\">\u003C!--Empty-->\u003C/col>\u003C/colgroup>\u003Cthead>\u003Ctr>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533781856\" scope=\"col\">Flag\u003C/th>\u003Cth align=\"left\" valign=\"top\" id=\"idm140209533780768\" scope=\"col\">Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-c\u003C/code>, \u003Ccode class=\"literal\">--config\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tPath to scorecard configuration file. The default path is \u003Ccode class=\"literal\">bundle/tests/scorecard/config.yaml\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-h\u003C/code>, \u003Ccode class=\"literal\">--help\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tHelp output for the \u003Ccode class=\"literal\">scorecard\u003C/code> command.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">--kubeconfig\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tPath to \u003Ccode class=\"literal\">kubeconfig\u003C/code> file.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-L\u003C/code>, \u003Ccode class=\"literal\">--list\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tList which tests are available to run.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-n\u003C/code>, --namespace (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tNamespace in which to run the test images.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-o\u003C/code>, \u003Ccode class=\"literal\">--output\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tOutput format for results. Available values are \u003Ccode class=\"literal\">text\u003C/code>, which is the default, and \u003Ccode class=\"literal\">json\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-l\u003C/code>, \u003Ccode class=\"literal\">--selector\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tLabel selector to determine which tests are run.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-s\u003C/code>, \u003Ccode class=\"literal\">--service-account\u003C/code> (string)\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tService account to use for tests. The default value is \u003Ccode class=\"literal\">default\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-x\u003C/code>, \u003Ccode class=\"literal\">--skip-cleanup\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tDisable resource cleanup after tests are run.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533781856\"> \u003Cp>\n\t\t\t\t\t\t\t\t\t\u003Ccode class=\"literal\">-w\u003C/code>, \u003Ccode class=\"literal\">--wait-time &lt;duration&gt;\u003C/code>\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003Ctd align=\"left\" valign=\"top\" headers=\"idm140209533780768\"> \u003Cp>\n\t\t\t\t\t\t\t\t\tSeconds to wait for tests to complete, for example \u003Ccode class=\"literal\">35s\u003C/code>. The default value is \u003Ccode class=\"literal\">30s\u003C/code>.\n\t\t\t\t\t\t\t\t\u003C/p>\n\t\t\t\t\t\t\t\t \u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\u003C/rh-table>\u003Cdiv class=\"itemizedlist _additional-resources\">\u003Cp class=\"title\">\u003Cstrong>Additional resources\u003C/strong>\u003C/p>\u003Cul class=\"itemizedlist _additional-resources\" type=\"disc\">\u003Cli class=\"listitem\">\n\t\t\t\t\t\t\tSee \u003Ca class=\"link\" href=\"https://access.redhat.com/documentation/en-us/openshift_container_platform/4.8/html-single/operators/#osdk-scorecard\">Validating Operators using the scorecard tool\u003C/a> for details about running the scorecard tool.\n\t\t\t\t\t\t\u003C/li>\u003C/ul>\u003C/div>\u003C/section>\u003C/section>\u003C/section>\u003C/body>",[15,928,3458,3583,5083,5517,6073,6545,8290,9236,11231],{"title":16,"visible":17,"categoryName":17,"sections":18},"Getting Started",true,[19,82,383,487],{"title":20,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":24,"url":25,"docTitle":26,"sections":27},"About",1,"index",null,[],"/documentation/openshift_container_platform/4.8/html/about/index","about",[28,40,51,73],{"title":29,"visible":17,"weight":30,"urlFragment":31,"anchor":23,"singlePageAnchor":31,"subChapters":32,"url":39,"docTitle":26},"OpenShift Container Platform 4.8 Documentation",2,"welcome-index",[33,34,35,36,37,38],"cluster-installer-activities","developer-activities","cluster-administrator-activities","manage-cluster-components","change-cluster-components","monitor-the-cluster","/documentation/openshift_container_platform/4.8/html/about/welcome-index",{"title":41,"visible":17,"weight":42,"urlFragment":43,"anchor":23,"singlePageAnchor":43,"subChapters":44,"url":50,"docTitle":26},"Learn more about OpenShift Container Platform",3,"learn_more_about_openshift",[45,46,47,48,49],"architect","cluster-administrator","application_site_reliability_engineer","Developer","understanding-openshift_welcome-personas","/documentation/openshift_container_platform/4.8/html/about/learn_more_about_openshift",{"title":52,"visible":17,"weight":53,"urlFragment":54,"anchor":23,"singlePageAnchor":54,"subChapters":55,"url":72,"docTitle":26},"About OpenShift Kubernetes Engine",4,"oke-about",[56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71],"about_oke_similarities_and_differences","about_oke_core_kubernetes_and_container_orchestration","about_oke_enterprise_ready_configurations","about_oke_standard_infrastructure_services","about_oke_core_user_experience","maintained-and-curated-content","openshift-container-storage-compatible","red-hat-middleware-compatible","openshift-serverless","quay-integration-compatible","openshift-virtualization","advanced-cluster-management","advanced-networking","developer-experience","feature-summary","subscription-limitations","/documentation/openshift_container_platform/4.8/html/about/oke-about",{"title":74,"visible":17,"weight":75,"urlFragment":76,"anchor":23,"singlePageAnchor":76,"subChapters":77,"url":81,"docTitle":26},"Kubernetes overview",5,"kubernetes-overview",[78,79,80],"kubernetes-components_kubernetes-overview","kubernetes-resources_kubernetes-overview","kubernetes-conceptual-guidelines_kubernetes-overview","/documentation/openshift_container_platform/4.8/html/about/kubernetes-overview",{"title":83,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":84,"url":85,"docTitle":86,"sections":87},"Release notes",[],"/documentation/openshift_container_platform/4.8/html/release_notes/index","release_notes",[88],{"title":89,"visible":17,"weight":30,"urlFragment":90,"anchor":23,"singlePageAnchor":90,"subChapters":91,"url":382,"docTitle":86},"OpenShift Container Platform 4.8 release notes","ocp-4-8-release-notes",[92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381],"ocp-4-8-about-this-release","ocp-4-8-inclusive-language","ocp-4-8-add-on-support-status","ocp-4-8-new-features-and-enhancements","ocp-4-8-rhcos","ocp-4-8-rhcos-rhel-8-4-packages","ocp-4-8-stream-metadata","ocp-4-8-rhcos-butane","ocp-4-8-rhcos-chrony-default","ocp-4-8-rhcos-multipath-install","ocp-4-8-installation-and-upgrade","ocp-4-8-installation-azure-empty-rg","ocp-4-8-installation-existing-iam-roles-aws","ocp-4-8-installation-pre-existing-hosted-zones-aws","ocp-4-8-installation-increase-gcp-subnets-within-machine-cidr","ocp-4-8-improved-upgrade-duration","ocp-4-8-mco-upgrade-complete","ocp-4-8-installation-fujitsu-irmc","ocp-4-8-installation-openstack-installer-provisioned-sr-iov","installation-ironic-agent-vlan-support","ocp-4-8-osus","ocp-4-8-web-console","ocp-4-8-custom-console-routes-use-custom-domains-cluster-api","ocp-4-8-access-code-snippet-from-quick-start","ocp-4-8-improved-presentation-quick-start-prereqs","ocp-4-8-web-console-developer-perspective","ocp-4-8-ibm-z","ocp-4-8-ibm-power","ocp-4-8-security","ocp-4-8-security-log-oauth-tokens","ocp-4-8-security-wildcard-subjects-headless-services","ocp-4-8-security-oc-compliance-plug-in","ocp-4-8-security-tls-security-profile-control-plane","ocp-4-8-security-tls-security-profile-kubelet","ocp-4-8-security-bcrypt-hashing","ocp-4-8-managed-secure-boot","ocp-4-8-networking","ocp-4-8-dual-stack-support-bare-metal-ovn-kubernetes-network-provider","ocp-4-8-migrate-openshift-sdn-ovn-kubernetes-user-provisioned","ocp-4-8-openshift-sdn-egress-ips-balance","ocp-4-8-network-policy-host-network-ingress-controllers","ocp-4-8-network-policy-host-network-policy-group","ocp-4-8-network-policy-audit-logs","ocp-4-8-macvlan-multi-network-policy","ocp-4-8-supported-hardware-sriov","ocp-4-8-enhancements-sriov-network-operator","ocp-4-8-tracking-network-flows","ocp-4-8-coredns-mdns","ocp-4-8-preparation-haproxy-2.2","ocp-4-8-stricter-http-head-validation-haproxy-2.2","ocp-4-8-ingress-configuring-global-access-gcp","ocp-4-8-setting-ingress-configuring-thread-count","ocp-4-8-ingress-configuring-proxy-protocol","ocp-4-8-networking-ntp-on-control-plane","ocp-4-8-enhancements-kuryr-kubernetes","ocp-4-8-networking-enabling-provisioning-network-day2","ocp-4-8-configure-vips-to-run-on-control-plane","ocp-4-8-networking-external-load-balancer","ocp-4-8-IPsec-support-dual-stack","ocp-4-8-egress-router-ovn-kubernetes","ocp-4-8-ip-failover-support","ocp-4-8-control-dns-pod-placement","ocp-4-8-networking-openstack-provider-networks","ocp-4-8-configurable-headerBufferMaxRewriteByte-headerBufferBytes-parameters","ocp-4-8-storage","ocp-4-8-storage-gcp-pd-csi-ga","ocp-4-8-storage-azure-csi-tp","ocp-4-8-storage-vsphere-csi-tp","ocp-4-8-storage-csi-migration","ocp-4-8-storage-aws-efs-removed-1st","ocp-4-8-storage-openstack-cinder-availability-zones","ocp-4-8-registry","ocp-4-8-olm","ocp-4-8-admin-error-reporting","ocp-4-8-installplan-errors","ocp-4-8-operatorgroup-errors","ocp-4-8-candidate-operator-errors","ocp-4-8-osdk","ocp-4-8-pkgman-to-bundle","ocp-4-8-catalog-build-push","ocp-4-8-bundle-upgrade","ocp-4-8-osdk-compat","ocp-4-8-builds-telemetry-metric","ocp-4-8-builds-mount-custom-pki-ca","ocp-4-8-images","ocp-4-8-machine-api","ocp-4-8-vsphere-machine-autoscaler-to-from-zero","ocp-4-8-mco-no-reboot-cert","ocp-4-8-machine-set-policy-enhancement","ocp-4-8-machine-set-hugepage-enhancement","ocp-4-8-machine-config-operator-image-content-source-object-enhancement","ocp-4-8-nodes","ocp-4-8-nodes-descheduler-apigroup","ocp-4-8-nodes-descheduler-metrics","ocp-4-8-nodes-huge-pages-downward-api","ocp-4-8-nodes-nfd-operator-new-labels_release-notes","ocp-4-8-poison-pill-operator","ocp-4-8-nodes-no-reboot-cert","ocp-4-8-nodes-vpa-ga","ocp-4-8-nodes-vpa-replicas","ocp-4-8-nodes-resources-configuring-auto_release-notes","ocp-4-8-nodes-registry-allowed-repo_release-notes","ocp-4-8-nodes-cronjob-qa_release-notes","ocp-4-8-logging","ocp-4-8-monitoring","ocp-4-8-monitoring-alerting-rule-changes","ocp-4-8-monitoring-removed-API-alerts","ocp-4-8-monitoring-stack-dependency-version-updates","ocp-4-8-monitoring-kube-state-metrics-v2.0.0-upgrade","ocp-4-8-monitoring-removed-grafana-alertmanager-ui-links","ocp-4-8-monitoring-dashboards-updates-web-console","ocp-4-8-metering","ocp-4-8-scale","ocp-4-8-scale-running-in-a-single-node-cluster","ocp-4-8-reducing-nic-queues-using-the-performance-addon-operator","ocp-4-8-scale-cluster-maximums","ocp-4-8-performance-creator-tool","ocp-4-8-nfd-operator","ocp-4-8-driver-toolkit","ocp-4-8-backup-and-restore","ocp-4-8-etcd-snapshot","ocp-4-8-insights-operator","ocp-4-8-insights-operator-restricted-network","ocp-4-8-insights-advisor-improvements","ocp-4-8-insights-operator-data-collection-enhancements","ocp-4-8-insights-operator-gathering-sap","ocp-4-8-gathering-sap-datahubs","ocp-4-8-auth","ocp-4-8-auth-tp-aws-sts","ocp-4.8-sandboxed-containers","ocp-4.8-sandboxed-containers-tp","ocp-4-8-notable-technical-changes","ocp-4-8-deprecated-removed-features","ocp-4-8-deprecated-features","ocp-4-8-descheduler-apigroup-deprecated","ocp-4-8-dhclient-deprecated","ocp-4-8-cluster-loader-deprecated","ocp-4-8-builds-lasttriggeredimageid-parameter","ocp-4-8-builds-jenkins-operator","ocp-4-8-instance_type_id-operator_rhv","ocp-4-8-removed-features","ocp-4-8-removed-feature-azure-mint-mode","ocp-4-8-images-removed-from-samples-imagestreams","ocp-4-8-pkgman-format","ocp-4-8-hpa-prometheus","ocp-4-8-oauth-secure-token-annotation","ocp-4-8-bug-fixes","ocp-4-8-technology-preview","ocp-4-8-known-issues","ocp-4-8-asynchronous-errata-updates","ocp-4-8-1-ga","ocp-4-8-3","ocp-4-8-3-updating","ocp-4-8-4","ocp-4-8-4-bug-fixes","ocp-4-8-4-updating","ocp-4-8-5","ocp-4-8-5-features","ocp-4-8-5-egress-ip-enhancement","ocp-4-8-5-bug-fixes","ocp-4-8-5-updating","ocp-4-8-9","ocp-4-8-9-bug-fixes","ocp-4-8-9-updating","ocp-4-8-10","ocp-4-8-10-updating","ocp-4-8-11","ocp-4-8-11-bug-fixes","ocp-4-8-11-updating","ocp-4-8-12","ocp-4-8-12-features","ocp-4-8-12-new-minimum-storage-requirement","ocp-4-8-12-bug-fixes","ocp-4-8-12-updating","ocp-4-8-13","ocp-4-8-13-features","ocp-kubernetes-1-21-4-updates","ocp-4-8-13-bug-fixes","ocp-4-8-13-updating","ocp-4-8-14","ocp-4-8-14-preparing-upgrade-next-release","ocp-4-8-14-bug-fixes","ocp-4-8-14-updating","ocp-4-8-15","ocp-4-8-15-known-issues","ocp-4-8-15-bug-fixes","ocp-4-8-15-updating","ocp-4-8-17","ocp-4-8-17-updating","ocp-4-8-18","ocp-4-8-18-bug-fixes","ocp-4-8-18-updating","ocp-4-8-19","ocp-4-8-19-updating","ocp-4-8-20","ocp-4-8-20-known-issues","ocp-4-8-20-updating","ocp-4-8-21","ocp-4-8-21-features","ocp-kubernetes-1-21-5-updates","ocp-4-8-21-updating","ocp-4-8-22","ocp-4-8-22-features","ocp-kubernetes-1-21-6-updates","ocp-4-8-22-updating","ocp-4-8-23","ocp-4-8-23-updating","ocp-4-8-24","ocp-4-8-24-updating","ocp-4-8-25","ocp-4-8-25-bug-fixes","ocp-4-8-25-updating","ocp-4-8-26","ocp-4-8-26-updating","ocp-4-8-27","ocp-4-8-27-updating","ocp-4-8-28","ocp-4-8-28-updating","ocp-4-8-29","ocp-4-8-29-bug-fixes","ocp-4-8-29-updating","ocp-4-8-31","ocp-4-8-31-features","ocp-4-8-31-features-ip-reconciler","ocp-4-8-31-bug-fixes","ocp-4-8-31-updating","ocp-4-8-32","ocp-4-8-32-updating","ocp-4-8-33","ocp-4-8-33-updating","ocp-4-8-34","ocp-4-8-34-features","ocp-kubernetes-1-21-8-updates","ocp-4-8-34-removed-feature-azure-mint-mode","ocp-4-8-34-known-issues","ocp-4-8-34-bug-fixes","ocp-4-8-34-updating","ocp-4-8-35","ocp-4-8-35-updating","ocp-4-8-36","ocp-4-8-36-bug-fixes","ocp-4-8-36-updating","ocp-4-8-37","ocp-4-8-37-bug-fixes","ocp-4-8-37-updating","ocp-4-8-39","ocp-4-8-39-known-issues","ocp-4-8-39-updating","ocp-4-8-41","ocp-4-8-41-features","ocp-kubernetes-1-21-11-updates","ocp-4-8-41-updating","ocp-4-8-42","ocp-4-8-42-updating","ocp-4-8-43","ocp-4-8-43-updating","ocp-4-8-44","ocp-4-8-44-bug-fixes","ocp-4-8-44-updating","ocp-4-8-45","ocp-4-8-45-bug-fixes","ocp-4-8-45-updating","ocp-4-8-46","updating","ocp-4-8-47","updating-2","ocp-4-8-48","ocp-4-8-48-bug-fixes","updating-3","ocp-4-8-49","ocp-4-8-49-updating","ocp-4-8-50","ocp-4-8-50-bug-fixes","ocp-4-8-50-updating","ocp-4-8-51","ocp-4-8-51-updating","ocp-4-8-52","ocp-4-8-52-bug-fixes","updating-4","ocp-4-8-53","updating-5","ocp-4-8-54","updating-6","ocp-4-8-55","ocp-kubernetes-1-21-14-updates","updating-7","ocp-4-8-56","ocp-4-8-56-updating","ocp-4-8-57","ocp-4-8-57-updating","/documentation/openshift_container_platform/4.8/html/release_notes/ocp-4-8-release-notes",{"title":384,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":385,"url":386,"docTitle":387,"sections":388},"Architecture",[],"/documentation/openshift_container_platform/4.8/html/architecture/index","architecture",[389,400,415,426,440,458,473],{"title":390,"visible":17,"weight":30,"urlFragment":391,"anchor":23,"singlePageAnchor":391,"subChapters":392,"url":399,"docTitle":387},"Architecture overview","architecture-overview",[393,394,395,396,397,398],"openshift-architecture-common-terms_architecture-overview","about-installation-and-updates","about-control-planes","about-containerized-applications-for-developers","coreos-and-ignition","about-admission-plug-ins","/documentation/openshift_container_platform/4.8/html/architecture/architecture-overview",{"title":401,"visible":17,"weight":42,"urlFragment":387,"anchor":23,"singlePageAnchor":387,"subChapters":402,"url":414,"docTitle":387},"OpenShift Container Platform architecture",[403,404,405,406,407,408,409,410,411,412,413],"architecture-platform-introduction_architecture","architecture-kubernetes-introduction_architecture","architecture-container-application-benefits_architecture","operating-system-benefits_architecture","deployment-scaling-benefits_architecture","architecture-platform-benefits_architecture","architecture-custom-os_architecture","architecture-platform-management_architecture","architecture-key-features_architecture","architecture-overview-image_architecture","cluster-entitlements_architecture","/documentation/openshift_container_platform/4.8/html/architecture/architecture",{"title":416,"visible":17,"weight":53,"urlFragment":417,"anchor":23,"singlePageAnchor":417,"subChapters":418,"url":425,"docTitle":387},"Installation and update","architecture-installation",[419,420,421,422,423,424],"installation-overview_architecture-installation","supported-platforms-for-openshift-clusters_architecture-installation","installation-process_architecture-installation","update-service-overview_architecture-installation","unmanaged-operators_architecture-installation","architecture-installation-next-steps","/documentation/openshift_container_platform/4.8/html/architecture/architecture-installation",{"title":427,"visible":17,"weight":75,"urlFragment":428,"anchor":23,"singlePageAnchor":428,"subChapters":429,"url":439,"docTitle":387},"Control plane architecture","control-plane",[430,431,432,433,434,435,436,437,438],"architecture-machine-config-pools_control-plane","architecture-machine-roles_control-plane","control-plane-and-node-host-compatibility","defining-workers_control-plane","defining-masters_control-plane","operators-overview_control-plane","cluster-operators_control-plane","olm-operators_control-plane","about-machine-config-operator_control-plane","/documentation/openshift_container_platform/4.8/html/architecture/control-plane",{"title":441,"visible":17,"weight":442,"urlFragment":443,"anchor":23,"singlePageAnchor":443,"subChapters":444,"url":457,"docTitle":387},"Understanding OpenShift Container Platform development",6,"understanding-development",[445,446,447,448,449,450,451,452,453,454,455,456],"developing-containerized-applications","building-simple-container","container-build-tool-options","base-image-options","understanding-development-registry-options","creating-kubernetes-manifest-openshift","understanding-kubernetes-pods","application-types","supporting-components","applying-manifest","manifest-next-steps","develop-for-operators","/documentation/openshift_container_platform/4.8/html/architecture/understanding-development",{"title":459,"visible":17,"weight":460,"urlFragment":461,"anchor":23,"singlePageAnchor":461,"subChapters":462,"url":472,"docTitle":387},"Red Hat Enterprise Linux CoreOS (RHCOS)",7,"architecture-rhcos",[463,464,465,466,467,468,469,470,471],"rhcos-about_architecture-rhcos","rhcos-key-features_architecture-rhcos","rhcos-configured_architecture-rhcos","rhcos-deployed_architecture-rhcos","rhcos-about-ignition_architecture-rhcos","about-ignition_architecture-rhcos","ignition-sequence_architecture-rhcos","ignition-config-viewing_architecture-rhcos","digging-into-machine-config_architecture-rhcos","/documentation/openshift_container_platform/4.8/html/architecture/architecture-rhcos",{"title":474,"visible":17,"weight":475,"urlFragment":476,"anchor":23,"singlePageAnchor":476,"subChapters":477,"url":486,"docTitle":387},"Admission plugins",8,"admission-plug-ins",[478,479,480,481,482,483,484,485],"admission-plug-ins-about_admission-plug-ins","admission-plug-ins-default_admission-plug-ins","admission-webhooks-about_admission-plug-ins","admission-webhook-types_admission-plug-ins","mutating-admission-plug-in_admission-plug-ins","validating-admission-plug-in_admission-plug-ins","configuring-dynamic-admission_admission-plug-ins","admission-plug-ins-additional-resources","/documentation/openshift_container_platform/4.8/html/architecture/admission-plug-ins",{"title":488,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":489,"url":490,"docTitle":491,"sections":492},"Security and compliance",[],"/documentation/openshift_container_platform/4.8/html/security_and_compliance/index","security_and_compliance",[493,501,586,609,680,810,864,874,882,893,904,911,920],{"title":494,"visible":17,"weight":30,"urlFragment":495,"anchor":23,"singlePageAnchor":495,"subChapters":496,"url":500,"docTitle":491},"OpenShift Container Platform security and compliance","security-compliance-overview",[497,498,499],"security-overview","compliance-overview","additional-resources_security-compliance-overview","/documentation/openshift_container_platform/4.8/html/security_and_compliance/security-compliance-overview",{"title":502,"visible":17,"weight":42,"urlFragment":503,"anchor":23,"singlePageAnchor":503,"subChapters":504,"url":585,"docTitle":491},"Container security","container-security-1",[505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584],"security-understanding","security-understanding-containers_security-understanding","security-understanding-openshift_security-understanding","security-hosts-vms","security-hosts-vms-rhcos_security-hosts-vms","security-hosts-vms-vs-containers_security-hosts-vms","security-hosts-vms-openshift_security-hosts-vms","security-hardening","security-hardening-what_security-hardening","security-hardening-how_security-hardening","security-harden-before-installation_security-hardening","security-harden-during-installation_security-hardening","security-harden-after-installation_security-hardening","security-container-signature","containers-signature-verify-enable_security-container-signature","containers-signature-verify-application_security-container-signature","additional-resources_security-container-signature","security-compliance","security-compliance-nist_security-compliance","security-container-content","security-container-content-inside_security-container-content","security-container-content-universal_security-container-content","security-container-content-scanning_security-container-content","quay-security-scan_security-container-content","security-container-content-external-scanning_security-container-content","security-image-metadata_security-container-content","security-example-annotation-keys_security-container-content","security-example-annotation-values_security-container-content","security-annotating-image-objects_security-container-content","security-example-annotate-CLI_security-container-content","controlling-pod-execution_security-container-content","security-controlling-pod-execution-example-annotation_security-container-content","security-integration-reference_security-container-content","security-integration-reference-example-api-call_security-container-content","security-registries","security-registries-where_security-registries","security-registries-immutable_security-registries","security-registries-ecosystem_security-registries","security-registries-openshift_security-registries","security-registries-quay_security-registries","security-build","security-build-once_security-build","security-build-management_security-build","security-build-inputs_security-build","security-build-designing_security-build","security-build-knative_security-build","additional-resources_security-build","security-deploy","security-deploy-trigger_security-deploy","security-deploy-image-sources_security-deploy","security-deploy-signature_security-deploy","security-deploy-secrets_security-deploy","security-deploy-continuous_security-deploy","security-platform","security-platform-multi-tenancy_security-platform","security-platform-admission_security-platform","security-deployment-sccs_security-platform","security-service-account_security-platform","security-platform-authentication_security-platform","security-platform-auth-controlling-access_security-platform","security-platform-api-access-control_security-platform","security-platform-red-hat-sso_security-platform","security-platform-auth-secure-self-service-web-console_security-platform","security-platform-certificates_security-platform","security-platform-config-custom-certs_security-platform","security-network","security-network-namespaces_security-network","security-network-policies_security-network","security-network-multiple-pod_security-network","security-network-isolating_security-network","security-network-ingress_security-network","security-network-egress_security-network","security-storage","security-network-storage-persistent_security-storage","security-network-storage-shared_security-storage","security-network-storage-block_security-storage","security-monitoring","security-monitoring-events_security-monitoring","security-monitoring-cluster-logging_security-monitoring","security-monitoring-audit-logs_security-monitoring","/documentation/openshift_container_platform/4.8/html/security_and_compliance/container-security-1",{"title":587,"visible":17,"weight":53,"urlFragment":588,"anchor":23,"singlePageAnchor":588,"subChapters":589,"url":608,"docTitle":491},"Configuring certificates","configuring-certificates",[590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607],"replacing-default-ingress","understanding-default-ingress_replacing-default-ingress","replacing-default-ingress_replacing-default-ingress","api-server-certificates","customize-certificates-api-add-named_api-server-certificates","add-service-serving","understanding-service-serving_service-serving-certificate","add-service-certificate_service-serving-certificate","add-service-certificate-configmap_service-serving-certificate","add-service-certificate-apiservice_service-serving-certificate","add-service-certificate-crd_service-serving-certificate","add-service-certificate-mutating-webhook_service-serving-certificate","add-service-certificate-validating-webhook_service-serving-certificate","rotate-service-serving_service-serving-certificate","manually-rotate-service-ca_service-serving-certificate","updating-ca-bundle","ca-bundle-understanding_updating-ca-bundle","ca-bundle-replacing_updating-ca-bundle","/documentation/openshift_container_platform/4.8/html/security_and_compliance/configuring-certificates",{"title":610,"visible":17,"weight":75,"urlFragment":611,"anchor":23,"singlePageAnchor":611,"subChapters":612,"url":679,"docTitle":491},"Certificate types and descriptions","certificate-types-and-descriptions",[613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678],"cert-types-user-provided-certificates-for-the-api-server","purpose","location","management","expiration","customization","cert-types-proxy-certificates","purpose-2","managing-proxy-certificates-during-installation","location-2","expiration-2","services","management-2","customization-2","renewal","cert-types-service-ca-certificates","purpose-3","expiration-3","management-3","services-2","cert-types-node-certificates","purpose-4","management-4","cert-types-bootstrap-certificates","purpose-5","management-5","expiration-4","customization-3","cert-types-etcd-certificates","purpose-6","expiration-5","management-6","services-3","cert-types-olm-certificates","management-7","cert-types-aggregated-api-client-certificates","purpose-7","management-8","expiration-6","customization-4","cert-types-machine-config-operator-certificates","purpose-8","management-9","expiration-7","customization-5","cert-types-user-provided-certificates-for-default-ingress","purpose-9","location-3","management-10","expiration-8","services-4","customization-6","cert-types-ingress-certificates","purpose-10","location-4","workflow","expiration-9","services-5","management-11","renewal-2","cert-types-monitoring-and-cluster-logging-operator-component-certificates","expiration-10","management-12","cert-types-control-plane-certificates","location-5","management-13","/documentation/openshift_container_platform/4.8/html/security_and_compliance/certificate-types-and-descriptions",{"title":681,"visible":17,"weight":442,"urlFragment":682,"anchor":23,"singlePageAnchor":682,"subChapters":683,"url":809,"docTitle":491},"Compliance Operator","compliance-operator",[684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808],"compliance-operator-release-notes","compliance-operator-release-notes-0-1-59","compliance-operator-0-1-59-new-features-and-enhancements","compliance-operator-0-1-59-bug-fixes","compliance-operator-release-notes-0-1-57","compliance-operator-0-1-57-new-features-and-enhancements","compliance-operator-0-1-57-bug-fixes","compliance-operator-0-1-57-deprecations","compliance-operator-release-notes-0-1-53","compliance-operator-0-1-53-bug-fixes","compliance-operator-0-1-53-known-issue","compliance-operator-release-notes-0-1-52","compliance-operator-0-1-52-new-features-and-enhancements","compliance-operator-0-1-52-bug-fixes","compliance-operator-0-1-52-known-issue","compliance-operator-release-notes-0-1-49","compliance-operator-0-1-49-bug-fixes","compliance-operator-release-notes-0-1-48","openshift-compliance-operator-0-1-48-bug-fixes","compliance-operator-release-notes-0-1-47","compliance-operator-0-1-47-new-features-and-enhancements","openshift-compliance-operator-0-1-47-bug-fixes","compliance-operator-release-notes-0-1-44","compliance-operator-0-1-44-new-features-and-enhancements","openshift-compliance-operator-0-1-44-templating","openshift-compliance-operator-0-1-44-bug-fixes","compliance-operator-release-notes-0-1-39","compliance-operator-0-1-39-new-features-and-enhancements","compliance-operator-release-notes_additional-resources","compliance-operator-supported-profiles","compliance-supported-profiles_compliance-operator-supported-profiles","additional-resources-compliance-operator-","compliance-operator-installation","installing-compliance-operator-web-console_compliance-operator-installation","installing-compliance-operator-cli_compliance-operator-installation","additional-resources-installing-the-compliance-operator","compliance-operator-updating","olm-preparing-upgrade_compliance-operator-updating","olm-changing-update-channel_compliance-operator-updating","olm-approving-pending-upgrade_compliance-operator-updating","compliance-operator-scans","running-compliance-scans_compliance-operator-scans","running-compliance-scans-worker-node_compliance-operator-scans","compliance-scansetting-cr_compliance-operator-scans","compliance-applying-resource-requests-and-limits_compliance-operator-scans","compliance-scheduling-pods-with-resource-requests_compliance-operator-scans","understanding-compliance-operator","compliance_profiles_understanding-compliance","compliance-operator-understanding","compliance-profilebundle_managing-compliance","compliance-update_managing-compliance","additional-resources_managing-the-compliance-operator","compliance-operator-tailor","compliance-new-tailored-profiles_compliance-tailor","compliance-tailored-profiles_compliance-tailor","compliance-operator-raw-results","compliance-results_compliance-raw-results","compliance-operator-remediation","filtering-compliance-check-results_compliance-remediation","compliance-review_compliance-remediation","compliance-operator-apply-remediation-for-customized-mcp","compliance-evaluate-kubeletconfig-rules_compliance-remediation","compliance-custom-node-pools_compliance-remediation","compliance-kubeletconfig-sub-pool-remediation_compliance-remediation","compliance-applying_compliance-remediation","compliance-manual_compliance-remediation","compliance-updating_compliance-remediation","compliance-unapplying_compliance-remediation","compliance-removing-kubeletconfig_compliance-remediation","compliance-inconsistent_compliance-remediation","additional-resources-9","compliance-operator-advanced","compliance-objects_compliance-advanced","compliance-priorityclass_compliance-advanced","compliance-raw-tailored_compliance-advanced","compliance-rescan_compliance-advanced","compliance-custom-storage_compliance-advanced","using-custom-result-storage-values_compliance-advanced","installing-compliance-operator-cli_compliance-advanced","automatically-update-remediations_compliance-advanced","compliance-custom-scc_compliance-advanced","additional-resources_compliance-operator-advanced","compliance-operator-troubleshooting","compliance-anatomy_compliance-troubleshooting","compliance-anatomy-compliance-sources_compliance-troubleshooting","compliance-anatomy-scan-setting-scan-binding-lifecycle_compliance-troubleshooting","compliance-suite-lifecycle-debugging_compliance-troubleshooting","compliance-scan-lifecycle-debugging_compliance-troubleshooting","compliance-scan-pending-phase_compliance-troubleshooting","compliance-scan-launching-phase_compliance-troubleshooting","compliance-scan-running-phase_compliance-troubleshooting","compliance-scan-aggregating-phase_compliance-troubleshooting","compliance-scan-done-phase_compliance-troubleshooting","compliance-remediation-lifecycle-debugging_compliance-troubleshooting","compliance-operator-useful-labels_compliance-troubleshooting","compliance-increasing-operator-limits_compliance-troubleshooting","operator-resource-constraints_compliance-troubleshooting","support_compliance-troubleshooting","compliance-operator-uninstallation_compliance-troubleshooting","compliance-operator-uninstall_compliance-operator-uninstallation","using-oc-compliance-plug-in","installing-oc-compliance_oc-compliance-plug-in-understanding","fetching-raw-results_oc-compliance-plug-in-understanding","re-running-scans_oc-compliance-plug-in-understanding","using-scan-setting-bindings_oc-compliance-plug-in-understanding","printing-controls_oc-compliance-plug-in-understanding","fetching-compliance-remediation-details_oc-compliance-plug-in-understanding","viewing-compliance-remediation-details_oc-compliance-plug-in-understanding","custom-resource-definitions","custom-resource-definitions-workflow_compliance-crd","defining-compliance-scan-requirements_compliance-crd","profile-bundle-object_compliance-crd","profile-object_compliance-crd","rule-object_compliance-crd","tailored-profile-object_compliance-crd","configure-compliance-scan-settings_compliance-crd","scan-setting-object_compliance-crd","process-compliance-requirements-with-compliance-settings_compliance-crd","scan-setting-binding-object_compliance-crd","track-compliance-scans_compliance-crd","compliance-suite-object_compliance-crd","advance-compliance-scan-object_compliance-crd","view-compliance-results_compliance-crd","compliance-check-result_compliance-crd","compliance-remediation-object_compliance-crd","/documentation/openshift_container_platform/4.8/html/security_and_compliance/compliance-operator",{"title":811,"visible":17,"weight":460,"urlFragment":812,"anchor":23,"singlePageAnchor":812,"subChapters":813,"url":863,"docTitle":491},"File Integrity Operator","file-integrity-operator",[814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862],"file-integrity-operator-release-notes","file-integrity-operator-release-notes-1-0-0","file-integrity-operator-release-notes-0-1-32","file-integrity-operator-0-1-32-bug-fixes","file-integrity-operator-release-notes-0-1-30","file-integrity-operator-0-1-30-bug-fixes","file-integrity-operator-release-notes-0-1-24","file-integrity-operator-0-1-24-new-features-and-enhancements","openshift-file-integrity-operator-0-1-24-bug-fixes","file-integrity-operator-release-notes-0-1-22","openshift-file-integrity-operator-0-1-22-bug-fixes","file-integrity-operator-release-notes-0-1-21","file-integrity-operator-0-1-21-new-features-and-enhancements","openshift-file-integrity-operator-0-1-21-bug-fixes","file-integrity-operator-release-notes_additional-resources","installing-file-integrity-operator","installing-file-integrity-operator-using-web-console_file-integrity-operator-installation","installing-file-integrity-operator-using-cli_file-integrity-operator-installation","additional-resources-installing-the-file-integrity-operator","file-integrity-operator-updating","olm-preparing-upgrade_file-integrity-operator-updating","olm-changing-update-channel_file-integrity-operator-updating","olm-approving-pending-upgrade_file-integrity-operator-updating","understanding-file-integrity-operator","understanding-file-integrity-custom-resource_file-integrity-operator","checking-the-file-integrity-CR-status_file-integrity-operator","file-integrity-CR-phases_file-integrity-operator","understanding-file-integrity-node-statuses-object_file-integrity-operator","file-integrity-node-status-types_file-integrity-operator","file-integrity-node-status-success_file-integrity-operator","file-integrity-node-status-failure_file-integrity-operator","file-integrity-events_file-integrity-operator","configuring-file-integrity-operator","viewing-file-integrity-object-attributes_file-integrity-operator","important-file-integrity-object-attributes_file-integrity-operator","file-integrity-examine-default-config_file-integrity-operator","file-integrity-understanding-default-config_file-integrity-operator","file-integrity-operator-supplying-custom-aide-config_file-integrity-operator","file-integrity-operator-defining-custom-config_file-integrity-operator","file-integrity-operator-changing-custom-config_file-integrity-operator","file-integrity-operator-advanced-usage","file-integrity-operator-reinitializing-database_file-integrity-operator","file-integrity-operator-machine-config-integration_file-integrity-operator","file-integrity-operator-exploring-daemon-sets_file-integrity-operator","troubleshooting-file-integrity-operator","general-troubleshooting","checking-the-aide-configuration","determining-the-fileintegrity-object-s-phase","determining-that-the-daemon-set-s-pods-are-running-on-the-expected-nodes","/documentation/openshift_container_platform/4.8/html/security_and_compliance/file-integrity-operator",{"title":865,"visible":17,"weight":475,"urlFragment":866,"anchor":23,"singlePageAnchor":866,"subChapters":867,"url":873,"docTitle":491},"Viewing audit logs","audit-log-view",[868,869,870,871,872],"nodes-pods-audit-log-basic_audit-log-view","nodes-nodes-audit-log-basic-viewing_audit-log-view","security-audit-log-basic-filtering_audit-log-view","gathering-data-audit-logs_audit-log-view","viewing-audit-logs-additional-resources","/documentation/openshift_container_platform/4.8/html/security_and_compliance/audit-log-view",{"title":875,"visible":17,"weight":876,"urlFragment":877,"anchor":23,"singlePageAnchor":877,"subChapters":878,"url":881,"docTitle":491},"Configuring the audit log policy",9,"audit-log-policy-config",[879,880],"about-audit-log-profiles_audit-log-policy-config","configuring-audit-policy_audit-log-policy-config","/documentation/openshift_container_platform/4.8/html/security_and_compliance/audit-log-policy-config",{"title":883,"visible":17,"weight":884,"urlFragment":885,"anchor":23,"singlePageAnchor":885,"subChapters":886,"url":892,"docTitle":491},"Configuring TLS security profiles",10,"tls-security-profiles",[887,888,889,890,891],"tls-profiles-understanding_tls-security-profiles","tls-profiles-view-details_tls-security-profiles","tls-profiles-ingress-configuring_tls-security-profiles","tls-profiles-kubernetes-configuring_tls-security-profiles","tls-profiles-kubelet-configuring_tls-security-profiles","/documentation/openshift_container_platform/4.8/html/security_and_compliance/tls-security-profiles",{"title":894,"visible":17,"weight":895,"urlFragment":896,"anchor":23,"singlePageAnchor":896,"subChapters":897,"url":903,"docTitle":491},"Configuring seccomp profiles",11,"seccomp-profiles",[898,899,900,901,902],"configuring-default-seccomp-profile_configuring-seccomp-profiles","custom-seccomp-profile","setting-custom-seccomp-profile_configuring-seccomp-profiles","applying-custom-seccomp-profile_configuring-seccomp-profiles","additional-resources_configuring-seccomp-profiles","/documentation/openshift_container_platform/4.8/html/security_and_compliance/seccomp-profiles",{"title":905,"visible":17,"weight":906,"urlFragment":907,"anchor":23,"singlePageAnchor":907,"subChapters":908,"url":910,"docTitle":491},"Allowing JavaScript-based access to the API server from additional hosts",12,"allowing-javascript-based-access-api-server",[909],"auth-allowing-javascript-access-api-server_auth-allowed-origins","/documentation/openshift_container_platform/4.8/html/security_and_compliance/allowing-javascript-based-access-api-server",{"title":912,"visible":17,"weight":913,"urlFragment":914,"anchor":23,"singlePageAnchor":914,"subChapters":915,"url":919,"docTitle":491},"Encrypting etcd data",13,"encrypting-etcd",[916,917,918],"about-etcd_encrypting-etcd","enabling-etcd-encryption_encrypting-etcd","disabling-etcd-encryption_encrypting-etcd","/documentation/openshift_container_platform/4.8/html/security_and_compliance/encrypting-etcd",{"title":921,"visible":17,"weight":922,"urlFragment":923,"anchor":23,"singlePageAnchor":923,"subChapters":924,"url":927,"docTitle":491},"Scanning pods for vulnerabilities",14,"pod-vulnerability-scan",[925,926],"security-pod-scan-cso_pod-vulnerability-scan","security-pod-scan-query-cli_pod-vulnerability-scan","/documentation/openshift_container_platform/4.8/html/security_and_compliance/pod-vulnerability-scan",{"title":929,"visible":17,"categoryName":17,"sections":930},"Install",[931],{"title":932,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":933,"url":934,"docTitle":935,"sections":936},"Installing",[],"/documentation/openshift_container_platform/4.8/html/installing/index","installing",[937,946,959,981,1280,1484,1801,1982,2066,2166,2274,2380,2683,2804,3069,3337,3393,3419,3434,3446],{"title":938,"visible":17,"weight":30,"urlFragment":939,"anchor":23,"singlePageAnchor":939,"subChapters":940,"url":945,"docTitle":935},"OpenShift Container Platform installation overview","ocp-installation-overview",[941,942,943,944],"installation-overview_ocp-installation-overview","installation-process_ocp-installation-overview","ipi-verifying-nodes-after-installation_ocp-installation-overview","supported-platforms-for-openshift-clusters_ocp-installation-overview","/documentation/openshift_container_platform/4.8/html/installing/ocp-installation-overview",{"title":947,"visible":17,"weight":42,"urlFragment":948,"anchor":23,"singlePageAnchor":948,"subChapters":949,"url":958,"docTitle":935},"Selecting a cluster installation method and preparing it for users","installing-preparing",[950,951,952,953,954,955,956,957],"installing-preparing-selecting-cluster-type","installing-preparing-install-manage","installing-preparing-migrate","installing-preparing-existing-components","installing-preparing-security","installing-preparing-cluster-for-users","installing-preparing-cluster-for-workloads","supported-installation-methods-for-different-platforms","/documentation/openshift_container_platform/4.8/html/installing/installing-preparing",{"title":960,"visible":17,"weight":53,"urlFragment":961,"anchor":23,"singlePageAnchor":961,"subChapters":962,"url":980,"docTitle":935},"Mirroring images for a disconnected installation","installing-mirroring-installation-images",[963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979],"prerequisites_installing-mirroring-installation-images","installation-about-mirror-registry_installing-mirroring-installation-images","installing-preparing-mirror","cli-installing-cli_installing-mirroring-installation-images","installation-adding-registry-pull-secret_installing-mirroring-installation-images","mirror-registry","mirror-registry-introduction_installing-mirroring-installation-images","mirror-registry-localhost_installing-mirroring-installation-images","mirror-registry-remote_installing-mirroring-installation-images","upgrading-mirror-registry_installing-mirroring-installation-images","uninstalling-mirror-registry_installing-mirroring-installation-images","mirror-registry-flags_installing-mirroring-installation-images","installation-mirror-repository_installing-mirroring-installation-images","installing-preparing-samples-operator","installation-images-samples-disconnected-mirroring-assist_installing-mirroring-installation-images","next-steps","restricted-networks-additional-resources","/documentation/openshift_container_platform/4.8/html/installing/installing-mirroring-installation-images",{"title":982,"visible":17,"weight":75,"urlFragment":983,"anchor":23,"singlePageAnchor":983,"subChapters":984,"url":1279,"docTitle":935},"Installing on AWS","installing-on-aws",[985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278],"preparing-to-install-on-aws","preparing-to-install-on-aws-prerequisites","requirements-for-installing-ocp-on-aws","choosing-an-method-to-install-ocp-on-aws","choosing-an-method-to-install-ocp-on-aws-installer-provisioned","choosing-an-method-to-install-ocp-on-aws-user-provisioned","preparing-to-install-on-aws-next-steps","installing-aws-account","installation-aws-route53_installing-aws-account","nw-endpoint-route53_installing-aws-account","installation-aws-limits_installing-aws-account","installation-aws-permissions_installing-aws-account","installation-aws-iam-user_installing-aws-account","iam-policies-and-aws-authentication_installing-aws-account","installation-aws-permissions-iam-roles_installing-aws-account","specify-an-existing-iam-role_installing-aws-account","create-custom-permissions-for-iam-instance-profiles_installing-aws-account","installation-aws-marketplace_installing-aws-account","installation-aws-regions_installing-aws-account","next-steps-2","manually-creating-iam-aws","alternatives-to-storing-admin-secrets-in-kube-system_manually-creating-iam-aws","manually-create-iam_manually-creating-iam-aws","manually-maintained-credentials-upgrade_manually-creating-iam-aws","mint-mode_manually-creating-iam-aws","mint-mode-with-removal-or-rotation-of-admin-credential_manually-creating-iam-aws","manually-creating-iam-aws-next-steps","installing-aws-default","prerequisites","cluster-entitlements_installing-aws-default","ssh-agent-using_installing-aws-default","installation-obtaining-installer_installing-aws-default","installation-launching-installer_installing-aws-default","cli-installing-cli_installing-aws-default","cli-logging-in-kubeadmin_installing-aws-default","logging-in-by-using-the-web-console_installing-aws-default","cluster-telemetry_installing-aws-default","next-steps-3","installing-aws-customizations","prerequisites-2","cluster-entitlements_installing-aws-customizations","ssh-agent-using_installing-aws-customizations","installation-aws-marketplace-subscribe_installing-aws-customizations","installation-obtaining-installer_installing-aws-customizations","installation-initializing_installing-aws-customizations","installation-configuration-parameters_installing-aws-customizations","installation-configuration-parameters-required_installing-aws-customizations","installation-configuration-parameters-network_installing-aws-customizations","installation-configuration-parameters-optional_installing-aws-customizations","installation-configuration-parameters-optional-aws_installing-aws-customizations","installation-supported-aws-machine-types_installing-aws-customizations","installation-aws-config-yaml_installing-aws-customizations","installation-configure-proxy_installing-aws-customizations","installation-launching-installer_installing-aws-customizations","cli-installing-cli_installing-aws-customizations","cli-logging-in-kubeadmin_installing-aws-customizations","logging-in-by-using-the-web-console_installing-aws-customizations","cluster-telemetry_installing-aws-customizations","next-steps-4","installing-aws-network-customizations","prerequisites-3","cluster-entitlements_installing-aws-network-customizations","ssh-agent-using_installing-aws-network-customizations","installation-obtaining-installer_installing-aws-network-customizations","nw-network-config_installing-aws-network-customizations","installation-initializing_installing-aws-network-customizations","installation-configuration-parameters_installing-aws-network-customizations","installation-configuration-parameters-required_installing-aws-network-customizations","installation-configuration-parameters-network_installing-aws-network-customizations","installation-configuration-parameters-optional_installing-aws-network-customizations","installation-configuration-parameters-optional-aws_installing-aws-network-customizations","installation-supported-aws-machine-types_installing-aws-network-customizations","installation-aws-config-yaml_installing-aws-network-customizations","installation-configure-proxy_installing-aws-network-customizations","nw-operator-cr_installing-aws-network-customizations","nw-operator-cr-cno-object_installing-aws-network-customizations","modifying-nwoperator-config-startup_installing-aws-network-customizations","nw-aws-nlb-new-cluster_installing-aws-network-customizations","configuring-hybrid-ovnkubernetes_installing-aws-network-customizations","installation-launching-installer_installing-aws-network-customizations","cli-installing-cli_installing-aws-network-customizations","cli-logging-in-kubeadmin_installing-aws-network-customizations","logging-in-by-using-the-web-console_installing-aws-network-customizations","cluster-telemetry_installing-aws-network-customizations","next-steps-5","installing-restricted-networks-aws-installer-provisioned","prerequisites_installing-restricted-networks-aws-installer-provisioned","installation-about-restricted-networks_installing-restricted-networks-aws-installer-provisioned","installation-restricted-network-limits_installing-restricted-networks-aws-installer-provisioned","installation-custom-aws-vpc_installing-restricted-networks-aws-installer-provisioned","installation-custom-aws-vpc-requirements_installing-restricted-networks-aws-installer-provisioned","installation-custom-aws-vpc-validation_installing-restricted-networks-aws-installer-provisioned","installation-about-custom-aws-permissions_installing-restricted-networks-aws-installer-provisioned","installation-custom-aws-vpc-isolation_installing-restricted-networks-aws-installer-provisioned","cluster-entitlements_installing-restricted-networks-aws-installer-provisioned","ssh-agent-using_installing-restricted-networks-aws-installer-provisioned","installation-initializing_installing-restricted-networks-aws-installer-provisioned","installation-configuration-parameters_installing-restricted-networks-aws-installer-provisioned","installation-configuration-parameters-required_installing-restricted-networks-aws-installer-provisioned","installation-configuration-parameters-network_installing-restricted-networks-aws-installer-provisioned","installation-configuration-parameters-optional_installing-restricted-networks-aws-installer-provisioned","installation-configuration-parameters-optional-aws_installing-restricted-networks-aws-installer-provisioned","installation-aws-config-yaml_installing-restricted-networks-aws-installer-provisioned","installation-configure-proxy_installing-restricted-networks-aws-installer-provisioned","installation-launching-installer_installing-restricted-networks-aws-installer-provisioned","cli-installing-cli_installing-restricted-networks-aws-installer-provisioned","cli-logging-in-kubeadmin_installing-restricted-networks-aws-installer-provisioned","olm-restricted-networks-operatorhub_installing-restricted-networks-aws-installer-provisioned","cluster-telemetry_installing-restricted-networks-aws-installer-provisioned","next-steps_installing-restricted-networks-aws-installer-provisioned","installing-aws-vpc","prerequisites-4","installation-custom-aws-vpc_installing-aws-vpc","installation-custom-aws-vpc-requirements_installing-aws-vpc","installation-custom-aws-vpc-validation_installing-aws-vpc","installation-about-custom-aws-permissions_installing-aws-vpc","installation-custom-aws-vpc-isolation_installing-aws-vpc","cluster-entitlements_installing-aws-vpc","ssh-agent-using_installing-aws-vpc","installation-obtaining-installer_installing-aws-vpc","installation-initializing_installing-aws-vpc","installation-configuration-parameters_installing-aws-vpc","installation-configuration-parameters-required_installing-aws-vpc","installation-configuration-parameters-network_installing-aws-vpc","installation-configuration-parameters-optional_installing-aws-vpc","installation-configuration-parameters-optional-aws_installing-aws-vpc","installation-supported-aws-machine-types_installing-aws-vpc","installation-aws-config-yaml_installing-aws-vpc","installation-configure-proxy_installing-aws-vpc","installation-launching-installer_installing-aws-vpc","cli-installing-cli_installing-aws-vpc","cli-logging-in-kubeadmin_installing-aws-vpc","logging-in-by-using-the-web-console_installing-aws-vpc","cluster-telemetry_installing-aws-vpc","next-steps-6","installing-aws-private","prerequisites-5","private-clusters-default_installing-aws-private","private-clusters-about-aws_installing-aws-private","private-clusters-limitations-aws_installing-aws-private","installation-custom-aws-vpc_installing-aws-private","installation-custom-aws-vpc-requirements_installing-aws-private","installation-custom-aws-vpc-validation_installing-aws-private","installation-about-custom-aws-permissions_installing-aws-private","installation-custom-aws-vpc-isolation_installing-aws-private","cluster-entitlements_installing-aws-private","ssh-agent-using_installing-aws-private","installation-obtaining-installer_installing-aws-private","installation-initializing-manual_installing-aws-private","installation-configuration-parameters_installing-aws-private","installation-configuration-parameters-required_installing-aws-private","installation-configuration-parameters-network_installing-aws-private","installation-configuration-parameters-optional_installing-aws-private","installation-configuration-parameters-optional-aws_installing-aws-private","installation-supported-aws-machine-types_installing-aws-private","installation-aws-config-yaml_installing-aws-private","installation-configure-proxy_installing-aws-private","installation-launching-installer_installing-aws-private","cli-installing-cli_installing-aws-private","cli-logging-in-kubeadmin_installing-aws-private","logging-in-by-using-the-web-console_installing-aws-private","cluster-telemetry_installing-aws-private","next-steps-7","installing-aws-government-region","prerequisites-6","installation-aws-about-government-region_installing-aws-government-region","private-clusters-default_installing-aws-government-region","private-clusters-about-aws_installing-aws-government-region","private-clusters-limitations-aws_installing-aws-government-region","installation-custom-aws-vpc_installing-aws-government-region","installation-custom-aws-vpc-requirements_installing-aws-government-region","installation-custom-aws-vpc-validation_installing-aws-government-region","installation-about-custom-aws-permissions_installing-aws-government-region","installation-custom-aws-vpc-isolation_installing-aws-government-region","cluster-entitlements_installing-aws-government-region","ssh-agent-using_installing-aws-government-region","installation-aws-marketplace-subscribe_installing-aws-government-region","installation-obtaining-installer_installing-aws-government-region","installation-initializing-manual_installing-aws-government-region","installation-configuration-parameters_installing-aws-government-region","installation-configuration-parameters-required_installing-aws-government-region","installation-configuration-parameters-network_installing-aws-government-region","installation-configuration-parameters-optional_installing-aws-government-region","installation-configuration-parameters-optional-aws_installing-aws-government-region","installation-supported-aws-machine-types_installing-aws-government-region","installation-aws-config-yaml_installing-aws-government-region","installation-aws-regions-with-no-ami_installing-aws-government-region","installation-aws-upload-custom-rhcos-ami_installing-aws-government-region","installation-configure-proxy_installing-aws-government-region","installation-launching-installer_installing-aws-government-region","cli-installing-cli_installing-aws-government-region","cli-logging-in-kubeadmin_installing-aws-government-region","logging-in-by-using-the-web-console_installing-aws-government-region","cluster-telemetry_installing-aws-government-region","next-steps-8","installing-aws-user-infra","prerequisites-7","cluster-entitlements_installing-aws-user-infra","installation-aws-user-infra-requirements_installing-aws-user-infra","installation-aws-user-infra-other-infrastructure_installing-aws-user-infra","installation-aws-user-infra-cluster-machines_installing-aws-user-infra","csr-management_installing-aws-user-infra","installation-supported-aws-machine-types_installing-aws-user-infra","installation-aws-permissions_installing-aws-user-infra","installation-aws-marketplace-subscribe_installing-aws-user-infra","installation-obtaining-installer_installing-aws-user-infra","ssh-agent-using_installing-aws-user-infra","installation-user-infra-generate_installing-aws-user-infra","installation-disk-partitioning-upi-templates_installing-aws-user-infra","installation-generate-aws-user-infra-install-config_installing-aws-user-infra","installation-configure-proxy_installing-aws-user-infra","installation-user-infra-generate-k8s-manifest-ignition_installing-aws-user-infra","installation-extracting-infraid_installing-aws-user-infra","installation-creating-aws-vpc_installing-aws-user-infra","installation-cloudformation-vpc_installing-aws-user-infra","installation-creating-aws-dns_installing-aws-user-infra","installation-cloudformation-dns_installing-aws-user-infra","installation-creating-aws-security_installing-aws-user-infra","installation-cloudformation-security_installing-aws-user-infra","installation-aws-ami-stream-metadata_installing-aws-user-infra","installation-aws-user-infra-rhcos-ami_installing-aws-user-infra","installation-aws-regions-with-no-ami_installing-aws-user-infra","installation-aws-upload-custom-rhcos-ami_installing-aws-user-infra","installation-creating-aws-bootstrap_installing-aws-user-infra","installation-cloudformation-bootstrap_installing-aws-user-infra","installation-creating-aws-control-plane_installing-aws-user-infra","installation-cloudformation-control-plane_installing-aws-user-infra","installation-creating-aws-worker_installing-aws-user-infra","installation-cloudformation-worker_installing-aws-user-infra","installation-aws-user-infra-bootstrap_installing-aws-user-infra","cli-installing-cli_installing-aws-user-infra","cli-logging-in-kubeadmin_installing-aws-user-infra","installation-approve-csrs_installing-aws-user-infra","installation-operators-config_installing-aws-user-infra","installation-registry-storage-config_installing-aws-user-infra","registry-configuring-storage-aws-user-infra_installing-aws-user-infra","installation-registry-storage-non-production_installing-aws-user-infra","installation-aws-user-infra-delete-bootstrap_installing-aws-user-infra","installation-create-ingress-dns-records_installing-aws-user-infra","installation-aws-user-infra-installation_installing-aws-user-infra","logging-in-by-using-the-web-console_installing-aws-user-infra","cluster-telemetry_installing-aws-user-infra","installing-aws-user-infra-additional-resources","installing-aws-user-infra-next-steps","installing-restricted-networks-aws","prerequisites-8","installation-about-restricted-networks_installing-restricted-networks-aws","installation-restricted-network-limits_installing-restricted-networks-aws","cluster-entitlements_installing-restricted-networks-aws","installation-aws-user-infra-requirements_installing-restricted-networks-aws","installation-aws-user-infra-other-infrastructure_installing-restricted-networks-aws","installation-aws-user-infra-cluster-machines_installing-restricted-networks-aws","csr-management_installing-restricted-networks-aws","installation-supported-aws-machine-types_installing-restricted-networks-aws","installation-aws-permissions_installing-restricted-networks-aws","ssh-agent-using_installing-restricted-networks-aws","installation-user-infra-generate_installing-restricted-networks-aws","installation-disk-partitioning-upi-templates_installing-restricted-networks-aws","installation-generate-aws-user-infra-install-config_installing-restricted-networks-aws","installation-configure-proxy_installing-restricted-networks-aws","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-aws","installation-extracting-infraid_installing-restricted-networks-aws","installation-creating-aws-vpc_installing-restricted-networks-aws","installation-cloudformation-vpc_installing-restricted-networks-aws","installation-creating-aws-dns_installing-restricted-networks-aws","installation-cloudformation-dns_installing-restricted-networks-aws","installation-creating-aws-security_installing-restricted-networks-aws","installation-cloudformation-security_installing-restricted-networks-aws","installation-aws-ami-stream-metadata_installing-restricted-networks-aws","installation-aws-user-infra-rhcos-ami_installing-restricted-networks-aws","installation-creating-aws-bootstrap_installing-restricted-networks-aws","installation-cloudformation-bootstrap_installing-restricted-networks-aws","installation-creating-aws-control-plane_installing-restricted-networks-aws","installation-cloudformation-control-plane_installing-restricted-networks-aws","installation-creating-aws-worker_installing-restricted-networks-aws","installation-cloudformation-worker_installing-restricted-networks-aws","installation-aws-user-infra-bootstrap_installing-restricted-networks-aws","cli-logging-in-kubeadmin_installing-restricted-networks-aws","installation-approve-csrs_installing-restricted-networks-aws","installation-operators-config_installing-restricted-networks-aws","olm-restricted-networks-operatorhub_installing-restricted-networks-aws","installation-registry-storage-config_installing-restricted-networks-aws","registry-configuring-storage-aws-user-infra_installing-restricted-networks-aws","installation-registry-storage-non-production_installing-restricted-networks-aws","installation-aws-user-infra-delete-bootstrap_installing-restricted-networks-aws","installation-create-ingress-dns-records_installing-restricted-networks-aws","installation-aws-user-infra-installation_installing-restricted-networks-aws","logging-in-by-using-the-web-console_installing-restricted-networks-aws","cluster-telemetry_installing-restricted-networks-aws","installing-restricted-networks-aws-additional-resources","installing-restricted-networks-aws-next-steps","uninstalling-cluster-aws","installation-uninstall-clouds_uninstall-cluster-aws","cco-ccoctl-deleting-sts-resources_uninstall-cluster-aws","/documentation/openshift_container_platform/4.8/html/installing/installing-on-aws",{"title":1281,"visible":17,"weight":442,"urlFragment":1282,"anchor":23,"singlePageAnchor":1282,"subChapters":1283,"url":1483,"docTitle":935},"Installing on Azure","installing-on-azure",[1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482],"preparing-to-install-on-azure","preparing-to-install-on-azure-prerequisites","requirements-for-installing-ocp-on-azure","choosing-an-method-to-install-ocp-on-azure","choosing-an-method-to-install-ocp-on-azure-installer-provisioned","choosing-an-method-to-install-ocp-on-azure-user-provisioned","preparing-to-install-on-azure-next-steps","installing-azure-account","installation-azure-limits_installing-azure-account","installation-azure-network-config_installing-azure-account","installation-azure-increasing-limits_installing-azure-account","installation-azure-permissions_installing-azure-account","installation-azure-service-principal_installing-azure-account","installation-azure-marketplace_installing-azure-account","installation-azure-regions_installing-azure-account","next-steps-9","manually-creating-iam-azure","alternatives-to-storing-admin-secrets-in-kube-system_manually-creating-iam-azure","manually-create-iam_manually-creating-iam-azure","manually-maintained-credentials-upgrade_manually-creating-iam-azure","manually-creating-iam-azure-next-steps","installing-azure-default","prerequisites-9","cluster-entitlements_installing-azure-default","ssh-agent-using_installing-azure-default","installation-obtaining-installer_installing-azure-default","installation-launching-installer_installing-azure-default","cli-installing-cli_installing-azure-default","cli-logging-in-kubeadmin_installing-azure-default","cluster-telemetry_installing-azure-default","next-steps-10","installing-azure-customizations","prerequisites-10","cluster-entitlements_installing-azure-customizations","ssh-agent-using_installing-azure-customizations","installation-azure-marketplace-subscribe_installing-azure-customizations","installation-obtaining-installer_installing-azure-customizations","installation-initializing_installing-azure-customizations","installation-configuration-parameters_installing-azure-customizations","installation-configuration-parameters-required_installing-azure-customizations","installation-configuration-parameters-network_installing-azure-customizations","installation-configuration-parameters-optional_installing-azure-customizations","installation-configuration-parameters-additional-azure_installing-azure-customizations","installation-azure-config-yaml_installing-azure-customizations","installation-configure-proxy_installing-azure-customizations","installation-azure-marketplace-manifests_installing-azure-customizations","installation-launching-installer_installing-azure-customizations","cli-installing-cli_installing-azure-customizations","cli-logging-in-kubeadmin_installing-azure-customizations","cluster-telemetry_installing-azure-customizations","next-steps-11","installing-azure-network-customizations","prerequisites-11","cluster-entitlements_installing-azure-network-customizations","ssh-agent-using_installing-azure-network-customizations","installation-obtaining-installer_installing-azure-network-customizations","installation-initializing_installing-azure-network-customizations","installation-configuration-parameters_installing-azure-network-customizations","installation-configuration-parameters-required_installing-azure-network-customizations","installation-configuration-parameters-network_installing-azure-network-customizations","installation-configuration-parameters-optional_installing-azure-network-customizations","installation-configuration-parameters-additional-azure_installing-azure-network-customizations","installation-azure-config-yaml_installing-azure-network-customizations","installation-configure-proxy_installing-azure-network-customizations","nw-network-config_installing-azure-network-customizations","modifying-nwoperator-config-startup_installing-azure-network-customizations","nw-operator-cr_installing-azure-network-customizations","nw-operator-cr-cno-object_installing-azure-network-customizations","configuring-hybrid-ovnkubernetes_installing-azure-network-customizations","installation-launching-installer_installing-azure-network-customizations","cli-installing-cli_installing-azure-network-customizations","cli-logging-in-kubeadmin_installing-azure-network-customizations","cluster-telemetry_installing-azure-network-customizations","next-steps-12","installing-azure-vnet","prerequisites-12","installation-about-custom-azure-vnet_installing-azure-vnet","installation-about-custom-azure-vnet-requirements_installing-azure-vnet","installation-about-custom-azure-vnet-nsg-requirements_installing-azure-vnet","installation-about-custom-azure-permissions_installing-azure-vnet","installation-about-custom-azure-vnet-isolation_installing-azure-vnet","cluster-entitlements_installing-azure-vnet","ssh-agent-using_installing-azure-vnet","installation-obtaining-installer_installing-azure-vnet","installation-initializing_installing-azure-vnet","installation-configuration-parameters_installing-azure-vnet","installation-configuration-parameters-required_installing-azure-vnet","installation-configuration-parameters-network_installing-azure-vnet","installation-configuration-parameters-optional_installing-azure-vnet","installation-configuration-parameters-additional-azure_installing-azure-vnet","installation-azure-config-yaml_installing-azure-vnet","installation-configure-proxy_installing-azure-vnet","installation-launching-installer_installing-azure-vnet","cli-installing-cli_installing-azure-vnet","cli-logging-in-kubeadmin_installing-azure-vnet","cluster-telemetry_installing-azure-vnet","next-steps-13","installing-azure-private","prerequisites-13","private-clusters-default_installing-azure-private","private-clusters-about-azure_installing-azure-private","private-clusters-limitations-azure_installing-azure-private","installation-azure-user-defined-routing_installing-azure-private","installation-about-custom-azure-vnet_installing-azure-private","installation-about-custom-azure-vnet-requirements_installing-azure-private","installation-about-custom-azure-vnet-nsg-requirements_installing-azure-private","installation-about-custom-azure-permissions_installing-azure-private","installation-about-custom-azure-vnet-isolation_installing-azure-private","cluster-entitlements_installing-azure-private","ssh-agent-using_installing-azure-private","installation-obtaining-installer_installing-azure-private","installation-initializing-manual_installing-azure-private","installation-configuration-parameters_installing-azure-private","installation-configuration-parameters-required_installing-azure-private","installation-configuration-parameters-network_installing-azure-private","installation-configuration-parameters-optional_installing-azure-private","installation-configuration-parameters-additional-azure_installing-azure-private","installation-azure-config-yaml_installing-azure-private","installation-configure-proxy_installing-azure-private","installation-launching-installer_installing-azure-private","cli-installing-cli_installing-azure-private","cli-logging-in-kubeadmin_installing-azure-private","cluster-telemetry_installing-azure-private","next-steps-14","installing-azure-government-region","prerequisites-14","installation-azure-about-government-region_installing-azure-government-region","private-clusters-default_installing-azure-government-region","private-clusters-about-azure_installing-azure-government-region","private-clusters-limitations-azure_installing-azure-government-region","installation-azure-user-defined-routing_installing-azure-government-region","installation-about-custom-azure-vnet_installing-azure-government-region","installation-about-custom-azure-vnet-requirements_installing-azure-government-region","installation-about-custom-azure-vnet-nsg-requirements_installing-azure-government-region","installation-about-custom-azure-permissions_installing-azure-government-region","installation-about-custom-azure-vnet-isolation_installing-azure-government-region","cluster-entitlements_installing-azure-government-region","ssh-agent-using_installing-azure-government-region","installation-obtaining-installer_installing-azure-government-region","installation-initializing-manual_installing-azure-government-region","installation-configuration-parameters_installing-azure-government-region","installation-configuration-parameters-required_installing-azure-government-region","installation-configuration-parameters-network_installing-azure-government-region","installation-configuration-parameters-optional_installing-azure-government-region","installation-configuration-parameters-additional-azure_installing-azure-government-region","installation-azure-config-yaml_installing-azure-government-region","installation-configure-proxy_installing-azure-government-region","installation-launching-installer_installing-azure-government-region","cli-installing-cli_installing-azure-government-region","cli-logging-in-kubeadmin_installing-azure-government-region","cluster-telemetry_installing-azure-government-region","next-steps-15","installing-azure-user-infra","prerequisites-15","cluster-entitlements_installing-azure-user-infra","installation-azure-user-infra-config-project","installation-azure-limits_installing-azure-user-infra","installation-azure-network-config_installing-azure-user-infra","installation-azure-increasing-limits_installing-azure-user-infra","csr-management_installing-azure-user-infra","installation-azure-permissions_installing-azure-user-infra","installation-azure-service-principal_installing-azure-user-infra","installation-azure-regions_installing-azure-user-infra","installation-azure-marketplace-subscribe_installing-azure-user-infra","installation-obtaining-installer_installing-azure-user-infra","ssh-agent-using_installing-azure-user-infra","installation-user-infra-generate_installing-azure-user-infra","installation-disk-partitioning-upi-templates_installing-azure-user-infra","installation-initializing_installing-azure-user-infra","installation-configure-proxy_installing-azure-user-infra","installation-user-infra-exporting-common-variables-arm-templates_installing-azure-user-infra","installation-user-infra-generate-k8s-manifest-ignition_installing-azure-user-infra","installation-azure-create-resource-group-and-identity_installing-azure-user-infra","installation-azure-user-infra-uploading-rhcos_installing-azure-user-infra","installation-azure-create-dns-zones_installing-azure-user-infra","installation-creating-azure-vnet_installing-azure-user-infra","installation-arm-vnet_installing-azure-user-infra","installation-azure-user-infra-deploying-rhcos_installing-azure-user-infra","installation-arm-image-storage_installing-azure-user-infra","installation-network-user-infra_installing-azure-user-infra","installation-host-names-dhcp-user-infra_installing-azure-user-infra","installation-network-connectivity-user-infra_installing-azure-user-infra","installation-creating-azure-dns_installing-azure-user-infra","installation-arm-dns_installing-azure-user-infra","installation-creating-azure-bootstrap_installing-azure-user-infra","installation-arm-bootstrap_installing-azure-user-infra","installation-creating-azure-control-plane_installing-azure-user-infra","installation-arm-control-plane_installing-azure-user-infra","installation-azure-user-infra-wait-for-bootstrap_installing-azure-user-infra","installation-creating-azure-worker_installing-azure-user-infra","installation-arm-worker_installing-azure-user-infra","cli-installing-cli_installing-azure-user-infra","cli-logging-in-kubeadmin_installing-azure-user-infra","installation-approve-csrs_installing-azure-user-infra","installation-azure-create-ingress-dns-records_installing-azure-user-infra","installation-azure-user-infra-completing_installing-azure-user-infra","cluster-telemetry_installing-azure-user-infra","uninstalling-cluster-azure","installation-uninstall-clouds_uninstall-cluster-azure","/documentation/openshift_container_platform/4.8/html/installing/installing-on-azure",{"title":1485,"visible":17,"weight":460,"urlFragment":1486,"anchor":23,"singlePageAnchor":1486,"subChapters":1487,"url":1800,"docTitle":935},"Installing on GCP","installing-on-gcp",[1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799],"preparing-to-install-on-gcp","preparing-to-install-on-gcp-prerequisites","requirements-for-installing-ocp-on-gcp","choosing-an-method-to-install-ocp-on-gcp","choosing-an-method-to-install-ocp-on-gcp-installer-provisioned","choosing-an-method-to-install-ocp-on-gcp-user-provisioned","preparing-to-install-on-gcp-next-steps","installing-gcp-account","installation-gcp-project_installing-gcp-account","installation-gcp-enabling-api-services_installing-gcp-account","installation-gcp-dns_installing-gcp-account","installation-gcp-limits_installing-gcp-account","installation-gcp-service-account_installing-gcp-account","installation-gcp-permissions_installing-gcp-account","installation-gcp-regions_installing-gcp-account","next-steps-16","manually-creating-iam-gcp","alternatives-to-storing-admin-secrets-in-kube-system_manually-creating-iam-gcp","manually-create-iam_manually-creating-iam-gcp","manually-maintained-credentials-upgrade_manually-creating-iam-gcp","mint-mode_manually-creating-iam-gcp","mint-mode-with-removal-or-rotation-of-admin-credential_manually-creating-iam-gcp","manually-creating-iam-gcp-next-steps","installing-gcp-default","prerequisites-16","cluster-entitlements_installing-gcp-default","ssh-agent-using_installing-gcp-default","installation-obtaining-installer_installing-gcp-default","installation-launching-installer_installing-gcp-default","cli-installing-cli_installing-gcp-default","cli-logging-in-kubeadmin_installing-gcp-default","cluster-telemetry_installing-gcp-default","next-steps-17","installing-gcp-customizations","prerequisites-17","cluster-entitlements_installing-gcp-customizations","ssh-agent-using_installing-gcp-customizations","installation-obtaining-installer_installing-gcp-customizations","installation-initializing_installing-gcp-customizations","installation-configuration-parameters_installing-gcp-customizations","installation-configuration-parameters-required_installing-gcp-customizations","installation-configuration-parameters-network_installing-gcp-customizations","installation-configuration-parameters-optional_installing-gcp-customizations","installation-configuration-parameters-additional-gcp_installing-gcp-customizations","installation-gcp-config-yaml_installing-gcp-customizations","installation-custom-machine-types_installing-gcp-customizations","installation-configure-proxy_installing-gcp-customizations","installation-gcp-marketplace_installing-gcp-customizations","installation-launching-installer_installing-gcp-customizations","cli-installing-cli_installing-gcp-customizations","cli-logging-in-kubeadmin_installing-gcp-customizations","cluster-telemetry_installing-gcp-customizations","next-steps-18","installing-gcp-network-customizations","prerequisites-18","cluster-entitlements_installing-gcp-network-customizations","ssh-agent-using_installing-gcp-network-customizations","installation-obtaining-installer_installing-gcp-network-customizations","installation-initializing_installing-gcp-network-customizations","installation-configuration-parameters_installing-gcp-network-customizations","installation-configuration-parameters-required_installing-gcp-network-customizations","installation-configuration-parameters-network_installing-gcp-network-customizations","installation-configuration-parameters-optional_installing-gcp-network-customizations","installation-configuration-parameters-additional-gcp_installing-gcp-network-customizations","installation-gcp-config-yaml_installing-gcp-network-customizations","additional-resources","installation-custom-machine-types_installing-gcp-network-customizations","installation-configure-proxy_installing-gcp-network-customizations","nw-network-config_installing-gcp-network-customizations","modifying-nwoperator-config-startup_installing-gcp-network-customizations","nw-operator-cr_installing-gcp-network-customizations","nw-operator-cr-cno-object_installing-gcp-network-customizations","installation-launching-installer_installing-gcp-network-customizations","cli-installing-cli_installing-gcp-network-customizations","cli-logging-in-kubeadmin_installing-gcp-network-customizations","cluster-telemetry_installing-gcp-network-customizations","next-steps-19","installing-restricted-networks-gcp-installer-provisioned","prerequisites_installing-restricted-networks-gcp-installer-provisioned","installation-about-restricted-networks_installing-restricted-networks-gcp-installer-provisioned","installation-restricted-network-limits_installing-restricted-networks-gcp-installer-provisioned","cluster-entitlements_installing-restricted-networks-gcp-installer-provisioned","ssh-agent-using_installing-restricted-networks-gcp-installer-provisioned","installation-initializing_installing-restricted-networks-gcp-installer-provisioned","installation-configuration-parameters_installing-restricted-networks-gcp-installer-provisioned","installation-configuration-parameters-required_installing-restricted-networks-gcp-installer-provisioned","installation-configuration-parameters-network_installing-restricted-networks-gcp-installer-provisioned","installation-configuration-parameters-optional_installing-restricted-networks-gcp-installer-provisioned","installation-configuration-parameters-additional-gcp_installing-restricted-networks-gcp-installer-provisioned","installation-gcp-config-yaml_installing-restricted-networks-gcp-installer-provisioned","nw-gcp-global-access-configuration_installing-restricted-networks-gcp-installer-provisioned","installation-custom-machine-types_installing-restricted-networks-gcp-installer-provisioned","installation-configure-proxy_installing-restricted-networks-gcp-installer-provisioned","installation-launching-installer_installing-restricted-networks-gcp-installer-provisioned","cli-installing-cli_installing-restricted-networks-gcp-installer-provisioned","cli-logging-in-kubeadmin_installing-restricted-networks-gcp-installer-provisioned","olm-restricted-networks-operatorhub_installing-restricted-networks-gcp-installer-provisioned","cluster-telemetry_installing-restricted-networks-gcp-installer-provisioned","next-steps_installing-restricted-networks-gcp-installer-provisioned","installing-gcp-vpc","prerequisites-19","installation-custom-gcp-vpc_installing-gcp-vpc","installation-custom-gcp-vpc-requirements_installing-gcp-vpc","installation-custom-gcp-vpc-validation_installing-gcp-vpc","installation-about-custom-gcp-permissions_installing-gcp-vpc","installation-custom-gcp-vpc-isolation_installing-gcp-vpc","cluster-entitlements_installing-gcp-vpc","ssh-agent-using_installing-gcp-vpc","installation-obtaining-installer_installing-gcp-vpc","installation-initializing_installing-gcp-vpc","installation-configuration-parameters_installing-gcp-vpc","installation-configuration-parameters-required_installing-gcp-vpc","installation-configuration-parameters-network_installing-gcp-vpc","installation-configuration-parameters-optional_installing-gcp-vpc","installation-configuration-parameters-additional-gcp_installing-gcp-vpc","installation-gcp-config-yaml_installing-gcp-vpc","nw-gcp-global-access-configuration_installing-gcp-vpc","additional-resources-2","installation-custom-machine-types_installing-gcp-vpc","installation-configure-proxy_installing-gcp-vpc","installation-launching-installer_installing-gcp-vpc","cli-installing-cli_installing-gcp-vpc","cli-logging-in-kubeadmin_installing-gcp-vpc","cluster-telemetry_installing-gcp-vpc","next-steps-20","installing-gcp-private","prerequisites-20","private-clusters-default_installing-gcp-private","private-clusters-about-gcp_installing-gcp-private","private-clusters-limitations-gcp_installing-gcp-private","installation-about-custom-gcp-vpc_installing-gcp-private","installation-about-custom-gcp-vpcs-requirements_installing-gcp-private","installation-about-custom-gcp-permissions_installing-gcp-private","installation-about-custom-gcp-vpcs-isolation_installing-gcp-private","cluster-entitlements_installing-gcp-private","ssh-agent-using_installing-gcp-private","installation-obtaining-installer_installing-gcp-private","installation-initializing-manual_installing-gcp-private","installation-configuration-parameters_installing-gcp-private","installation-configuration-parameters-required_installing-gcp-private","installation-configuration-parameters-network_installing-gcp-private","installation-configuration-parameters-optional_installing-gcp-private","installation-configuration-parameters-additional-gcp_installing-gcp-private","installation-gcp-config-yaml_installing-gcp-private","nw-gcp-global-access-configuration_installing-gcp-private","additional-resources-3","installation-custom-machine-types_installing-gcp-private","installation-configure-proxy_installing-gcp-private","installation-launching-installer_installing-gcp-private","cli-installing-cli_installing-gcp-private","cli-logging-in-kubeadmin_installing-gcp-private","cluster-telemetry_installing-gcp-private","next-steps-21","installing-gcp-user-infra","prerequisites-21","csr-management_installing-gcp-user-infra","cluster-entitlements_installing-gcp-user-infra","installation-gcp-user-infra-config-project","installation-gcp-project_installing-gcp-user-infra","installation-gcp-enabling-api-services_installing-gcp-user-infra","installation-gcp-dns_installing-gcp-user-infra","installation-gcp-limits_installing-gcp-user-infra","installation-gcp-service-account_installing-gcp-user-infra","installation-gcp-permissions_installing-gcp-user-infra","installation-gcp-regions_installing-gcp-user-infra","installation-gcp-install-cli_installing-gcp-user-infra","installation-user-infra-generate_installing-gcp-user-infra","installation-disk-partitioning-upi-templates_installing-gcp-user-infra","installation-initializing_installing-gcp-user-infra","installation-custom-machine-types_installing-gcp-user-infra","installation-configure-proxy_installing-gcp-user-infra","installation-user-infra-generate-k8s-manifest-ignition_installing-gcp-user-infra","installation-gcp-user-infra-exporting-common-variables","installation-extracting-infraid_installing-gcp-user-infra","installation-user-infra-exporting-common-variables_installing-gcp-user-infra","installation-creating-gcp-vpc_installing-gcp-user-infra","installation-deployment-manager-vpc_installing-gcp-user-infra","installation-network-user-infra_installing-gcp-user-infra","installation-host-names-dhcp-user-infra_installing-gcp-user-infra","installation-network-connectivity-user-infra_installing-gcp-user-infra","installation-creating-gcp-lb_installing-gcp-user-infra","installation-deployment-manager-ext-lb_installing-gcp-user-infra","installation-deployment-manager-int-lb_installing-gcp-user-infra","installation-creating-gcp-private-dns_installing-gcp-user-infra","installation-deployment-manager-private-dns_installing-gcp-user-infra","installation-creating-gcp-firewall-rules-vpc_installing-gcp-user-infra","installation-deployment-manager-firewall-rules_installing-gcp-user-infra","installation-creating-gcp-iam-shared-vpc_installing-gcp-user-infra","installation-deployment-manager-iam-shared-vpc_installing-gcp-user-infra","installation-gcp-user-infra-rhcos_installing-gcp-user-infra","installation-creating-gcp-bootstrap_installing-gcp-user-infra","installation-deployment-manager-bootstrap_installing-gcp-user-infra","installation-creating-gcp-control-plane_installing-gcp-user-infra","installation-deployment-manager-control-plane_installing-gcp-user-infra","installation-gcp-user-infra-wait-for-bootstrap_installing-gcp-user-infra","installation-creating-gcp-worker_installing-gcp-user-infra","installation-deployment-manager-worker_installing-gcp-user-infra","cli-installing-cli_installing-gcp-user-infra","cli-logging-in-kubeadmin_installing-gcp-user-infra","installation-approve-csrs_installing-gcp-user-infra","installation-gcp-user-infra-adding-ingress_installing-gcp-user-infra","installation-gcp-user-infra-installation_installing-gcp-user-infra","cluster-telemetry_installing-gcp-user-infra","next-steps-22","installing-gcp-user-infra-vpc","prerequisites-22","csr-management_installing-gcp-user-infra-vpc","cluster-entitlements_installing-gcp-user-infra-vpc","installation-gcp-user-infra-config-project-vpc","installation-gcp-project_installing-gcp-user-infra-vpc","installation-gcp-enabling-api-services_installing-gcp-user-infra-vpc","installation-gcp-limits_installing-gcp-user-infra-vpc","installation-gcp-service-account_installing-gcp-user-infra-vpc","installation-gcp-permissions_installing-gcp-user-infra-vpc","installation-gcp-regions_installing-gcp-user-infra-vpc","installation-gcp-install-cli_installing-gcp-user-infra-vpc","installation-gcp-user-infra-config-host-project-vpc_installing-gcp-user-infra-vpc","installation-gcp-dns_installing-gcp-user-infra-vpc","installation-creating-gcp-vpc_installing-gcp-user-infra-vpc","installation-deployment-manager-vpc_installing-gcp-user-infra-vpc","installation-user-infra-generate_installing-gcp-user-infra-vpc","installation-initializing-manual_installing-gcp-user-infra-vpc","installation-gcp-user-infra-shared-vpc-config-yaml_installing-gcp-user-infra-vpc","installation-custom-machine-types_installing-gcp-user-infra-vpc","installation-configure-proxy_installing-gcp-user-infra-vpc","installation-user-infra-generate-k8s-manifest-ignition_installing-gcp-user-infra-vpc","installation-gcp-user-infra-exporting-common-variables-vpc","installation-extracting-infraid_installing-gcp-user-infra-vpc","installation-user-infra-exporting-common-variables_installing-gcp-user-infra-vpc","installation-network-user-infra_installing-gcp-user-infra-vpc","installation-host-names-dhcp-user-infra_installing-gcp-user-infra-vpc","installation-network-connectivity-user-infra_installing-gcp-user-infra-vpc","installation-creating-gcp-lb_installing-gcp-user-infra-vpc","installation-deployment-manager-ext-lb_installing-gcp-user-infra-vpc","installation-deployment-manager-int-lb_installing-gcp-user-infra-vpc","installation-creating-gcp-private-dns_installing-gcp-user-infra-vpc","installation-deployment-manager-private-dns_installing-gcp-user-infra-vpc","installation-creating-gcp-firewall-rules-vpc_installing-gcp-user-infra-vpc","installation-deployment-manager-firewall-rules_installing-gcp-user-infra-vpc","installation-creating-gcp-iam-shared-vpc_installing-gcp-user-infra-vpc","installation-deployment-manager-iam-shared-vpc_installing-gcp-user-infra-vpc","installation-gcp-user-infra-rhcos_installing-gcp-user-infra-vpc","installation-creating-gcp-bootstrap_installing-gcp-user-infra-vpc","installation-deployment-manager-bootstrap_installing-gcp-user-infra-vpc","installation-creating-gcp-control-plane_installing-gcp-user-infra-vpc","installation-deployment-manager-control-plane_installing-gcp-user-infra-vpc","installation-gcp-user-infra-wait-for-bootstrap_installing-gcp-user-infra-vpc","installation-creating-gcp-worker_installing-gcp-user-infra-vpc","installation-deployment-manager-worker_installing-gcp-user-infra-vpc","cli-installing-cli_installing-gcp-user-infra-vpc","cli-logging-in-kubeadmin_installing-gcp-user-infra-vpc","installation-approve-csrs_installing-gcp-user-infra-vpc","installation-gcp-user-infra-adding-ingress_installing-gcp-user-infra-vpc","installation-gcp-user-infra-vpc-adding-firewall-rules","installation-creating-gcp-shared-vpc-cluster-wide-firewall-rules_installing-gcp-user-infra-vpc","installation-gcp-user-infra-installation_installing-gcp-user-infra-vpc","cluster-telemetry_installing-gcp-user-infra-vpc","next-steps-23","installing-restricted-networks-gcp","prerequisites-23","installation-about-restricted-networks_installing-restricted-networks-gcp","installation-restricted-network-limits_installing-restricted-networks-gcp","cluster-entitlements_installing-restricted-networks-gcp","installation-restricted-networks-gcp-user-infra-config-project","installation-gcp-project_installing-restricted-networks-gcp","installation-gcp-enabling-api-services_installing-restricted-networks-gcp","installation-gcp-dns_installing-restricted-networks-gcp","installation-gcp-limits_installing-restricted-networks-gcp","installation-gcp-service-account_installing-restricted-networks-gcp","installation-gcp-permissions_installing-restricted-networks-gcp","installation-gcp-regions_installing-restricted-networks-gcp","installation-gcp-install-cli_installing-restricted-networks-gcp","installation-user-infra-generate_installing-restricted-networks-gcp","installation-disk-partitioning-upi-templates_installing-restricted-networks-gcp","installation-initializing_installing-restricted-networks-gcp","installation-custom-machine-types_installing-restricted-networks-gcp","installation-configure-proxy_installing-restricted-networks-gcp","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-gcp","installation-restricted-networks-gcp-user-infra-exporting-common-variables","installation-extracting-infraid_installing-restricted-networks-gcp","installation-user-infra-exporting-common-variables_installing-restricted-networks-gcp","installation-creating-gcp-vpc_installing-restricted-networks-gcp","installation-deployment-manager-vpc_installing-restricted-networks-gcp","installation-network-user-infra_installing-restricted-networks-gcp","installation-host-names-dhcp-user-infra_installing-restricted-networks-gcp","installation-network-connectivity-user-infra_installing-restricted-networks-gcp","installation-creating-gcp-lb_installing-restricted-networks-gcp","installation-deployment-manager-ext-lb_installing-restricted-networks-gcp","installation-deployment-manager-int-lb_installing-restricted-networks-gcp","installation-creating-gcp-private-dns_installing-restricted-networks-gcp","installation-deployment-manager-private-dns_installing-restricted-networks-gcp","installation-creating-gcp-firewall-rules-vpc_installing-restricted-networks-gcp","installation-deployment-manager-firewall-rules_installing-restricted-networks-gcp","installation-creating-gcp-iam-shared-vpc_installing-restricted-networks-gcp","installation-deployment-manager-iam-shared-vpc_installing-restricted-networks-gcp","installation-gcp-user-infra-rhcos_installing-restricted-networks-gcp","installation-creating-gcp-bootstrap_installing-restricted-networks-gcp","installation-deployment-manager-bootstrap_installing-restricted-networks-gcp","installation-creating-gcp-control-plane_installing-restricted-networks-gcp","installation-deployment-manager-control-plane_installing-restricted-networks-gcp","installation-gcp-user-infra-wait-for-bootstrap_installing-restricted-networks-gcp","installation-creating-gcp-worker_installing-restricted-networks-gcp","installation-deployment-manager-worker_installing-restricted-networks-gcp","cli-logging-in-kubeadmin_installing-restricted-networks-gcp","olm-restricted-networks-operatorhub_installing-restricted-networks-gcp","installation-approve-csrs_installing-restricted-networks-gcp","installation-gcp-user-infra-adding-ingress_installing-restricted-networks-gcp","installation-gcp-user-infra-installation_installing-restricted-networks-gcp","cluster-telemetry_installing-restricted-networks-gcp","next-steps-24","uninstalling-cluster-gcp","installation-uninstall-clouds_uninstalling-cluster-gcp","/documentation/openshift_container_platform/4.8/html/installing/installing-on-gcp",{"title":1802,"visible":17,"weight":475,"urlFragment":1803,"anchor":23,"singlePageAnchor":1803,"subChapters":1804,"url":1981,"docTitle":935},"Installing on bare metal","installing-on-bare-metal",[1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980],"preparing-to-install-on-bare-metal","preparing_preparing-to-install-on-bare-metal","virt-planning-bare-metal-cluster-for-ocp-virt_preparing-to-install-on-bare-metal","choosing-a-method-to-install-ocp-on-bare-metal","choosing-a-method-to-install-ocp-on-bare-metal-installer-provisioned","choosing-a-method-to-install-ocp-on-bare-metal-user-provisioned","installing-bare-metal","prerequisites-24","cluster-entitlements_installing-bare-metal","installation-requirements-user-infra_installing-bare-metal","machine-requirements_installing-bare-metal","minimum-resource-requirements_installing-bare-metal","csr-management_installing-bare-metal","installation-network-user-infra_installing-bare-metal","installation-host-names-dhcp-user-infra_installing-bare-metal","installation-network-connectivity-user-infra_installing-bare-metal","installation-dns-user-infra_installing-bare-metal","installation-dns-user-infra-example_installing-bare-metal","installation-load-balancing-user-infra_installing-bare-metal","installation-load-balancing-user-infra-example_installing-bare-metal","installation-infrastructure-user-infra_installing-bare-metal","installation-user-provisioned-validating-dns_installing-bare-metal","ssh-agent-using_installing-bare-metal","installation-obtaining-installer_installing-bare-metal","cli-installing-cli_installing-bare-metal","installation-initializing-manual_installing-bare-metal","installation-configuration-parameters_installing-bare-metal","installation-configuration-parameters-required_installing-bare-metal","installation-configuration-parameters-network_installing-bare-metal","installation-configuration-parameters-optional_installing-bare-metal","installation-bare-metal-config-yaml_installing-bare-metal","installation-configure-proxy_installing-bare-metal","installation-three-node-cluster_installing-bare-metal","installation-user-infra-generate-k8s-manifest-ignition_installing-bare-metal","creating-machines-bare-metal_installing-bare-metal","installation-user-infra-machines-iso_installing-bare-metal","installation-user-infra-machines-pxe_installing-bare-metal","installation-user-infra-machines-advanced_installing-bare-metal","installation-user-infra-machines-advanced_network_installing-bare-metal","installation-user-infra-machines-advanced_disk_installing-bare-metal","installation-user-infra-machines-advanced_vardisk_installing-bare-metal","installation-user-infra-machines-advanced_retaindisk_installing-bare-metal","installation-user-infra-machines-advanced_ignition_installing-bare-metal","installation-user-infra-machines-advanced_embed_ignition_installing-bare-metal","installation-user-infra-machines-static-network_installing-bare-metal","installation-user-infra-machines-routing-bonding_installing-bare-metal","installation-user-infra-machines-coreos-installer-options_installing-bare-metal","installation-user-infra-machines-coreos-inst-options_installing-bare-metal","rhcos-enabling-multipath_installing-bare-metal","architecture-rhcos-updating-bootloader.adoc_installing-bare-metal","installation-installing-bare-metal_installing-bare-metal","cli-logging-in-kubeadmin_installing-bare-metal","installation-approve-csrs_installing-bare-metal","installation-operators-config_installing-bare-metal","registry-removed_installing-bare-metal","installation-registry-storage-config_installing-bare-metal","registry-configuring-storage-baremetal_installing-bare-metal","installation-registry-storage-non-production_installing-bare-metal","installation-registry-storage-block-recreate-rollout-bare-metal_installing-bare-metal","installation-complete-user-infra_installing-bare-metal","cluster-telemetry_installing-bare-metal","next-steps-25","installing-bare-metal-network-customizations","prerequisites-25","cluster-entitlements_installing-bare-metal-network-customizations","installation-requirements-user-infra_installing-bare-metal-network-customizations","machine-requirements_installing-bare-metal-network-customizations","minimum-resource-requirements_installing-bare-metal-network-customizations","csr-management_installing-bare-metal-network-customizations","installation-network-user-infra_installing-bare-metal-network-customizations","installation-host-names-dhcp-user-infra_installing-bare-metal-network-customizations","installation-network-connectivity-user-infra_installing-bare-metal-network-customizations","installation-dns-user-infra_installing-bare-metal-network-customizations","installation-dns-user-infra-example_installing-bare-metal-network-customizations","installation-load-balancing-user-infra_installing-bare-metal-network-customizations","installation-load-balancing-user-infra-example_installing-bare-metal-network-customizations","installation-infrastructure-user-infra_installing-bare-metal-network-customizations","installation-user-provisioned-validating-dns_installing-bare-metal-network-customizations","ssh-agent-using_installing-bare-metal-network-customizations","installation-obtaining-installer_installing-bare-metal-network-customizations","cli-installing-cli_installing-bare-metal-network-customizations","installation-initializing-manual_installing-bare-metal-network-customizations","installation-configuration-parameters_installing-bare-metal-network-customizations","installation-configuration-parameters-required_installing-bare-metal-network-customizations","installation-configuration-parameters-network_installing-bare-metal-network-customizations","installation-configuration-parameters-optional_installing-bare-metal-network-customizations","installation-bare-metal-config-yaml_installing-bare-metal-network-customizations","nw-network-config_installing-bare-metal-network-customizations","modifying-nwoperator-config-startup_installing-bare-metal-network-customizations","nw-operator-cr_installing-bare-metal-network-customizations","nw-operator-cr-cno-object_installing-bare-metal-network-customizations","installation-generate-ignition-configs_installing-bare-metal-network-customizations","creating-machines-bare-metal_installing-bare-metal-network-customizations","installation-user-infra-machines-iso_installing-bare-metal-network-customizations","installation-user-infra-machines-pxe_installing-bare-metal-network-customizations","installation-user-infra-machines-advanced_installing-bare-metal-network-customizations","installation-user-infra-machines-advanced_network_installing-bare-metal-network-customizations","installation-user-infra-machines-advanced_disk_installing-bare-metal-network-customizations","installation-user-infra-machines-advanced_vardisk_installing-bare-metal-network-customizations","installation-user-infra-machines-advanced_retaindisk_installing-bare-metal-network-customizations","installation-user-infra-machines-advanced_ignition_installing-bare-metal-network-customizations","installation-user-infra-machines-advanced_embed_ignition_installing-bare-metal-network-customizations","installation-user-infra-machines-static-network_installing-bare-metal-network-customizations","installation-user-infra-machines-routing-bonding_installing-bare-metal-network-customizations","installation-user-infra-machines-coreos-installer-options_installing-bare-metal-network-customizations","installation-user-infra-machines-coreos-inst-options_installing-bare-metal-network-customizations","rhcos-enabling-multipath_installing-bare-metal-network-customizations","architecture-rhcos-updating-bootloader.adoc_installing-bare-metal-network-customizations","installation-installing-bare-metal_installing-bare-metal-network-customizations","cli-logging-in-kubeadmin_installing-bare-metal-network-customizations","installation-approve-csrs_installing-bare-metal-network-customizations","installation-operators-config_installing-bare-metal-network-customizations","registry-removed_installing-bare-metal-network-customizations","installation-registry-storage-config_installing-bare-metal-network-customizations","installation-registry-storage-block-recreate-rollout-bare-metal_installing-bare-metal-network-customizations","installation-complete-user-infra_installing-bare-metal-network-customizations","cluster-telemetry_installing-bare-metal-network-customizations","next-steps-26","installing-restricted-networks-bare-metal","prerequisites-26","installation-about-restricted-networks_installing-restricted-networks-bare-metal","installation-restricted-network-limits_installing-restricted-networks-bare-metal","cluster-entitlements_installing-restricted-networks-bare-metal","installation-requirements-user-infra_installing-restricted-networks-bare-metal","machine-requirements_installing-restricted-networks-bare-metal","minimum-resource-requirements_installing-restricted-networks-bare-metal","csr-management_installing-restricted-networks-bare-metal","installation-network-user-infra_installing-restricted-networks-bare-metal","installation-host-names-dhcp-user-infra_installing-restricted-networks-bare-metal","installation-network-connectivity-user-infra_installing-restricted-networks-bare-metal","installation-dns-user-infra_installing-restricted-networks-bare-metal","installation-dns-user-infra-example_installing-restricted-networks-bare-metal","installation-load-balancing-user-infra_installing-restricted-networks-bare-metal","installation-load-balancing-user-infra-example_installing-restricted-networks-bare-metal","installation-infrastructure-user-infra_installing-restricted-networks-bare-metal","installation-user-provisioned-validating-dns_installing-restricted-networks-bare-metal","ssh-agent-using_installing-restricted-networks-bare-metal","installation-initializing-manual_installing-restricted-networks-bare-metal","installation-configuration-parameters_installing-restricted-networks-bare-metal","installation-configuration-parameters-required_installing-restricted-networks-bare-metal","installation-configuration-parameters-network_installing-restricted-networks-bare-metal","installation-configuration-parameters-optional_installing-restricted-networks-bare-metal","installation-bare-metal-config-yaml_installing-restricted-networks-bare-metal","installation-configure-proxy_installing-restricted-networks-bare-metal","installation-three-node-cluster_installing-restricted-networks-bare-metal","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-bare-metal","installation-special-config-chrony_installing-restricted-networks-bare-metal","creating-machines-bare-metal_installing-restricted-networks-bare-metal","installation-user-infra-machines-iso_installing-restricted-networks-bare-metal","installation-user-infra-machines-pxe_installing-restricted-networks-bare-metal","installation-user-infra-machines-advanced_installing-restricted-networks-bare-metal","installation-user-infra-machines-advanced_network_installing-restricted-networks-bare-metal","installation-user-infra-machines-advanced_disk_installing-restricted-networks-bare-metal","installation-user-infra-machines-advanced_vardisk_installing-restricted-networks-bare-metal","installation-user-infra-machines-advanced_retaindisk_installing-restricted-networks-bare-metal","installation-user-infra-machines-advanced_ignition_installing-restricted-networks-bare-metal","installation-user-infra-machines-advanced_embed_ignition_installing-restricted-networks-bare-metal","installation-user-infra-machines-static-network_installing-restricted-networks-bare-metal","installation-user-infra-machines-routing-bonding_installing-restricted-networks-bare-metal","installation-user-infra-machines-coreos-installer-options_installing-restricted-networks-bare-metal","installation-user-infra-machines-coreos-inst-options_installing-restricted-networks-bare-metal","rhcos-enabling-multipath_installing-restricted-networks-bare-metal","architecture-rhcos-updating-bootloader.adoc_installing-restricted-networks-bare-metal","installation-installing-bare-metal_installing-restricted-networks-bare-metal","cli-logging-in-kubeadmin_installing-restricted-networks-bare-metal","installation-approve-csrs_installing-restricted-networks-bare-metal","installation-operators-config_installing-restricted-networks-bare-metal","olm-restricted-networks-operatorhub_installing-restricted-networks-bare-metal","installation-registry-storage-config_installing-restricted-networks-bare-metal","registry-change-management-state_installing-restricted-networks-bare-metal","registry-configuring-storage-baremetal_installing-restricted-networks-bare-metal","installation-registry-storage-non-production_installing-restricted-networks-bare-metal","installation-registry-storage-block-recreate-rollout-bare-metal_installing-restricted-networks-bare-metal","installation-complete-user-infra_installing-restricted-networks-bare-metal","cluster-telemetry_installing-restricted-networks-bare-metal","next-steps-27","/documentation/openshift_container_platform/4.8/html/installing/installing-on-bare-metal",{"title":1983,"visible":17,"weight":876,"urlFragment":1984,"anchor":23,"singlePageAnchor":1984,"subChapters":1985,"url":2065,"docTitle":935},"Deploying installer-provisioned clusters on bare metal","deploying-installer-provisioned-clusters-on-bare-metal",[1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064],"ipi-install-overview","ipi-install-prerequisites","node-requirements_ipi-install-prerequisites","virt-planning-bare-metal-cluster-for-ocp-virt_ipi-install-prerequisites","ipi-install-firmware-requirements-for-installing-with-virtual-media_ipi-install-prerequisites","network-requirements_ipi-install-prerequisites","network-requirements-increase-mtu_ipi-install-prerequisites","network-requirements-config-nics_ipi-install-prerequisites","network-requirements-dns_ipi-install-prerequisites","network-requirements-dhcp-reqs_ipi-install-prerequisites","network-requirements-reserving-ip-addresses_ipi-install-prerequisites","network-requirements-ntp_ipi-install-prerequisites","network-requirements-state-config_ipi-install-prerequisites","network-requirements-out-of-band_ipi-install-prerequisites","configuring-nodes_ipi-install-prerequisites","out-of-band-management_ipi-install-prerequisites","required-data-for-installation_ipi-install-prerequisites","validation-checklist-for-nodes_ipi-install-prerequisites","ipi-install-installation-workflow","installing-rhel-on-the-provisioner-node_ipi-install-installation-workflow","preparing-the-provisioner-node-for-openshift-install_ipi-install-installation-workflow","retrieving-the-openshift-installer_ipi-install-installation-workflow","extracting-the-openshift-installer_ipi-install-installation-workflow","ipi-install-creating-an-rhcos-images-cache_ipi-install-installation-workflow","ipi-install-configuration-files","configuring-the-install-config-file_ipi-install-installation-workflow","ipi-install-setting-proxy-settings-within-install-config_ipi-install-installation-workflow","modifying-install-config-for-no-provisioning-network_ipi-install-installation-workflow","modifying-install-config-for-dual-stack-network_ipi-install-installation-workflow","configuring-managed-secure-boot-in-the-install-config-file_ipi-install-installation-workflow","additional-install-config-parameters_ipi-install-installation-workflow","bmc-addressing_ipi-install-installation-workflow","bmc-addressing-for-dell-idrac_ipi-install-installation-workflow","bmc-addressing-for-hpe-ilo_ipi-install-installation-workflow","bmc-addressing-for-fujitsu-irmc_ipi-install-installation-workflow","root-device-hints_ipi-install-installation-workflow","creating-the-openshift-manifests_ipi-install-installation-workflow","configuring-ntp-for-disconnected-clusters_ipi-install-installation-workflow","configure-network-components-to-run-on-the-control-plane_ipi-install-installation-workflow","ipi-install-creating-a-disconnected-registry_ipi-install-installation-workflow","preparing-the-registry-node-to-host-the-mirrored-registry-optional","generating-the-self-signed-certificate-optional","creating-the-registry-podman-container-optional","copy-and-update-the-pull-secret-optional","mirroring-the-repository-optional","modify-the-literal-install-config-yaml-literal-file-to-use-the-disconnected-registry-optional","deploying-routers-on-worker-nodes_ipi-install-installation-workflow","validation-checklist-for-installation_ipi-install-installation-workflow","deploying-the-cluster-via-the-openshift-installer_ipi-install-installation-workflow","ipi-install-troubleshooting-following-the-installation_ipi-install-installation-workflow","verifying-static-ip-address-configuration_ipi-install-installation-workflow","ipi-preparing-reinstall-cluster-bare-metal_ipi-install-installation-workflow","ipi-install-post-installation-configuration","configuring-ntp-for-disconnected-clusters_ipi-install-post-installation-configuration","enabling-a-provisioning-network-after-installation_ipi-install-post-installation-configuration","nw-osp-configuring-external-load-balancer_ipi-install-post-installation-configuration","ipi-install-expanding-the-cluster","preparing-the-bare-metal-node_ipi-install-expanding","replacing-a-bare-metal-control-plane-node_ipi-install-expanding","ipi-install-diagnosing-duplicate-mac-address_ipi-install-expanding","provisioning-the-bare-metal-node_ipi-install-expanding","ipi-install-troubleshooting","troubleshooting-the-installer-workflow","ipi-install-troubleshooting-install-config_ipi-install-troubleshooting","ipi-install-troubleshooting-bootstrap-vm_ipi-install-troubleshooting","ipi-install-troubleshooting-bootstrap-vm-cannot-boot_ipi-install-troubleshooting","ipi-install-troubleshooting-bootstrap-vm-inspecting-logs_ipi-install-troubleshooting","ipi-install-troubleshooting-cluster-nodes-will-not-pxe_ipi-install-troubleshooting","ipi-install-troubleshooting-api-not-accessible_ipi-install-troubleshooting","ipi-install-troubleshooting-cleaning-up-previous-installations_ipi-install-troubleshooting","ipi-install-troubleshooting-registry-issues_ipi-install-troubleshooting","ipi-install-troubleshooting-misc-issues_ipi-install-troubleshooting","addressing-the-literal-runtime-network-not-ready-literal-error","cluster-nodes-not-getting-the-correct-ipv6-address-over-dhcp","cluster-nodes-not-getting-the-correct-hostname-over-dhcp","routes-do-not-reach-endpoints","ipi-install-troubleshooting-failed-ignition-during-firstboot_ipi-install-troubleshooting","ipi-install-troubleshooting-ntp-out-of-sync_ipi-install-troubleshooting","ipi-install-troubleshooting-reviewing-the-installation_ipi-install-troubleshooting","/documentation/openshift_container_platform/4.8/html/installing/deploying-installer-provisioned-clusters-on-bare-metal",{"title":2067,"visible":17,"weight":884,"urlFragment":2068,"anchor":23,"singlePageAnchor":2068,"subChapters":2069,"url":2165,"docTitle":935},"Installing with z/VM on IBM Z and LinuxONE","installing-with-z-vm-on-ibm-z-and-linuxone",[2070,2071,2072,2073,2074,2075,2076,2077,2078,2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164],"preparing-to-install-on-ibm-z","preparing-to-install-on-ibm-z-prerequisites","choosing-an-method-to-install-ocp-on-ibm-z","installing-ibm-z","prerequisites-27","cluster-entitlements_installing-ibm-z","installation-requirements-user-infra_installing-ibm-z","machine-requirements_installing-ibm-z","minimum-resource-requirements_installing-ibm-z","minimum-ibm-z-system-requirements_installing-ibm-z","preferred-ibm-z-system-requirements_installing-ibm-z","csr-management_installing-ibm-z","installation-network-user-infra_installing-ibm-z","installation-network-connectivity-user-infra_installing-ibm-z","installation-dns-user-infra_installing-ibm-z","installation-dns-user-infra-example_installing-ibm-z","installation-load-balancing-user-infra_installing-ibm-z","installation-load-balancing-user-infra-example_installing-ibm-z","installation-infrastructure-user-infra_installing-ibm-z","installation-user-provisioned-validating-dns_installing-ibm-z","ssh-agent-using_installing-ibm-z","installation-obtaining-installer_installing-ibm-z","cli-installing-cli_installing-ibm-z","installation-initializing-manual_installing-ibm-z","installation-configuration-parameters_installing-ibm-z","installation-configuration-parameters-required_installing-ibm-z","installation-configuration-parameters-network_installing-ibm-z","installation-configuration-parameters-optional_installing-ibm-z","installation-bare-metal-config-yaml_installing-ibm-z","installation-configure-proxy_installing-ibm-z","installation-three-node-cluster_installing-ibm-z","nw-operator-cr_installing-ibm-z","nw-operator-cr-cno-object_installing-ibm-z","installation-user-infra-generate-k8s-manifest-ignition_installing-ibm-z","installation-user-infra-machines-iso-ibm-z_installing-ibm-z","installation-user-infra-machines-static-network_installing-ibm-z","installation-user-infra-machines-routing-bonding_installing-ibm-z","installation-installing-bare-metal_installing-ibm-z","cli-logging-in-kubeadmin_installing-ibm-z","installation-approve-csrs_installing-ibm-z","installation-operators-config_installing-ibm-z","installation-registry-storage-config_installing-ibm-z","registry-configuring-storage-baremetal_installing-ibm-z","installation-registry-storage-non-production_installing-ibm-z","installation-complete-user-infra_installing-ibm-z","cluster-telemetry_installing-ibm-z","installation-ibm-z-troubleshooting-and-debugging_installing-ibm-z","next-steps-28","installing-restricted-networks-ibm-z","prerequisites-28","installation-about-restricted-networks_installing-restricted-networks-ibm-z","installation-restricted-network-limits_installing-restricted-networks-ibm-z","cluster-entitlements_installing-restricted-networks-ibm-z","installation-requirements-user-infra_installing-restricted-networks-ibm-z","machine-requirements_installing-restricted-networks-ibm-z","minimum-resource-requirements_installing-restricted-networks-ibm-z","minimum-ibm-z-system-requirements_installing-restricted-networks-ibm-z","preferred-ibm-z-system-requirements_installing-restricted-networks-ibm-z","csr-management_installing-restricted-networks-ibm-z","installation-network-user-infra_installing-restricted-networks-ibm-z","installation-host-names-dhcp-user-infra_installing-restricted-networks-ibm-z","installation-network-connectivity-user-infra_installing-restricted-networks-ibm-z","installation-dns-user-infra_installing-restricted-networks-ibm-z","installation-dns-user-infra-example_installing-restricted-networks-ibm-z","installation-load-balancing-user-infra_installing-restricted-networks-ibm-z","installation-load-balancing-user-infra-example_installing-restricted-networks-ibm-z","installation-infrastructure-user-infra_installing-restricted-networks-ibm-z","installation-user-provisioned-validating-dns_installing-restricted-networks-ibm-z","ssh-agent-using_installing-restricted-networks-ibm-z","installation-initializing-manual_installing-restricted-networks-ibm-z","installation-configuration-parameters_installing-restricted-networks-ibm-z","installation-configuration-parameters-required_installing-restricted-networks-ibm-z","installation-configuration-parameters-network_installing-restricted-networks-ibm-z","installation-configuration-parameters-optional_installing-restricted-networks-ibm-z","installation-bare-metal-config-yaml_installing-restricted-networks-ibm-z","installation-configure-proxy_installing-restricted-networks-ibm-z","installation-three-node-cluster_installing-restricted-networks-ibm-z","nw-operator-cr_installing-restricted-networks-ibm-z","nw-operator-cr-cno-object_installing-restricted-networks-ibm-z","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-ibm-z","installation-user-infra-machines-iso-ibm-z_installing-restricted-networks-ibm-z","installation-user-infra-machines-static-network_installing-restricted-networks-ibm-z","installation-user-infra-machines-routing-bonding_installing-restricted-networks-ibm-z","installation-installing-bare-metal_installing-restricted-networks-ibm-z","cli-logging-in-kubeadmin_installing-restricted-networks-ibm-z","installation-approve-csrs_installing-restricted-networks-ibm-z","installation-operators-config_installing-restricted-networks-ibm-z","olm-restricted-networks-operatorhub_installing-restricted-networks-ibm-z","installation-registry-storage-config_installing-restricted-networks-ibm-z","registry-configuring-storage-baremetal_installing-restricted-networks-ibm-z","installation-registry-storage-non-production_installing-restricted-networks-ibm-z","installation-complete-user-infra_installing-restricted-networks-ibm-z","cluster-telemetry_installing-restricted-networks-ibm-z","installation-ibm-z-troubleshooting-and-debugging_installing-restricted-networks-ibm-z","next-steps-29","/documentation/openshift_container_platform/4.8/html/installing/installing-with-z-vm-on-ibm-z-and-linuxone",{"title":2167,"visible":17,"weight":895,"urlFragment":2168,"anchor":23,"singlePageAnchor":2168,"subChapters":2169,"url":2273,"docTitle":935},"Installing with RHEL KVM on IBM Z and LinuxONE","installing-with-rhel-kvm-on-ibm-z-and-linuxone",[2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272],"preparing-to-install-on-ibm-z-kvm","preparing-to-install-on-ibm-z-kvm-prerequisites","choosing-an-method-to-install-ocp-on-ibm-z-kvm","installing-ibm-z-kvm","prerequisites-29","cluster-entitlements_installing-ibm-z-kvm","installation-requirements-user-infra_installing-ibm-z-kvm","machine-requirements_installing-ibm-z-kvm","network-connectivity_installing-ibm-z-kvm","ibm-z-network-connectivity_installing-ibm-z-kvm","host-machine-resource-requirements_installing-ibm-z-kvm","minimum-ibm-z-system-requirements_installing-ibm-z-kvm","minimum-resource-requirements_installing-ibm-z-kvm","preferred-ibm-z-system-requirements_installing-ibm-z-kvm","preferred-resource-requirements_installing-ibm-z-kvm","csr-management_installing-ibm-z-kvm","installation-network-user-infra_installing-ibm-z-kvm","installation-host-names-dhcp-user-infra_installing-ibm-z-kvm","installation-network-connectivity-user-infra_installing-ibm-z-kvm","installation-dns-user-infra_installing-ibm-z-kvm","installation-dns-user-infra-example_installing-ibm-z-kvm","installation-load-balancing-user-infra_installing-ibm-z-kvm","installation-load-balancing-user-infra-example_installing-ibm-z-kvm","installation-infrastructure-user-infra_installing-ibm-z-kvm","installation-user-provisioned-validating-dns_installing-ibm-z-kvm","ssh-agent-using_installing-ibm-z-kvm","installation-obtaining-installer_installing-ibm-z-kvm","cli-installing-cli_installing-ibm-z-kvm","installation-initializing-manual_installing-ibm-z-kvm","installation-configuration-parameters_installing-ibm-z-kvm","installation-configuration-parameters-required_installing-ibm-z-kvm","installation-configuration-parameters-network_installing-ibm-z-kvm","installation-configuration-parameters-optional_installing-ibm-z-kvm","installation-bare-metal-config-yaml_installing-ibm-z-kvm","installation-configure-proxy_installing-ibm-z-kvm","installation-three-node-cluster_installing-ibm-z-kvm","nw-operator-cr_installing-ibm-z-kvm","nw-operator-cr-cno-object_installing-ibm-z-kvm","installation-user-infra-generate-k8s-manifest-ignition_installing-ibm-z-kvm","installation-ibm-z-kvm-user-infra-installing-rhcos_installing-ibm-z-kvm","installation-user-infra-machines-iso-ibm-z_kvm_installing-ibm-z-kvm","installation-user-infra-machines-iso-ibm-z-kvm-full_installing-ibm-z-kvm","installation-installing-bare-metal_installing-ibm-z-kvm","cli-logging-in-kubeadmin_installing-ibm-z-kvm","installation-approve-csrs_installing-ibm-z-kvm","installation-operators-config_installing-ibm-z-kvm","installation-registry-storage-config_installing-ibm-z-kvm","registry-configuring-storage-baremetal_installing-ibm-z-kvm","installation-registry-storage-non-production_installing-ibm-z-kvm","installation-complete-user-infra_installing-ibm-z-kvm","cluster-telemetry_installing-ibm-z-kvm","installation-ibm-z-troubleshooting-and-debugging_installing-ibm-z-kvm","next-steps_ibmz-kvm","installing-restricted-networks-ibm-z-kvm","prerequisites-30","installation-about-restricted-networks_installing-restricted-networks-ibm-z-kvm","installation-restricted-network-limits_installing-restricted-networks-ibm-z-kvm","cluster-entitlements_installing-restricted-networks-ibm-z-kvm","installation-requirements-user-infra_installing-restricted-networks-ibm-z-kvm","machine-requirements_installing-restricted-networks-ibm-z-kvm","network-connectivity_installing-restricted-networks-ibm-z-kvm","ibm-z-network-connectivity_installing-restricted-networks-ibm-z-kvm","host-machine-resource-requirements_installing-restricted-networks-ibm-z-kvm","minimum-ibm-z-system-requirements_installing-restricted-networks-ibm-z-kvm","minimum-resource-requirements_installing-restricted-networks-ibm-z-kvm","preferred-ibm-z-system-requirements_installing-restricted-networks-ibm-z-kvm","preferred-resource-requirements_installing-restricted-networks-ibm-z-kvm","csr-management_installing-restricted-networks-ibm-z-kvm","installation-network-user-infra_installing-restricted-networks-ibm-z-kvm","installation-network-connectivity-user-infra_installing-restricted-networks-ibm-z-kvm","installation-dns-user-infra_installing-restricted-networks-ibm-z-kvm","installation-dns-user-infra-example_installing-restricted-networks-ibm-z-kvm","installation-load-balancing-user-infra_installing-restricted-networks-ibm-z-kvm","installation-load-balancing-user-infra-example_installing-restricted-networks-ibm-z-kvm","installation-infrastructure-user-infra_installing-restricted-networks-ibm-z-kvm","installation-user-provisioned-validating-dns_installing-restricted-networks-ibm-z-kvm","ssh-agent-using_installing-restricted-networks-ibm-z-kvm","installation-initializing-manual_installing-restricted-networks-ibm-z-kvm","installation-configuration-parameters_installing-restricted-networks-ibm-z-kvm","installation-configuration-parameters-required_installing-restricted-networks-ibm-z-kvm","installation-configuration-parameters-network_installing-restricted-networks-ibm-z-kvm","installation-configuration-parameters-optional_installing-restricted-networks-ibm-z-kvm","installation-bare-metal-config-yaml_installing-restricted-networks-ibm-z-kvm","installation-configure-proxy_installing-restricted-networks-ibm-z-kvm","installation-three-node-cluster_installing-restricted-networks-ibm-z-kvm","nw-operator-cr_installing-restricted-networks-ibm-z-kvm","nw-operator-cr-cno-object_installing-restricted-networks-ibm-z-kvm","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-ibm-z-kvm","installation-ibm-z-kvm-user-infra-installing-rhcos_installing-restricted-networks-ibm-z-kvm","installation-user-infra-machines-iso-ibm-z_kvm_installing-restricted-networks-ibm-z-kvm","installation-user-infra-machines-iso-ibm-z-kvm-full_installing-restricted-networks-ibm-z-kvm","installation-installing-bare-metal_installing-restricted-networks-ibm-z-kvm","cli-logging-in-kubeadmin_installing-restricted-networks-ibm-z-kvm","installation-approve-csrs_installing-restricted-networks-ibm-z-kvm","installation-operators-config_installing-restricted-networks-ibm-z-kvm","olm-restricted-networks-operatorhub_installing-restricted-networks-ibm-z-kvm","installation-registry-storage-config_installing-restricted-networks-ibm-z-kvm","registry-configuring-storage-baremetal_installing-restricted-networks-ibm-z-kvm","installation-registry-storage-non-production_installing-restricted-networks-ibm-z-kvm","installation-complete-user-infra_installing-restricted-networks-ibm-z-kvm","cluster-telemetry_installing-restricted-networks-ibm-z-kvm","installation-ibm-z-troubleshooting-and-debugging_installing-restricted-networks-ibm-z-kvm","next-steps_ibmz-kvm-restricted","/documentation/openshift_container_platform/4.8/html/installing/installing-with-rhel-kvm-on-ibm-z-and-linuxone",{"title":2275,"visible":17,"weight":906,"urlFragment":2276,"anchor":23,"singlePageAnchor":2276,"subChapters":2277,"url":2379,"docTitle":935},"Installing on IBM Power Systems","installing-on-ibm-power-systems",[2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,2304,2305,2306,2307,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363,2364,2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378],"preparing-to-install-on-ibm-power","preparing-to-install-on-ibm-power-prerequisites","choosing-an-method-to-install-ocp-on-ibm-power","installing-ibm-power","prerequisites-31","cluster-entitlements_installing-ibm-power","installation-requirements-user-infra_installing-ibm-power","machine-requirements_installing-ibm-power","minimum-resource-requirements_installing-ibm-power","minimum-ibm-power-system-requirements_installing-ibm-power","recommended-ibm-power-system-requirements_installing-ibm-power","csr-management_installing-ibm-power","installation-network-user-infra_installing-ibm-power","installation-network-connectivity-user-infra_installing-ibm-power","installation-dns-user-infra_installing-ibm-power","installation-dns-user-infra-example_installing-ibm-power","installation-load-balancing-user-infra_installing-ibm-power","installation-load-balancing-user-infra-example_installing-ibm-power","installation-infrastructure-user-infra_installing-ibm-power","installation-user-provisioned-validating-dns_installing-ibm-power","ssh-agent-using_installing-ibm-power","installation-obtaining-installer_installing-ibm-power","cli-installing-cli_installing-ibm-power","installation-initializing-manual_installing-ibm-power","installation-configuration-parameters_installing-ibm-power","installation-configuration-parameters-required_installing-ibm-power","installation-configuration-parameters-network_installing-ibm-power","installation-configuration-parameters-optional_installing-ibm-power","installation-bare-metal-config-yaml_installing-ibm-power","sample-install-config-yaml-file-for-ibm-power-systems","installation-configure-proxy_installing-ibm-power","installation-three-node-cluster_installing-ibm-power","nw-operator-cr_installing-ibm-power","nw-operator-cr-cno-object_installing-ibm-power","installation-user-infra-generate-k8s-manifest-ignition_installing-ibm-power","creating-machines-bare-metal-power","installation-user-infra-machines-iso_installing-ibm-power","installation-user-infra-machines-static-network_installing-ibm-power","installation-user-infra-machines-routing-bonding_installing-ibm-power","installation-user-infra-machines-pxe_installing-ibm-power","installation-installing-bare-metal_installing-ibm-power","cli-logging-in-kubeadmin_installing-ibm-power","installation-approve-csrs_installing-ibm-power","installation-operators-config_installing-ibm-power","installation-registry-storage-config_installing-ibm-power","registry-configuring-storage-baremetal_installing-ibm-power","configuring-registry-storage-for-ibm-power-systems","installation-registry-storage-non-production_installing-ibm-power","installation-complete-user-infra_installing-ibm-power","cluster-telemetry_installing-ibm-power","next-steps-30","installing-restricted-networks-ibm-power","prerequisites-32","installation-about-restricted-networks_installing-restricted-networks-ibm-power","installation-restricted-network-limits_installing-restricted-networks-ibm-power","cluster-entitlements_installing-restricted-networks-ibm-power","installation-requirements-user-infra_installing-restricted-networks-ibm-power","machine-requirements_installing-restricted-networks-ibm-power","minimum-resource-requirements_installing-restricted-networks-ibm-power","minimum-ibm-power-system-requirements_installing-restricted-networks-ibm-power","recommended-ibm-power-system-requirements_installing-restricted-networks-ibm-power","csr-management_installing-restricted-networks-ibm-power","installation-network-user-infra_installing-restricted-networks-ibm-power","installation-network-connectivity-user-infra_installing-restricted-networks-ibm-power","installation-dns-user-infra_installing-restricted-networks-ibm-power","installation-dns-user-infra-example_installing-restricted-networks-ibm-power","installation-load-balancing-user-infra_installing-restricted-networks-ibm-power","installation-load-balancing-user-infra-example_installing-restricted-networks-ibm-power","installation-infrastructure-user-infra_installing-restricted-networks-ibm-power","installation-user-provisioned-validating-dns_installing-restricted-networks-ibm-power","ssh-agent-using_installing-restricted-networks-ibm-power","installation-initializing-manual_installing-restricted-networks-ibm-power","installation-configuration-parameters_installing-restricted-networks-ibm-power","installation-configuration-parameters-required_installing-restricted-networks-ibm-power","installation-configuration-parameters-network_installing-restricted-networks-ibm-power","installation-configuration-parameters-optional_installing-restricted-networks-ibm-power","installation-bare-metal-config-yaml_installing-restricted-networks-ibm-power","sample-install-config-yaml-file-for-ibm-power-systems-2","installation-configure-proxy_installing-restricted-networks-ibm-power","installation-three-node-cluster_installing-restricted-networks-ibm-power","nw-operator-cr_installing-restricted-networks-ibm-power","nw-operator-cr-cno-object_installing-restricted-networks-ibm-power","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-ibm-power","creating-machines-ibm-power-restricted-network","installation-user-infra-machines-iso_installing-restricted-networks-ibm-power","installation-user-infra-machines-static-network_installing-restricted-networks-ibm-power","installation-user-infra-machines-routing-bonding_installing-restricted-networks-ibm-power","installation-user-infra-machines-pxe_installing-restricted-networks-ibm-power","installation-installing-bare-metal_installing-restricted-networks-ibm-power","cli-logging-in-kubeadmin_installing-restricted-networks-ibm-power","installation-approve-csrs_installing-restricted-networks-ibm-power","installation-operators-config_installing-restricted-networks-ibm-power","olm-restricted-networks-operatorhub_installing-restricted-networks-ibm-power","installation-registry-storage-config_installing-restricted-networks-ibm-power","registry-change-management-state_installing-restricted-networks-ibm-power","registry-configuring-storage-baremetal_installing-restricted-networks-ibm-power","configuring-registry-storage-for-ibm-power-systems-2","installation-registry-storage-non-production_installing-restricted-networks-ibm-power","installation-complete-user-infra_installing-restricted-networks-ibm-power","cluster-telemetry_installing-restricted-networks-ibm-power","next-steps-31","/documentation/openshift_container_platform/4.8/html/installing/installing-on-ibm-power-systems",{"title":2381,"visible":17,"weight":913,"urlFragment":2382,"anchor":23,"singlePageAnchor":2382,"subChapters":2383,"url":2682,"docTitle":935},"Installing on OpenStack","installing-on-openstack",[2384,2385,2386,2387,2388,2389,2390,2391,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2496,2497,2498,2499,2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,2511,2512,2513,2514,2515,2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,2574,2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2601,2602,2603,2604,2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618,2619,2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633,2634,2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678,2679,2680,2681],"preparing-to-install-on-openstack","preparing-to-install-on-openstack-prerequisites","choosing-an-method-to-install-ocp-on-openstack","choosing-an-method-to-install-ocp-on-openstack-installer-provisioned","choosing-an-method-to-install-ocp-on-openstack-user-provisioned","installing-openstack-installer-custom","prerequisites-33","installation-osp-default-deployment_installing-openstack-installer-custom","installation-osp-control-machines_installing-openstack-installer-custom","installation-osp-compute-machines_installing-openstack-installer-custom","installation-osp-bootstrap-machine_installing-openstack-installer-custom","cluster-entitlements_installing-openstack-installer-custom","installation-osp-enabling-swift_installing-openstack-installer-custom","installation-registry-osp-creating-custom-pvc_installing-openstack-installer-custom","installation-osp-verifying-external-network_installing-openstack-installer-custom","installation-osp-describing-cloud-parameters_installing-openstack-installer-custom","installation-obtaining-installer_installing-openstack-installer-custom","installation-initializing_installing-openstack-installer-custom","installation-configure-proxy_installing-openstack-installer-custom","installation-configuration-parameters_installing-openstack-installer-custom","installation-configuration-parameters-required_installing-openstack-installer-custom","installation-configuration-parameters-network_installing-openstack-installer-custom","installation-configuration-parameters-optional_installing-openstack-installer-custom","installation-configuration-parameters-additional-osp_installing-openstack-installer-custom","installation-configuration-parameters-optional-osp_installing-openstack-installer-custom","installation-osp-custom-subnet_installing-openstack-installer-custom","installation-osp-deploying-bare-metal-machines_installing-openstack-installer-custom","installation-osp-provider-networks_installing-openstack-installer-custom","installation-osp-provider-network-preparation_installing-openstack-installer-custom","installation-osp-deploying-provider-networks-installer_installing-openstack-installer-custom","installation-osp-config-yaml_installing-openstack-installer-custom","installation-osp-setting-worker-affinity_installing-openstack-installer-custom","ssh-agent-using_installing-openstack-installer-custom","installation-osp-accessing-api_installing-openstack-installer-custom","installation-osp-accessing-api-floating_installing-openstack-installer-custom","installation-osp-accessing-api-no-floating_installing-openstack-installer-custom","installation-launching-installer_installing-openstack-installer-custom","installation-osp-verifying-cluster-status_installing-openstack-installer-custom","cli-logging-in-kubeadmin_installing-openstack-installer-custom","cluster-telemetry_installing-openstack-installer-custom","next-steps-32","installing-openstack-installer-kuryr","prerequisites-34","installation-osp-about-kuryr_installing-openstack-installer-kuryr","installation-osp-default-kuryr-deployment_installing-openstack-installer-kuryr","installation-osp-kuryr-increase-quota_installing-openstack-installer-kuryr","installation-osp-kuryr-neutron-configuration_installing-openstack-installer-kuryr","installation-osp-kuryr-octavia-configuration_installing-openstack-installer-kuryr","installation-osp-kuryr-octavia-driver_installing-openstack-installer-kuryr","installation-osp-kuryr-known-limitations_installing-openstack-installer-kuryr","installation-osp-control-machines_installing-openstack-installer-kuryr","installation-osp-compute-machines_installing-openstack-installer-kuryr","installation-osp-bootstrap-machine_installing-openstack-installer-kuryr","cluster-entitlements_installing-openstack-installer-kuryr","installation-osp-enabling-swift_installing-openstack-installer-kuryr","installation-osp-verifying-external-network_installing-openstack-installer-kuryr","installation-osp-describing-cloud-parameters_installing-openstack-installer-kuryr","installation-obtaining-installer_installing-openstack-installer-kuryr","installation-initializing_installing-openstack-installer-kuryr","installation-configure-proxy_installing-openstack-installer-kuryr","installation-configuration-parameters_installing-openstack-installer-kuryr","installation-configuration-parameters-required_installing-openstack-installer-kuryr","installation-configuration-parameters-network_installing-openstack-installer-kuryr","installation-configuration-parameters-optional_installing-openstack-installer-kuryr","installation-configuration-parameters-additional-osp_installing-openstack-installer-kuryr","installation-configuration-parameters-optional-osp_installing-openstack-installer-kuryr","installation-osp-custom-subnet_installing-openstack-installer-kuryr","installation-osp-kuryr-config-yaml_installing-openstack-installer-kuryr","installation-osp-provider-networks_installing-openstack-installer-kuryr","installation-osp-provider-network-preparation_installing-openstack-installer-kuryr","installation-osp-deploying-provider-networks-installer_installing-openstack-installer-kuryr","installation-osp-kuryr-port-pools_installing-openstack-installer-kuryr","installation-osp-kuryr-settings-installing_installing-openstack-installer-kuryr","installation-osp-setting-worker-affinity_installing-openstack-installer-kuryr","ssh-agent-using_installing-openstack-installer-kuryr","installation-osp-accessing-api_installing-openstack-installer-kuryr","installation-osp-accessing-api-floating_installing-openstack-installer-kuryr","installation-osp-accessing-api-no-floating_installing-openstack-installer-kuryr","installation-launching-installer_installing-openstack-installer-kuryr","installation-osp-verifying-cluster-status_installing-openstack-installer-kuryr","cli-logging-in-kubeadmin_installing-openstack-installer-kuryr","cluster-telemetry_installing-openstack-installer-kuryr","next-steps-33","installing-openstack-installer-sr-iov","prerequisites-35","installation-osp-default-deployment_installing-openstack-installer-sr-iov","installation-osp-control-machines_installing-openstack-installer-sr-iov","installation-osp-compute-machines_installing-openstack-installer-sr-iov","installation-osp-bootstrap-machine_installing-openstack-installer-sr-iov","cluster-entitlements_installing-openstack-installer-sr-iov","installation-osp-enabling-swift_installing-openstack-installer-sr-iov","installation-osp-verifying-external-network_installing-openstack-installer-sr-iov","installation-osp-describing-cloud-parameters_installing-openstack-installer-sr-iov","installation-obtaining-installer_installing-openstack-installer-sr-iov","installation-initializing_installing-openstack-installer-sr-iov","installation-configure-proxy_installing-openstack-installer-sr-iov","installation-configuration-parameters_installing-openstack-installer-sr-iov","installation-configuration-parameters-required_installing-openstack-installer-sr-iov","installation-configuration-parameters-network_installing-openstack-installer-sr-iov","installation-configuration-parameters-optional_installing-openstack-installer-sr-iov","installation-osp-custom-subnet_installing-openstack-installer-sr-iov","installation-osp-deploying-bare-metal-machines_installing-openstack-installer-sr-iov","installation-osp-config-yaml_installing-openstack-installer-sr-iov","ssh-agent-using_installing-openstack-installer-sr-iov","installation-osp-accessing-api_installing-openstack-installer-sr-iov","installation-osp-accessing-api-floating_installing-openstack-installer-sr-iov","installation-osp-accessing-api-no-floating_installing-openstack-installer-sr-iov","installation-osp-configuring-sr-iov_installing-openstack-installer-sr-iov","installation-launching-installer_installing-openstack-installer-sr-iov","installation-osp-verifying-cluster-status_installing-openstack-installer-sr-iov","cli-logging-in-kubeadmin_installing-openstack-installer-sr-iov","networking-osp-preparing-for-sr-iov_installing-openstack-installer-sr-iov","networking-osp-enabling-metadata_installing-openstack-installer-sr-iov","networking-osp-enabling-vfio-noiommu_installing-openstack-installer-sr-iov","cluster-telemetry_installing-openstack-installer-sr-iov","next-steps-34","installing-openstack-user","prerequisites-36","cluster-entitlements_installing-openstack-user","installation-osp-default-deployment_installing-openstack-user","installation-osp-control-machines_installing-openstack-user","installation-osp-compute-machines_installing-openstack-user","installation-osp-bootstrap-machine_installing-openstack-user","installation-osp-downloading-modules_installing-openstack-user","installation-osp-downloading-playbooks_installing-openstack-user","installation-obtaining-installer_installing-openstack-user","ssh-agent-using_installing-openstack-user","installation-osp-creating-image_installing-openstack-user","installation-osp-verifying-external-network_installing-openstack-user","installation-osp-accessing-api_installing-openstack-user","installation-osp-accessing-api-floating_installing-openstack-user","installation-osp-accessing-api-no-floating_installing-openstack-user","installation-osp-describing-cloud-parameters_installing-openstack-user","installation-initializing_installing-openstack-user","installation-configuration-parameters_installing-openstack-user","installation-configuration-parameters-required_installing-openstack-user","installation-configuration-parameters-network_installing-openstack-user","installation-configuration-parameters-optional_installing-openstack-user","installation-configuration-parameters-additional-osp_installing-openstack-user","installation-configuration-parameters-optional-osp_installing-openstack-user","installation-osp-custom-subnet_installing-openstack-user","installation-osp-config-yaml_installing-openstack-user","installation-osp-fixing-subnet_installing-openstack-user","installation-osp-emptying-worker-pools_installing-openstack-user","installation-osp-provider-networks_installing-openstack-user","installation-osp-provider-network-preparation_installing-openstack-user","installation-osp-deploying-provider-networks-installer_installing-openstack-user","installation-user-infra-generate-k8s-manifest-ignition_installing-openstack-user","installation-osp-converting-ignition-resources_installing-openstack-user","installation-osp-creating-control-plane-ignition_installing-openstack-user","installation-osp-creating-network-resources_installing-openstack-user","installation-osp-deploying-bare-metal-machines_installing-openstack-user","installation-osp-creating-bootstrap-machine_installing-openstack-user","installation-osp-creating-control-plane_installing-openstack-user","cli-logging-in-kubeadmin_installing-openstack-user","installation-osp-deleting-bootstrap-resources_installing-openstack-user","installation-osp-creating-compute-machines_installing-openstack-user","installation-approve-csrs_installing-openstack-user","installation-osp-verifying-installation_installing-openstack-user","cluster-telemetry_installing-openstack-user","next-steps-35","installing-openstack-user-kuryr","prerequisites-37","installation-osp-about-kuryr_installing-openstack-user-kuryr","installation-osp-default-kuryr-deployment_installing-openstack-user-kuryr","installation-osp-kuryr-increase-quota_installing-openstack-user-kuryr","installation-osp-kuryr-neutron-configuration_installing-openstack-user-kuryr","installation-osp-kuryr-octavia-configuration_installing-openstack-user-kuryr","installation-osp-kuryr-octavia-driver_installing-openstack-user-kuryr","installation-osp-kuryr-known-limitations_installing-openstack-user-kuryr","installation-osp-control-machines_installing-openstack-user-kuryr","installation-osp-compute-machines_installing-openstack-user-kuryr","installation-osp-bootstrap-machine_installing-openstack-user-kuryr","cluster-entitlements_installing-openstack-user-kuryr","installation-osp-downloading-modules_installing-openstack-user-kuryr","installation-osp-downloading-playbooks_installing-openstack-user-kuryr","installation-obtaining-installer_installing-openstack-user-kuryr","ssh-agent-using_installing-openstack-user-kuryr","installation-osp-creating-image_installing-openstack-user-kuryr","installation-osp-verifying-external-network_installing-openstack-user-kuryr","installation-osp-accessing-api_installing-openstack-user-kuryr","installation-osp-accessing-api-floating_installing-openstack-user-kuryr","installation-osp-accessing-api-no-floating_installing-openstack-user-kuryr","installation-osp-describing-cloud-parameters_installing-openstack-user-kuryr","installation-initializing_installing-openstack-user-kuryr","installation-configuration-parameters_installing-openstack-user-kuryr","installation-configuration-parameters-required_installing-openstack-user-kuryr","installation-configuration-parameters-network_installing-openstack-user-kuryr","installation-configuration-parameters-optional_installing-openstack-user-kuryr","installation-configuration-parameters-additional-osp_installing-openstack-user-kuryr","installation-configuration-parameters-optional-osp_installing-openstack-user-kuryr","installation-osp-custom-subnet_installing-openstack-user-kuryr","installation-osp-kuryr-config-yaml_installing-openstack-user-kuryr","installation-osp-provider-networks_installing-openstack-user-kuryr","installation-osp-provider-network-preparation_installing-openstack-user-kuryr","installation-osp-deploying-provider-networks-installer_installing-openstack-user-kuryr","installation-osp-kuryr-port-pools_installing-openstack-user-kuryr","installation-osp-kuryr-settings-installing_installing-openstack-user-kuryr","installation-osp-fixing-subnet_installing-openstack-user-kuryr","installation-osp-emptying-worker-pools_installing-openstack-user-kuryr","installation-osp-modifying-networktype_installing-openstack-user-kuryr","installation-user-infra-generate-k8s-manifest-ignition_installing-openstack-user-kuryr","installation-osp-converting-ignition-resources_installing-openstack-user-kuryr","installation-osp-creating-control-plane-ignition_installing-openstack-user-kuryr","installation-osp-creating-network-resources_installing-openstack-user-kuryr","installation-osp-creating-bootstrap-machine_installing-openstack-user-kuryr","installation-osp-creating-control-plane_installing-openstack-user-kuryr","cli-logging-in-kubeadmin_installing-openstack-user-kuryr","installation-osp-deleting-bootstrap-resources_installing-openstack-user-kuryr","installation-osp-creating-compute-machines_installing-openstack-user-kuryr","installation-approve-csrs_installing-openstack-user-kuryr","installation-osp-verifying-installation_installing-openstack-user-kuryr","cluster-telemetry_installing-openstack-user-kuryr","next-steps-36","installing-openstack-user-sr-iov","prerequisites-38","cluster-entitlements_installing-openstack-user-sr-iov","installation-osp-default-deployment_installing-openstack-user-sr-iov","installation-osp-control-machines_installing-openstack-user-sr-iov","installation-osp-compute-machines_installing-openstack-user-sr-iov","installation-osp-bootstrap-machine_installing-openstack-user-sr-iov","installation-osp-downloading-modules_installing-openstack-user-sr-iov","installation-osp-downloading-playbooks_installing-openstack-user-sr-iov","installation-obtaining-installer_installing-openstack-user-sr-iov","ssh-agent-using_installing-openstack-user-sr-iov","installation-osp-creating-image_installing-openstack-user-sr-iov","installation-osp-verifying-external-network_installing-openstack-user-sr-iov","installation-osp-accessing-api_installing-openstack-user-sr-iov","installation-osp-accessing-api-floating_installing-openstack-user-sr-iov","installation-osp-accessing-api-no-floating_installing-openstack-user-sr-iov","installation-osp-describing-cloud-parameters_installing-openstack-user-sr-iov","installation-initializing_installing-openstack-user-sr-iov","installation-configuration-parameters_installing-openstack-user-sr-iov","installation-configuration-parameters-required_installing-openstack-user-sr-iov","installation-configuration-parameters-network_installing-openstack-user-sr-iov","installation-configuration-parameters-optional_installing-openstack-user-sr-iov","installation-configuration-parameters-additional-osp_installing-openstack-user-sr-iov","installation-configuration-parameters-optional-osp_installing-openstack-user-sr-iov","installation-osp-config-yaml_installing-openstack-user-sr-iov","installation-osp-custom-subnet_installing-openstack-user-sr-iov","installation-osp-fixing-subnet_installing-openstack-user-sr-iov","installation-osp-emptying-worker-pools_installing-openstack-user-sr-iov","installation-user-infra-generate-k8s-manifest-ignition_installing-openstack-user-sr-iov","installation-osp-converting-ignition-resources_installing-openstack-user-sr-iov","installation-osp-creating-control-plane-ignition_installing-openstack-user-sr-iov","installation-osp-creating-network-resources_installing-openstack-user-sr-iov","installation-osp-deploying-bare-metal-machines_installing-openstack-user-sr-iov","installation-osp-creating-bootstrap-machine_installing-openstack-user-sr-iov","installation-osp-creating-control-plane_installing-openstack-user-sr-iov","cli-logging-in-kubeadmin_installing-openstack-user-sr-iov","installation-osp-deleting-bootstrap-resources_installing-openstack-user-sr-iov","installation-osp-configuring-sr-iov_installing-openstack-user-sr-iov","installation-osp-creating-sr-iov-compute-machines_installing-openstack-user-sr-iov","installation-approve-csrs_installing-openstack-user-sr-iov","installation-osp-verifying-installation_installing-openstack-user-sr-iov","networking-osp-preparing-for-sr-iov_installing-openstack-user-sr-iov","networking-osp-enabling-metadata_installing-openstack-user-sr-iov","networking-osp-enabling-vfio-noiommu_installing-openstack-user-sr-iov","cluster-telemetry_installing-openstack-user-sr-iov","additional-resources-4","next-steps-37","installing-openstack-installer-restricted","prerequisites-39","installation-about-restricted-networks_installing-openstack-installer-restricted","installation-restricted-network-limits_installing-openstack-installer-restricted","installation-osp-default-deployment_installing-openstack-installer-restricted","installation-osp-control-machines_installing-openstack-installer-restricted","installation-osp-compute-machines_installing-openstack-installer-restricted","installation-osp-bootstrap-machine_installing-openstack-installer-restricted","cluster-entitlements_installing-openstack-installer-restricted","installation-osp-enabling-swift_installing-openstack-installer-restricted","installation-osp-describing-cloud-parameters_installing-openstack-installer-restricted","installation-creating-image-restricted_installing-openstack-installer-restricted","installation-initializing_installing-openstack-installer-restricted","installation-configure-proxy_installing-openstack-installer-restricted","installation-configuration-parameters_installing-openstack-installer-restricted","installation-configuration-parameters-required_installing-openstack-installer-restricted","installation-configuration-parameters-network_installing-openstack-installer-restricted","installation-configuration-parameters-optional_installing-openstack-installer-restricted","installation-configuration-parameters-additional-osp_installing-openstack-installer-restricted","installation-configuration-parameters-optional-osp_installing-openstack-installer-restricted","installation-osp-restricted-config-yaml_installing-openstack-installer-restricted","installation-osp-setting-worker-affinity_installing-openstack-installer-restricted","ssh-agent-using_installing-openstack-installer-restricted","installation-osp-accessing-api_installing-openstack-installer-restricted","installation-osp-accessing-api-floating_installing-openstack-installer-restricted","installation-osp-accessing-api-no-floating_installing-openstack-installer-restricted","installation-launching-installer_installing-openstack-installer-restricted","installation-osp-verifying-cluster-status_installing-openstack-installer-restricted","cli-logging-in-kubeadmin_installing-openstack-installer-restricted","olm-restricted-networks-operatorhub_installing-openstack-installer-restricted","cluster-telemetry_installing-openstack-installer-restricted","next-steps-38","uninstalling-cluster-openstack","installation-uninstall-clouds_uninstalling-cluster-openstack","uninstalling-openstack-user","installation-osp-downloading-modules_uninstalling-openstack-user","installation-uninstall-infra_uninstalling-openstack-user","/documentation/openshift_container_platform/4.8/html/installing/installing-on-openstack",{"title":2684,"visible":17,"weight":922,"urlFragment":2685,"anchor":23,"singlePageAnchor":2685,"subChapters":2686,"url":2803,"docTitle":935},"Installing on RHV","installing-on-rhv",[2687,2688,2689,2690,2691,2692,2693,2694,2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783,2784,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,2800,2801,2802],"preparing-to-install-on-rhv","preparing-to-install-on-rhv-prerequisites","choosing-an-method-to-install-ocp-on-rhv","choosing-an-method-to-install-ocp-on-rhv-installer-provisioned","choosing-an-method-to-install-ocp-on-rhv-user-provisioned","installing-rhv-default","prerequisites-40","cluster-entitlements_installing-rhv-default","installing-rhv-requirements_installing-rhv-default","installing-rhv-verifying-rhv-environment_installing-rhv-default","installing-rhv-preparing-network-environment_installing-rhv-default","installing-rhv-insecure-mode_installing-rhv-default","ssh-agent-using_installing-rhv-default","installation-obtaining-installer_installing-rhv-default","installation-launching-installer_installing-rhv-default","cli-installing-cli_installing-rhv-default","cli-logging-in-kubeadmin_installing-rhv-default","installation-osp-verifying-cluster-status_installing-rhv-default","installing-rhv-accessing-ocp-web-console_installing-rhv-default","cluster-telemetry_installing-rhv-default","installation-common-issues_installing-rhv-default","cpu-load-increases-and-nodes-go-into-a-not-ready-state_installing-rhv-default","trouble-connecting-the-rhv-cluster-api_installing-rhv-default","post-installation-tasks","installing-rhv-customizations","prerequisites-41","cluster-entitlements_installing-rhv-customizations","installing-rhv-requirements_installing-rhv-customizations","installing-rhv-verifying-rhv-environment_installing-rhv-customizations","installing-rhv-preparing-network-environment_installing-rhv-customizations","installing-rhv-insecure-mode_installing-rhv-customizations","ssh-agent-using_installing-rhv-customizations","installation-obtaining-installer_installing-rhv-customizations","installation-initializing_installing-rhv-customizations","installing-rhv-example-install-config-yaml_installing-rhv-customizations","installation-configuration-parameters_installing-rhv-customizations","installation-configuration-parameters-required_installing-rhv-customizations","installation-configuration-parameters-network_installing-rhv-customizations","installation-configuration-parameters-optional_installing-rhv-customizations","installation-configuration-parameters-additional-rhv_installing-rhv-customizations","installation-configuration-parameters-additional-machine_installing-rhv-customizations","installation-launching-installer_installing-rhv-customizations","cli-installing-cli_installing-rhv-customizations","cli-logging-in-kubeadmin_installing-rhv-customizations","installation-osp-verifying-cluster-status_installing-rhv-customizations","installing-rhv-accessing-ocp-web-console_installing-rhv-customizations","cluster-telemetry_installing-rhv-customizations","installation-common-issues_installing-rhv-customizations","cpu-load-increases-and-nodes-go-into-a-not-ready-state_installing-rhv-customizations","trouble-connecting-the-rhv-cluster-api_installing-rhv-customizations","post-installation-tasks-2","next-steps-39","installing-rhv-user-infra","prerequisites-42","cluster-entitlements_installing-rhv-user-infra","installing-rhv-requirements_installing-rhv-user-infra","installing-rhv-verifying-rhv-environment_installing-rhv-user-infra","installation-network-user-infra_installing-rhv-user-infra","installation-network-connectivity-user-infra_installing-rhv-user-infra","installing-rhv-setting-up-installation-machine_installing-rhv-user-infra","installing-rhv-insecure-mode_installing-rhv-user-infra","ssh-agent-using_installing-rhv-user-infra","installation-obtaining-installer_installing-rhv-user-infra","installation-rhv-downloading-ansible-playbooks_installing-rhv-user-infra","installation-rhv-about-inventory-yml_installing-rhv-user-infra","installation-rhv-specifying-rhcos-image-settings_installing-rhv-user-infra","installation-rhv-creating-install-config-file_installing-rhv-user-infra","installation-rhv-customizing-install-config-yaml_installing-rhv-user-infra","installation-rhv-editing-mantifests_installing-rhv-user-infra","installation-rhv-making-control-plane-nodes-non-schedulable_installing-rhv-user-infra","installation-rhv-building-ignition-files_installing-rhv-user-infra","installation-rhv-creating-templates-virtual-machines_installing-rhv-user-infra","installation-rhv-creating-bootstrap-machine_installing-rhv-user-infra","installation-rhv-creating-control-plane-nodes_installing-rhv-user-infra","installation-osp-verifying-cluster-status_installing-rhv-user-infra","installation-rhv-removing-bootstrap-machine_installing-rhv-user-infra","installation-rhv-creating-worker-nodes-completing-installation_installing-rhv-user-infra","cluster-telemetry_installing-rhv-user-infra","installing-rhv-restricted-network","prerequisites-43","installation-about-restricted-networks_installing-rhv-restricted-network","installation-restricted-network-limits_installing-rhv-restricted-network","cluster-entitlements_installing-rhv-restricted-network","installing-rhv-requirements_installing-rhv-restricted-network","installing-rhv-verifying-rhv-environment_installing-rhv-restricted-network","installation-network-user-infra_installing-rhv-restricted-network","installation-network-connectivity-user-infra_installing-rhv-restricted-network","installation-dns-user-infra_installing-rhv-restricted-network","installation-dns-user-infra-example_installing-rhv-restricted-network","installation-load-balancing-user-infra_installing-rhv-restricted-network","installation-load-balancing-user-infra-example_installing-rhv-restricted-network","installing-rhv-setting-up-installation-machine_installing-rhv-restricted-network","installing-rhv-setting-up-ca-certificate_installing-rhv-restricted-network","ssh-agent-using_installing-rhv-restricted-network","installation-rhv-downloading-ansible-playbooks_installing-rhv-restricted-network","installation-rhv-about-inventory-yml_installing-rhv-restricted-network","installation-rhv-specifying-rhcos-image-settings_installing-rhv-restricted-network","installation-rhv-creating-install-config-file_installing-rhv-restricted-network","installation-bare-metal-config-yaml_installing-rhv-restricted-network","sample-install-config-yaml-file-for-rhv","installation-configure-proxy_installing-rhv-restricted-network","installation-rhv-customizing-install-config-yaml_installing-rhv-restricted-network","installation-rhv-editing-mantifests_installing-rhv-restricted-network","installation-rhv-making-control-plane-nodes-non-schedulable_installing-rhv-restricted-network","installation-rhv-building-ignition-files_installing-rhv-restricted-network","installation-rhv-creating-templates-virtual-machines_installing-rhv-restricted-network","installation-rhv-creating-bootstrap-machine_installing-rhv-restricted-network","installation-rhv-creating-control-plane-nodes_installing-rhv-restricted-network","installation-osp-verifying-cluster-status_installing-rhv-restricted-network","installation-rhv-removing-bootstrap-machine_installing-rhv-restricted-network","installation-rhv-creating-worker-nodes-completing-installation_installing-rhv-restricted-network","cluster-telemetry_installing-rhv-restricted-network","olm-restricted-networks-operatorhub_installing-rhv-restricted-network","uninstalling-cluster-rhv","installation-uninstall-clouds_uninstalling-cluster-rhv","installation-rhv-removing-cluster-upi_uninstalling-cluster-rhv","/documentation/openshift_container_platform/4.8/html/installing/installing-on-rhv",{"title":2805,"visible":17,"weight":2806,"urlFragment":2807,"anchor":23,"singlePageAnchor":2807,"subChapters":2808,"url":3068,"docTitle":935},"Installing on vSphere",15,"installing-on-vsphere",[2809,2810,2811,2812,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,2859,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,2874,2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963,2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067],"preparing-to-install-on-vsphere","preparing-to-install-on-vsphere-prerequisites","choosing-a-method-to-install-ocp-on-vsphere","installer-provisioned-infrastructure-installation-of-openshift-container-platform-on-vsphere","user-provisioned-infrastructure-installation-of-openshift-container-platform-on-vsphere","installation-vsphere-infrastructure_preparing-to-install-on-vsphere","uninstalling-an-installer-provisioned-infrastructure-installation-of-openshift-container-platform-on-vsphere","installing-vsphere-installer-provisioned","prerequisites-44","cluster-entitlements_installing-vsphere-installer-provisioned","installation-vsphere-infrastructure_installing-vsphere-installer-provisioned","installation-vsphere-installer-network-requirements_installing-vsphere-installer-provisioned","installation-vsphere-installer-infra-requirements_installing-vsphere-installer-provisioned","ssh-agent-using_installing-vsphere-installer-provisioned","installation-obtaining-installer_installing-vsphere-installer-provisioned","installation-adding-vcenter-root-certificates_installing-vsphere-installer-provisioned","installation-launching-installer_installing-vsphere-installer-provisioned","cli-installing-cli_installing-vsphere-installer-provisioned","cli-logging-in-kubeadmin_installing-vsphere-installer-provisioned","installing-vsphere-installer-provisioned-registry","registry-removed_installing-vsphere-installer-provisioned","installation-registry-storage-config_installing-vsphere-installer-provisioned","registry-configuring-storage-vsphere_installing-vsphere-installer-provisioned","installation-registry-storage-block-recreate-rollout_installing-vsphere-installer-provisioned","vsphere-pv-backup_installing-vsphere-installer-provisioned","installation-vsphere-steal-clock-accounting_installing-vsphere-installer-provisioned","cluster-telemetry_installing-vsphere-installer-provisioned","next-steps-40","installing-vsphere-installer-provisioned-customizations","prerequisites-45","cluster-entitlements_installing-vsphere-installer-provisioned-customizations","installation-vsphere-infrastructure_installing-vsphere-installer-provisioned-customizations","installation-vsphere-installer-network-requirements_installing-vsphere-installer-provisioned-customizations","installation-vsphere-installer-infra-requirements_installing-vsphere-installer-provisioned-customizations","ssh-agent-using_installing-vsphere-installer-provisioned-customizations","installation-obtaining-installer_installing-vsphere-installer-provisioned-customizations","installation-adding-vcenter-root-certificates_installing-vsphere-installer-provisioned-customizations","installation-initializing_installing-vsphere-installer-provisioned-customizations","installation-configuration-parameters_installing-vsphere-installer-provisioned-customizations","installation-configuration-parameters-required_installing-vsphere-installer-provisioned-customizations","installation-configuration-parameters-network_installing-vsphere-installer-provisioned-customizations","installation-configuration-parameters-optional_installing-vsphere-installer-provisioned-customizations","installation-configuration-parameters-additional-vsphere_installing-vsphere-installer-provisioned-customizations","installation-configuration-parameters-optional-vsphere_installing-vsphere-installer-provisioned-customizations","installation-installer-provisioned-vsphere-config-yaml_installing-vsphere-installer-provisioned-customizations","installation-configure-proxy_installing-vsphere-installer-provisioned-customizations","installation-launching-installer_installing-vsphere-installer-provisioned-customizations","cli-installing-cli_installing-vsphere-installer-provisioned-customizations","cli-logging-in-kubeadmin_installing-vsphere-installer-provisioned-customizations","installing-vsphere-installer-provisioned-customizations-registry","registry-removed_installing-vsphere-installer-provisioned-customizations","installation-registry-storage-config_installing-vsphere-installer-provisioned-customizations","registry-configuring-storage-vsphere_installing-vsphere-installer-provisioned-customizations","installation-registry-storage-block-recreate-rollout_installing-vsphere-installer-provisioned-customizations","vsphere-pv-backup_installing-vsphere-installer-provisioned-customizations","installation-vsphere-steal-clock-accounting_installing-vsphere-installer-provisioned-customizations","cluster-telemetry_installing-vsphere-installer-provisioned-customizations","next-steps-41","installing-vsphere-installer-provisioned-network-customizations","prerequisites-46","cluster-entitlements_installing-vsphere-installer-provisioned-network-customizations","installation-vsphere-infrastructure_installing-vsphere-installer-provisioned-network-customizations","installation-vsphere-installer-network-requirements_installing-vsphere-installer-provisioned-network-customizations","installation-vsphere-installer-infra-requirements_installing-vsphere-installer-provisioned-network-customizations","ssh-agent-using_installing-vsphere-installer-provisioned-network-customizations","installation-obtaining-installer_installing-vsphere-installer-provisioned-network-customizations","installation-adding-vcenter-root-certificates_installing-vsphere-installer-provisioned-network-customizations","installation-initializing_installing-vsphere-installer-provisioned-network-customizations","installation-configuration-parameters_installing-vsphere-installer-provisioned-network-customizations","installation-configuration-parameters-required_installing-vsphere-installer-provisioned-network-customizations","installation-configuration-parameters-network_installing-vsphere-installer-provisioned-network-customizations","installation-configuration-parameters-optional_installing-vsphere-installer-provisioned-network-customizations","installation-configuration-parameters-additional-vsphere_installing-vsphere-installer-provisioned-network-customizations","installation-configuration-parameters-optional-vsphere_installing-vsphere-installer-provisioned-network-customizations","installation-installer-provisioned-vsphere-config-yaml_installing-vsphere-installer-provisioned-network-customizations","installation-configure-proxy_installing-vsphere-installer-provisioned-network-customizations","nw-network-config_installing-vsphere-installer-provisioned-network-customizations","modifying-nwoperator-config-startup_installing-vsphere-installer-provisioned-network-customizations","nw-operator-cr_installing-vsphere-installer-provisioned-network-customizations","nw-operator-cr-cno-object_installing-vsphere-installer-provisioned-network-customizations","installation-launching-installer_installing-vsphere-installer-provisioned-network-customizations","cli-installing-cli_installing-vsphere-installer-provisioned-network-customizations","cli-logging-in-kubeadmin_installing-vsphere-installer-provisioned-network-customizations","installing-vsphere-installer-provisioned-network-customizations-registry","registry-removed_installing-vsphere-installer-provisioned-network-customizations","installation-registry-storage-config_installing-vsphere-installer-provisioned-network-customizations","registry-configuring-storage-vsphere_installing-vsphere-installer-provisioned-network-customizations","installation-registry-storage-block-recreate-rollout_installing-vsphere-installer-provisioned-network-customizations","vsphere-pv-backup_installing-vsphere-installer-provisioned-network-customizations","installation-vsphere-steal-clock-accounting_installing-vsphere-installer-provisioned-network-customizations","cluster-telemetry_installing-vsphere-installer-provisioned-network-customizations","next-steps-42","installing-vsphere","prerequisites-47","cluster-entitlements_installing-vsphere","installation-vsphere-infrastructure_installing-vsphere","installation-requirements-user-infra_installing-vsphere","machine-requirements_installing-vsphere","minimum-resource-requirements_installing-vsphere","csr-management_installing-vsphere","installation-network-user-infra_installing-vsphere","installation-network-connectivity-user-infra_installing-vsphere","installation-dns-user-infra_installing-vsphere","installation-dns-user-infra-example_installing-vsphere","installation-load-balancing-user-infra_installing-vsphere","installation-load-balancing-user-infra-example_installing-vsphere","installation-infrastructure-user-infra_installing-vsphere","installation-user-provisioned-validating-dns_installing-vsphere","ssh-agent-using_installing-vsphere","installation-obtaining-installer_installing-vsphere","installation-initializing-manual_installing-vsphere","installation-vsphere-config-yaml_installing-vsphere","installation-configure-proxy_installing-vsphere","installation-user-infra-generate-k8s-manifest-ignition_installing-vsphere","installation-extracting-infraid_installing-vsphere","installation-vsphere-machines_installing-vsphere","machine-vsphere-machines_installing-vsphere","installation-disk-partitioning_installing-vsphere","architecture-rhcos-updating-bootloader.adoc_installing-vsphere","cli-installing-cli_installing-vsphere","installation-installing-bare-metal_installing-vsphere","cli-logging-in-kubeadmin_installing-vsphere","installation-approve-csrs_installing-vsphere","installation-operators-config_installing-vsphere","registry-removed_installing-vsphere","installation-registry-storage-config_installing-vsphere","registry-configuring-storage-vsphere_installing-vsphere","installation-registry-storage-non-production_installing-vsphere","installation-registry-storage-block-recreate-rollout_installing-vsphere","installation-complete-user-infra_installing-vsphere","vsphere-pv-backup_installing-vsphere","cluster-telemetry_installing-vsphere","next-steps-43","installing-vsphere-network-customizations","prerequisites-48","cluster-entitlements_installing-vsphere-network-customizations","installation-vsphere-infrastructure_installing-vsphere-network-customizations","installation-requirements-user-infra_installing-vsphere-network-customizations","machine-requirements_installing-vsphere-network-customizations","minimum-resource-requirements_installing-vsphere-network-customizations","csr-management_installing-vsphere-network-customizations","installation-network-user-infra_installing-vsphere-network-customizations","installation-network-connectivity-user-infra_installing-vsphere-network-customizations","installation-dns-user-infra_installing-vsphere-network-customizations","installation-dns-user-infra-example_installing-vsphere-network-customizations","installation-load-balancing-user-infra_installing-vsphere-network-customizations","installation-load-balancing-user-infra-example_installing-vsphere-network-customizations","installation-infrastructure-user-infra_installing-vsphere-network-customizations","installation-user-provisioned-validating-dns_installing-vsphere-network-customizations","ssh-agent-using_installing-vsphere-network-customizations","installation-obtaining-installer_installing-vsphere-network-customizations","installation-initializing-manual_installing-vsphere-network-customizations","installation-vsphere-config-yaml_installing-vsphere-network-customizations","installation-configure-proxy_installing-vsphere-network-customizations","nw-network-config_installing-vsphere-network-customizations","modifying-nwoperator-config-startup_installing-vsphere-network-customizations","nw-operator-cr_installing-vsphere-network-customizations","nw-operator-cr-cno-object_installing-vsphere-network-customizations","installation-generate-ignition-configs_installing-vsphere-network-customizations","installation-extracting-infraid_installing-vsphere-network-customizations","installation-vsphere-machines_installing-vsphere-network-customizations","machine-vsphere-machines_installing-vsphere-network-customizations","installation-disk-partitioning_installing-vsphere-network-customizations","architecture-rhcos-updating-bootloader.adoc_installing-vsphere-network-customizations","installation-installing-bare-metal_installing-vsphere-network-customizations","cli-logging-in-kubeadmin_installing-vsphere-network-customizations","installation-approve-csrs_installing-vsphere-network-customizations","installation-operators-config_installing-vsphere-network-customizations","registry-removed_installing-vsphere-network-customizations","installation-registry-storage-config_installing-vsphere-network-customizations","installation-registry-storage-block-recreate-rollout_installing-vsphere-network-customizations","installation-complete-user-infra_installing-vsphere-network-customizations","vsphere-pv-backup_installing-vsphere-network-customizations","cluster-telemetry_installing-vsphere-network-customizations","next-steps-44","installing-restricted-networks-installer-provisioned-vsphere","prerequisites_installing-restricted-networks-installer-provisioned-vsphere","installation-about-restricted-networks_installing-restricted-networks-installer-provisioned-vsphere","installation-restricted-network-limits_installing-restricted-networks-installer-provisioned-vsphere","cluster-entitlements_installing-restricted-networks-installer-provisioned-vsphere","installation-vsphere-infrastructure_installing-restricted-networks-installer-provisioned-vsphere","installation-vsphere-installer-network-requirements_installing-restricted-networks-installer-provisioned-vsphere","installation-vsphere-installer-infra-requirements_installing-restricted-networks-installer-provisioned-vsphere","ssh-agent-using_installing-restricted-networks-installer-provisioned-vsphere","installation-adding-vcenter-root-certificates_installing-restricted-networks-installer-provisioned-vsphere","installation-creating-image-restricted_installing-restricted-networks-installer-provisioned-vsphere","installation-initializing_installing-restricted-networks-installer-provisioned-vsphere","installation-configuration-parameters_installing-restricted-networks-installer-provisioned-vsphere","installation-configuration-parameters-required_installing-restricted-networks-installer-provisioned-vsphere","installation-configuration-parameters-network_installing-restricted-networks-installer-provisioned-vsphere","installation-configuration-parameters-optional_installing-restricted-networks-installer-provisioned-vsphere","installation-configuration-parameters-additional-vsphere_installing-restricted-networks-installer-provisioned-vsphere","installation-configuration-parameters-optional-vsphere_installing-restricted-networks-installer-provisioned-vsphere","installation-installer-provisioned-vsphere-config-yaml_installing-restricted-networks-installer-provisioned-vsphere","installation-configure-proxy_installing-restricted-networks-installer-provisioned-vsphere","installation-launching-installer_installing-restricted-networks-installer-provisioned-vsphere","cli-installing-cli_installing-restricted-networks-installer-provisioned-vsphere","cli-logging-in-kubeadmin_installing-restricted-networks-installer-provisioned-vsphere","olm-restricted-networks-operatorhub_installing-restricted-networks-installer-provisioned-vsphere","installing-vsphere-restricted-networks-installer-provisioned-customizations-registry","registry-removed_installing-restricted-networks-installer-provisioned-vsphere","installation-registry-storage-config_installing-restricted-networks-installer-provisioned-vsphere","registry-configuring-storage-vsphere_installing-restricted-networks-installer-provisioned-vsphere","installation-vsphere-steal-clock-accounting_installing-restricted-networks-installer-provisioned-vsphere","cluster-telemetry_installing-restricted-networks-installer-provisioned-vsphere","next-steps_installing-restricted-networks-installer-provisioned-vsphere","installing-restricted-networks-vsphere","prerequisites-49","installation-about-restricted-networks_installing-restricted-networks-vsphere","installation-restricted-network-limits_installing-restricted-networks-vsphere","cluster-entitlements_installing-restricted-networks-vsphere","installation-vsphere-infrastructure_installing-restricted-networks-vsphere","installation-requirements-user-infra_installing-restricted-networks-vsphere","machine-requirements_installing-restricted-networks-vsphere","minimum-resource-requirements_installing-restricted-networks-vsphere","csr-management_installing-restricted-networks-vsphere","installation-network-user-infra_installing-restricted-networks-vsphere","installation-network-connectivity-user-infra_installing-restricted-networks-vsphere","installation-dns-user-infra_installing-restricted-networks-vsphere","installation-dns-user-infra-example_installing-restricted-networks-vsphere","installation-load-balancing-user-infra_installing-restricted-networks-vsphere","installation-load-balancing-user-infra-example_installing-restricted-networks-vsphere","installation-infrastructure-user-infra_installing-restricted-networks-vsphere","installation-user-provisioned-validating-dns_installing-restricted-networks-vsphere","ssh-agent-using_installing-restricted-networks-vsphere","installation-initializing-manual_installing-restricted-networks-vsphere","installation-vsphere-config-yaml_installing-restricted-networks-vsphere","installation-configure-proxy_installing-restricted-networks-vsphere","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-vsphere","installation-special-config-chrony_installing-restricted-networks-vsphere","installation-extracting-infraid_installing-restricted-networks-vsphere","installation-vsphere-machines_installing-restricted-networks-vsphere","machine-vsphere-machines_installing-restricted-networks-vsphere","installation-disk-partitioning_installing-restricted-networks-vsphere","architecture-rhcos-updating-bootloader.adoc_installing-restricted-networks-vsphere","installation-installing-bare-metal_installing-restricted-networks-vsphere","cli-logging-in-kubeadmin_installing-restricted-networks-vsphere","installation-approve-csrs_installing-restricted-networks-vsphere","installation-operators-config_installing-restricted-networks-vsphere","olm-restricted-networks-operatorhub_installing-restricted-networks-vsphere","installation-registry-storage-config_installing-restricted-networks-vsphere","registry-configuring-storage-vsphere_installing-restricted-networks-vsphere","installation-registry-storage-non-production_installing-restricted-networks-vsphere","installation-registry-storage-block-recreate-rollout_installing-restricted-networks-vsphere","installation-complete-user-infra_installing-restricted-networks-vsphere","vsphere-pv-backup_installing-restricted-networks-vsphere","cluster-telemetry_installing-restricted-networks-vsphere","next-steps-45","uninstalling-cluster-vsphere-installer-provisioned","installation-uninstall-clouds_uninstalling-cluster-vsphere-installer-provisioned","using-vsphere-problem-detector-operator","vsphere-problem-detector-about_vsphere-problem-detector","vsphere-problem-detector-running_vsphere-problem-detector","vsphere-problem-detector-viewing-events_vsphere-problem-detector","vsphere-problem-detector-viewing-logs_vsphere-problem-detector","vsphere-problem-detector-config-checks_vsphere-problem-detector","vsphere-problem-detector-storage-class-config-check_vsphere-problem-detector","vsphere-problem-detector-operator-metrics_vsphere-problem-detector","additional-resources-5","/documentation/openshift_container_platform/4.8/html/installing/installing-on-vsphere",{"title":3070,"visible":17,"weight":3071,"urlFragment":3072,"anchor":23,"singlePageAnchor":3072,"subChapters":3073,"url":3336,"docTitle":935},"Installing on VMC",16,"installing-on-vmc",[3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,3189,3190,3191,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,3202,3203,3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327,3328,3329,3330,3331,3332,3333,3334,3335],"preparing-to-install-on-vmc","preparing-to-install-on-vmc-prerequisites","choosing-a-method-to-install-ocp-on-vmc","installer-provisioned-method-to-install-ocp-on-vmc","user-provisioned-method-to-install-ocp-on-vmc","installation-vsphere-infrastructure_preparing-to-install-on-vmc","method-to-uninstall-ocp-on-vmc","installing-vmc","setting-up-vmc-for-vsphere_installing-vmc","vmc-sizer-tool_installing-vmc","vsphere-prerequisites","cluster-entitlements_installing-vmc","installation-vsphere-infrastructure_installing-vmc","installation-vsphere-installer-network-requirements_installing-vmc","installation-vsphere-installer-infra-requirements_installing-vmc","ssh-agent-using_installing-vmc","installation-obtaining-installer_installing-vmc","installation-adding-vcenter-root-certificates_installing-vmc","installation-launching-installer_installing-vmc","cli-installing-cli_installing-vmc","cli-logging-in-kubeadmin_installing-vmc","installing-vmc-registry","registry-removed_installing-vmc","installation-registry-storage-config_installing-vmc","registry-configuring-storage-vsphere_installing-vmc","installation-registry-storage-block-recreate-rollout_installing-vmc","vsphere-pv-backup_installing-vmc","installation-vsphere-steal-clock-accounting_installing-vmc","cluster-telemetry_installing-vmc","next-steps-46","installing-vmc-customizations","setting-up-vmc-for-vsphere_installing-vmc-customizations","vmc-sizer-tool_installing-vmc-customizations","vsphere-prerequisites-2","cluster-entitlements_installing-vmc-customizations","installation-vsphere-infrastructure_installing-vmc-customizations","installation-vsphere-installer-network-requirements_installing-vmc-customizations","installation-vsphere-installer-infra-requirements_installing-vmc-customizations","ssh-agent-using_installing-vmc-customizations","installation-obtaining-installer_installing-vmc-customizations","installation-adding-vcenter-root-certificates_installing-vmc-customizations","installation-initializing_installing-vmc-customizations","installation-configuration-parameters_installing-vmc-customizations","installation-configuration-parameters-required_installing-vmc-customizations","installation-configuration-parameters-network_installing-vmc-customizations","installation-configuration-parameters-optional_installing-vmc-customizations","installation-configuration-parameters-additional-vsphere_installing-vmc-customizations","installation-configuration-parameters-optional-vsphere_installing-vmc-customizations","installation-installer-provisioned-vsphere-config-yaml_installing-vmc-customizations","installation-configure-proxy_installing-vmc-customizations","installation-launching-installer_installing-vmc-customizations","cli-installing-cli_installing-vmc-customizations","cli-logging-in-kubeadmin_installing-vmc-customizations","installing-vmc-customizations-registry","registry-removed_installing-vmc-customizations","installation-registry-storage-config_installing-vmc-customizations","registry-configuring-storage-vsphere_installing-vmc-customizations","installation-registry-storage-block-recreate-rollout_installing-vmc-customizations","vsphere-pv-backup_installing-vmc-customizations","installation-vsphere-steal-clock-accounting_installing-vmc-customizations","cluster-telemetry_installing-vmc-customizations","next-steps-47","installing-vmc-network-customizations","setting-up-vmc-for-vsphere_installing-vmc-network-customizations","vmc-sizer-tool_installing-vmc-network-customizations","vsphere-prerequisites-3","cluster-entitlements_installing-vmc-network-customizations","installation-vsphere-infrastructure_installing-vmc-network-customizations","installation-vsphere-installer-network-requirements_installing-vmc-network-customizations","installation-vsphere-installer-infra-requirements_installing-vmc-network-customizations","ssh-agent-using_installing-vmc-network-customizations","installation-obtaining-installer_installing-vmc-network-customizations","installation-adding-vcenter-root-certificates_installing-vmc-network-customizations","installation-initializing_installing-vmc-network-customizations","installation-configuration-parameters_installing-vmc-network-customizations","installation-configuration-parameters-required_installing-vmc-network-customizations","installation-configuration-parameters-network_installing-vmc-network-customizations","installation-configuration-parameters-optional_installing-vmc-network-customizations","installation-configuration-parameters-additional-vsphere_installing-vmc-network-customizations","installation-configuration-parameters-optional-vsphere_installing-vmc-network-customizations","installation-installer-provisioned-vsphere-config-yaml_installing-vmc-network-customizations","installation-configure-proxy_installing-vmc-network-customizations","nw-network-config_installing-vmc-network-customizations","modifying-nwoperator-config-startup_installing-vmc-network-customizations","nw-operator-cr_installing-vmc-network-customizations","nw-operator-cr-cno-object_installing-vmc-network-customizations","installation-launching-installer_installing-vmc-network-customizations","cli-installing-cli_installing-vmc-network-customizations","cli-logging-in-kubeadmin_installing-vmc-network-customizations","installing-vmc-network-customizations-registry","registry-removed_installing-vmc-network-customizations","installation-registry-storage-config_installing-vmc-network-customizations","registry-configuring-storage-vsphere_installing-vmc-network-customizations","installation-registry-storage-block-recreate-rollout_installing-vmc-network-customizations","vsphere-pv-backup_installing-vmc-network-customizations","installation-vsphere-steal-clock-accounting_installing-vmc-network-customizations","cluster-telemetry_installing-vmc-network-customizations","next-steps-48","installing-restricted-networks-vmc","setting-up-vmc-for-vsphere_installing-restricted-networks-vmc","vmc-sizer-tool_installing-restricted-networks-vmc","vsphere-prerequisites_installing-restricted-networks-vmc","installation-about-restricted-networks_installing-restricted-networks-vmc","installation-restricted-network-limits_installing-restricted-networks-vmc","cluster-entitlements_installing-restricted-networks-vmc","installation-vsphere-infrastructure_installing-restricted-networks-vmc","installation-vsphere-installer-network-requirements_installing-restricted-networks-vmc","installation-vsphere-installer-infra-requirements_installing-restricted-networks-vmc","ssh-agent-using_installing-restricted-networks-vmc","installation-adding-vcenter-root-certificates_installing-restricted-networks-vmc","installation-creating-image-restricted_installing-restricted-networks-vmc","installation-initializing_installing-restricted-networks-vmc","installation-configuration-parameters_installing-restricted-networks-vmc","installation-configuration-parameters-required_installing-restricted-networks-vmc","installation-configuration-parameters-network_installing-restricted-networks-vmc","installation-configuration-parameters-optional_installing-restricted-networks-vmc","installation-configuration-parameters-additional-vsphere_installing-restricted-networks-vmc","installation-configuration-parameters-optional-vsphere_installing-restricted-networks-vmc","installation-installer-provisioned-vsphere-config-yaml_installing-restricted-networks-vmc","installation-configure-proxy_installing-restricted-networks-vmc","installation-launching-installer_installing-restricted-networks-vmc","cli-installing-cli_installing-restricted-networks-vmc","cli-logging-in-kubeadmin_installing-restricted-networks-vmc","olm-restricted-networks-operatorhub_installing-restricted-networks-vmc","installing-vmc-restricted-networks-installer-provisioned-customizations-registry","registry-removed_installing-restricted-networks-vmc","installation-registry-storage-config_installing-restricted-networks-vmc","registry-configuring-storage-vsphere_installing-restricted-networks-vmc","installation-vsphere-steal-clock-accounting_installing-restricted-networks-vmc","cluster-telemetry_installing-restricted-networks-vmc","next-steps_installing-restricted-networks-vmc","installing-vmc-user-infra","setting-up-vmc-for-vsphere_installing-vmc-user-infra","vmc-sizer-tool_installing-vmc-user-infra","vsphere-prerequisites-4","cluster-entitlements_installing-vmc-user-infra","installation-vsphere-infrastructure_installing-vmc-user-infra","installation-requirements-user-infra_installing-vmc-user-infra","machine-requirements_installing-vmc-user-infra","minimum-resource-requirements_installing-vmc-user-infra","csr-management_installing-vmc-user-infra","installation-network-user-infra_installing-vmc-user-infra","installation-network-connectivity-user-infra_installing-vmc-user-infra","installation-dns-user-infra_installing-vmc-user-infra","installation-dns-user-infra-example_installing-vmc-user-infra","installation-load-balancing-user-infra_installing-vmc-user-infra","installation-load-balancing-user-infra-example_installing-vmc-user-infra","installation-infrastructure-user-infra_installing-vmc-user-infra","installation-user-provisioned-validating-dns_installing-vmc-user-infra","ssh-agent-using_installing-vmc-user-infra","installation-obtaining-installer_installing-vmc-user-infra","installation-initializing-manual_installing-vmc-user-infra","installation-vsphere-config-yaml_installing-vmc-user-infra","installation-configure-proxy_installing-vmc-user-infra","installation-user-infra-generate-k8s-manifest-ignition_installing-vmc-user-infra","installation-extracting-infraid_installing-vmc-user-infra","installation-vsphere-machines_installing-vmc-user-infra","machine-vsphere-machines_installing-vmc-user-infra","installation-disk-partitioning_installing-vmc-user-infra","architecture-rhcos-updating-bootloader.adoc_installing-vmc-user-infra","cli-installing-cli_installing-vmc-user-infra","installation-installing-bare-metal_installing-vmc-user-infra","cli-logging-in-kubeadmin_installing-vmc-user-infra","installation-approve-csrs_installing-vmc-user-infra","installation-operators-config_installing-vmc-user-infra","registry-removed_installing-vmc-user-infra","installation-registry-storage-config_installing-vmc-user-infra","registry-configuring-storage-vsphere_installing-vmc-user-infra","installation-registry-storage-non-production_installing-vmc-user-infra","installation-registry-storage-block-recreate-rollout_installing-vmc-user-infra","installation-complete-user-infra_installing-vmc-user-infra","vsphere-pv-backup_installing-vmc-user-infra","cluster-telemetry_installing-vmc-user-infra","next-steps-49","installing-vmc-network-customizations-user-infra","setting-up-vmc-for-vsphere_installing-vmc-network-customizations-user-infra","vmc-sizer-tool_installing-vmc-network-customizations-user-infra","vsphere-prerequisites-5","cluster-entitlements_installing-vmc-network-customizations-user-infra","installation-vsphere-infrastructure_installing-vmc-network-customizations-user-infra","installation-requirements-user-infra_installing-vmc-network-customizations-user-infra","machine-requirements_installing-vmc-network-customizations-user-infra","minimum-resource-requirements_installing-vmc-network-customizations-user-infra","csr-management_installing-vmc-network-customizations-user-infra","installation-network-user-infra_installing-vmc-network-customizations-user-infra","installation-network-connectivity-user-infra_installing-vmc-network-customizations-user-infra","installation-dns-user-infra_installing-vmc-network-customizations-user-infra","installation-dns-user-infra-example_installing-vmc-network-customizations-user-infra","installation-load-balancing-user-infra_installing-vmc-network-customizations-user-infra","installation-load-balancing-user-infra-example_installing-vmc-network-customizations-user-infra","installation-infrastructure-user-infra_installing-vmc-network-customizations-user-infra","installation-user-provisioned-validating-dns_installing-vmc-network-customizations-user-infra","ssh-agent-using_installing-vmc-network-customizations-user-infra","installation-obtaining-installer_installing-vmc-network-customizations-user-infra","installation-initializing-manual_installing-vmc-network-customizations-user-infra","installation-vsphere-config-yaml_installing-vmc-network-customizations-user-infra","installation-configure-proxy_installing-vmc-network-customizations-user-infra","modifying-nwoperator-config-startup_installing-vmc-network-customizations-user-infra","nw-operator-cr_installing-vmc-network-customizations-user-infra","nw-operator-cr-cno-object_installing-vmc-network-customizations-user-infra","installation-generate-ignition-configs_installing-vmc-network-customizations-user-infra","installation-extracting-infraid_installing-vmc-network-customizations-user-infra","installation-vsphere-machines_installing-vmc-network-customizations-user-infra","machine-vsphere-machines_installing-vmc-network-customizations-user-infra","installation-disk-partitioning_installing-vmc-network-customizations-user-infra","architecture-rhcos-updating-bootloader.adoc_installing-vmc-network-customizations-user-infra","installation-installing-bare-metal_installing-vmc-network-customizations-user-infra","cli-logging-in-kubeadmin_installing-vmc-network-customizations-user-infra","installation-approve-csrs_installing-vmc-network-customizations-user-infra","installation-operators-config_installing-vmc-network-customizations-user-infra","registry-removed_installing-vmc-network-customizations-user-infra","installation-registry-storage-config_installing-vmc-network-customizations-user-infra","installation-registry-storage-block-recreate-rollout_installing-vmc-network-customizations-user-infra","installation-complete-user-infra_installing-vmc-network-customizations-user-infra","vsphere-pv-backup_installing-vmc-network-customizations-user-infra","cluster-telemetry_installing-vmc-network-customizations-user-infra","next-steps-50","installing-restricted-networks-vmc-user-infra","setting-up-vmc-for-vsphere_installing-restricted-networks-vmc-user-infra","vmc-sizer-tool_installing-restricted-networks-vmc-user-infra","vsphere-prerequisites-6","installation-about-restricted-networks_installing-restricted-networks-vmc-user-infra","installation-restricted-network-limits_installing-restricted-networks-vmc-user-infra","cluster-entitlements_installing-restricted-networks-vmc-user-infra","installation-vsphere-infrastructure_installing-restricted-networks-vmc-user-infra","installation-requirements-user-infra_installing-restricted-networks-vmc-user-infra","machine-requirements_installing-restricted-networks-vmc-user-infra","minimum-resource-requirements_installing-restricted-networks-vmc-user-infra","csr-management_installing-restricted-networks-vmc-user-infra","installation-network-user-infra_installing-restricted-networks-vmc-user-infra","installation-network-connectivity-user-infra_installing-restricted-networks-vmc-user-infra","installation-dns-user-infra_installing-restricted-networks-vmc-user-infra","installation-dns-user-infra-example_installing-restricted-networks-vmc-user-infra","installation-load-balancing-user-infra_installing-restricted-networks-vmc-user-infra","installation-load-balancing-user-infra-example_installing-restricted-networks-vmc-user-infra","installation-infrastructure-user-infra_installing-restricted-networks-vmc-user-infra","installation-user-provisioned-validating-dns_installing-restricted-networks-vmc-user-infra","ssh-agent-using_installing-restricted-networks-vmc-user-infra","installation-initializing-manual_installing-restricted-networks-vmc-user-infra","installation-vsphere-config-yaml_installing-restricted-networks-vmc-user-infra","installation-configure-proxy_installing-restricted-networks-vmc-user-infra","installation-user-infra-generate-k8s-manifest-ignition_installing-restricted-networks-vmc-user-infra","installation-extracting-infraid_installing-restricted-networks-vmc-user-infra","installation-vsphere-machines_installing-restricted-networks-vmc-user-infra","machine-vsphere-machines_installing-restricted-networks-vmc-user-infra","installation-disk-partitioning_installing-restricted-networks-vmc-user-infra","architecture-rhcos-updating-bootloader.adoc_installing-restricted-networks-vmc-user-infra","installation-installing-bare-metal_installing-restricted-networks-vmc-user-infra","cli-logging-in-kubeadmin_installing-restricted-networks-vmc-user-infra","installation-approve-csrs_installing-restricted-networks-vmc-user-infra","installation-operators-config_installing-restricted-networks-vmc-user-infra","olm-restricted-networks-operatorhub_installing-restricted-networks-vmc-user-infra","installation-registry-storage-config_installing-restricted-networks-vmc-user-infra","registry-configuring-storage-vsphere_installing-restricted-networks-vmc-user-infra","installation-registry-storage-non-production_installing-restricted-networks-vmc-user-infra","installation-registry-storage-block-recreate-rollout_installing-restricted-networks-vmc-user-infra","installation-complete-user-infra_installing-restricted-networks-vmc-user-infra","vsphere-pv-backup_installing-restricted-networks-vmc-user-infra","cluster-telemetry_installing-restricted-networks-vmc-user-infra","next-steps-51","uninstalling-cluster-vmc","installation-uninstall-clouds_uninstalling-cluster-vmc","/documentation/openshift_container_platform/4.8/html/installing/installing-on-vmc",{"title":3338,"visible":17,"weight":3339,"urlFragment":3340,"anchor":23,"singlePageAnchor":3340,"subChapters":3341,"url":3392,"docTitle":935},"Installing on any platform",17,"installing-on-any-platform",[3342,3343,3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,3388,3389,3390,3391],"installing-platform-agnostic","prerequisites-50","cluster-entitlements_installing-platform-agnostic","installation-requirements-user-infra_installing-platform-agnostic","machine-requirements_installing-platform-agnostic","minimum-resource-requirements_installing-platform-agnostic","csr-management_installing-platform-agnostic","installation-network-user-infra_installing-platform-agnostic","installation-network-connectivity-user-infra_installing-platform-agnostic","installation-dns-user-infra_installing-platform-agnostic","installation-dns-user-infra-example_installing-platform-agnostic","installation-load-balancing-user-infra_installing-platform-agnostic","installation-load-balancing-user-infra-example_installing-platform-agnostic","installation-infrastructure-user-infra_installing-platform-agnostic","installation-user-provisioned-validating-dns_installing-platform-agnostic","ssh-agent-using_installing-platform-agnostic","installation-obtaining-installer_installing-platform-agnostic","cli-installing-cli_installing-platform-agnostic","installation-initializing-manual_installing-platform-agnostic","installation-bare-metal-config-yaml_installing-platform-agnostic","sample-install-config-yaml-file-for-other-platforms","installation-configure-proxy_installing-platform-agnostic","installation-three-node-cluster_installing-platform-agnostic","installation-user-infra-generate-k8s-manifest-ignition_installing-platform-agnostic","creating-machines-bare-metal_installing-platform-agnostic","installation-user-infra-machines-iso_installing-platform-agnostic","installation-user-infra-machines-pxe_installing-platform-agnostic","installation-user-infra-machines-advanced_installing-platform-agnostic","installation-user-infra-machines-advanced_network_installing-platform-agnostic","installation-user-infra-machines-advanced_disk_installing-platform-agnostic","installation-user-infra-machines-advanced_vardisk_installing-platform-agnostic","installation-user-infra-machines-advanced_retaindisk_installing-platform-agnostic","installation-user-infra-machines-advanced_ignition_installing-platform-agnostic","installation-user-infra-machines-advanced_embed_ignition_installing-platform-agnostic","installation-user-infra-machines-static-network_installing-platform-agnostic","installation-user-infra-machines-routing-bonding_installing-platform-agnostic","architecture-rhcos-updating-bootloader.adoc_installing-platform-agnostic","installation-installing-bare-metal_installing-platform-agnostic","cli-logging-in-kubeadmin_installing-platform-agnostic","installation-approve-csrs_installing-platform-agnostic","installation-operators-config_installing-platform-agnostic","olm-restricted-networks-operatorhub_installing-platform-agnostic","registry-removed_installing-platform-agnostic","installation-registry-storage-config_installing-platform-agnostic","registry-configuring-storage-baremetal_installing-platform-agnostic","installation-registry-storage-non-production_installing-platform-agnostic","installation-registry-storage-block-recreate-rollout-bare-metal_installing-platform-agnostic","installation-complete-user-infra_installing-platform-agnostic","cluster-telemetry_installing-platform-agnostic","next-steps-52","/documentation/openshift_container_platform/4.8/html/installing/installing-on-any-platform",{"title":3394,"visible":17,"weight":3395,"urlFragment":3396,"anchor":23,"singlePageAnchor":3396,"subChapters":3397,"url":3418,"docTitle":935},"Installation configuration",18,"installation-configuration",[3398,3399,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,3414,3415,3416,3417],"installing-customizing","installation-special-config-butane_installing-customizing","installation-special-config-butane-about_installing-customizing","installation-special-config-butane-install_installing-customizing","installation-special-config-butane-create_installing-customizing","installation-special-config-kargs_installing-customizing","installation-special-config-kmod_installing-customizing","building-testing-kernel-module-container_installing-customizing","provisioning-kernel-module-to-ocp_installing-customizing","provision-kernel-modules-via-machineconfig_installing-customizing","installation-special-config-storage_installing-customizing","installation-special-config-encrypt-disk_installing-customizing","installation-special-config-encryption-threshold_installing-customizing","installation-special-config-mirrored-disk_installing-customizing","installation-special-config-storage-procedure_installing-customizing","installation-special-config-raid_installing-customizing","installation-special-config-chrony_installing-customizing","additional-resources-6","configuring-firewall","configuring-firewall_configuring-firewall","/documentation/openshift_container_platform/4.8/html/installing/installation-configuration",{"title":3420,"visible":17,"weight":3421,"urlFragment":3422,"anchor":23,"singlePageAnchor":3422,"subChapters":3423,"url":3433,"docTitle":935},"Validating an installation",19,"validating-an-installation",[3424,3425,3426,3427,3428,3429,3430,3431,3432],"reviewing-the-installation-log_validating-an-installation","viewing-the-image-pull-source_validating-an-installation","getting-cluster-version-and-update-details_validating-an-installation","querying-the-status-of-cluster-nodes-using-the-cli_validating-an-installation","reviewing-cluster-status-from-the-openshift-web-console_validating-an-installation","reviewing-cluster-status-from-the-openshift-cluster-manager_validating-an-installation","checking-cluster-resource-availability-and-utilization_validating-an-installation","listing-alerts-that-are-firing_validating-an-installation","validating-an-installation-next-steps","/documentation/openshift_container_platform/4.8/html/installing/validating-an-installation",{"title":3435,"visible":17,"weight":3436,"urlFragment":3437,"anchor":23,"singlePageAnchor":3437,"subChapters":3438,"url":3445,"docTitle":935},"Troubleshooting installation issues",20,"installing-troubleshooting",[3439,3440,3441,3442,3443,3444],"prerequisites-51","installation-bootstrap-gather_installing-troubleshooting","installation-manually-gathering-logs-with-SSH_installing-troubleshooting","installation-manually-gathering-logs-without-SSH_installing-troubleshooting","installing-getting-debug-information_installing-troubleshooting","restarting-installation_installing-troubleshooting","/documentation/openshift_container_platform/4.8/html/installing/installing-troubleshooting",{"title":3447,"visible":17,"weight":3448,"urlFragment":3449,"anchor":23,"singlePageAnchor":3449,"subChapters":3450,"url":3457,"docTitle":935},"Support for FIPS cryptography",21,"installing-fips",[3451,3452,3453,3454,3455,3456],"installation-about-fips-validation_installing-fips","installation-about-fips-components_installing-fips","installation-about-fips-components-etcd_installing-fips","installation-about-fips-components-storage_installing-fips","installation-about-fips-components-runtimes_installing-fips","installing-fips-mode_installing-fips","/documentation/openshift_container_platform/4.8/html/installing/installing-fips",{"title":3459,"visible":17,"categoryName":17,"sections":3460},"Upgrade",[3461],{"title":3462,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":3463,"url":3464,"docTitle":3465,"sections":3466},"Updating clusters",[],"/documentation/openshift_container_platform/4.8/html/updating_clusters/index","updating_clusters",[3467,3473,3487,3501,3507,3515,3522,3535,3546],{"title":3468,"visible":17,"weight":30,"urlFragment":3469,"anchor":23,"singlePageAnchor":3469,"subChapters":3470,"url":3472,"docTitle":3465},"Understanding OpenShift Container Platform updates","understanding-openshift-updates",[3471],"update-common-terms_understanding-openshift-updates","/documentation/openshift_container_platform/4.8/html/updating_clusters/understanding-openshift-updates",{"title":3474,"visible":17,"weight":42,"urlFragment":3475,"anchor":23,"singlePageAnchor":3475,"subChapters":3476,"url":3486,"docTitle":3465},"Updating clusters overview","updating-clusters-overview",[3477,3478,3479,3480,3481,3482,3483,3484,3485],"updating-clusters-overview-understanding-container-platform-updates","updating-clusters-overview-upgrade-channels-and-releases","Understanding_clusteroperator_conditiontypes_updating-clusters-overview","updating-clusters-overview-prepare-eus-to-eus-update","updating-clusters-overview-update-cluster-using-web-console","updating-clusters-overview-update-cluster-using-cli","updating-clusters-overview-perform-canary-rollout-update","updating-clusters-overview-update-cluster-with-rhel-compute-machines","updating-clusters-overview-update-restricted-network-cluster","/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-clusters-overview",{"title":3488,"visible":17,"weight":53,"urlFragment":3489,"anchor":23,"singlePageAnchor":3489,"subChapters":3490,"url":3500,"docTitle":3465},"Understanding upgrade channels and releases","understanding-upgrade-channels-releases",[3491,3492,3493,3494,3495,3496,3497,3498,3499],"understanding-upgrade-channels_understanding-upgrade-channels-releases","candidate-version-channel_understanding-upgrade-channels-releases","fast-version-channel_understanding-upgrade-channels-releases","stable-version-channel_understanding-upgrade-channels-releases","eus-4y-channel_understanding-upgrade-channels-releases","upgrade-version-paths_understanding-upgrade-channels-releases","fast-stable-channel-strategies_understanding-upgrade-channels-releases","restricted-network-clusters_understanding-upgrade-channels-releases","switching-between-channels_understanding-upgrade-channels-releases","/documentation/openshift_container_platform/4.8/html/updating_clusters/understanding-upgrade-channels-releases",{"title":3502,"visible":17,"weight":75,"urlFragment":3503,"anchor":23,"singlePageAnchor":3503,"subChapters":3504,"url":3506,"docTitle":3465},"Preparing to perform an EUS-to-EUS update","preparing-eus-eus-upgrade",[3505],"updating-eus-to-eus-upgrade_eus-to-eus-upgrade","/documentation/openshift_container_platform/4.8/html/updating_clusters/preparing-eus-eus-upgrade",{"title":3508,"visible":17,"weight":442,"urlFragment":3509,"anchor":23,"singlePageAnchor":3509,"subChapters":3510,"url":3514,"docTitle":3465},"Updating a cluster using the web console","updating-cluster-within-minor",[1013,3511,3512,3513],"update-using-custom-machine-config-pools-canary_updating-cluster-within-minor","update-upgrading-web_updating-cluster-within-minor","update-changing-update-server-web_updating-cluster-within-minor","/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-cluster-within-minor",{"title":3516,"visible":17,"weight":460,"urlFragment":3517,"anchor":23,"singlePageAnchor":3517,"subChapters":3518,"url":3521,"docTitle":3465},"Updating a cluster using the CLI","updating-cluster-cli",[1024,3519,3520],"update-upgrading-cli_updating-cluster-cli","update-changing-update-server-cli_updating-cluster-cli","/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-cluster-cli",{"title":3523,"visible":17,"weight":475,"urlFragment":3524,"anchor":23,"singlePageAnchor":3524,"subChapters":3525,"url":3534,"docTitle":3465},"Performing a canary rollout update","update-using-custom-machine-config-pools",[3526,3527,3528,3529,3530,3531,3532,3533],"update-using-custom-machine-config-pools-about-mcp_update-using-custom-machine-config-pools","update-using-custom-machine-config-pools-about_update-using-custom-machine-config-pools","update-using-custom-machine-config-pools-mcp_update-using-custom-machine-config-pools","update-using-custom-machine-config-pools-pause_update-using-custom-machine-config-pools","update-using-custom-machine-config-pools-update_update-using-custom-machine-config-pools","update-using-custom-machine-config-pools-unpause_update-using-custom-machine-config-pools","update-using-custom-machine-config-pools-fail_update-using-custom-machine-config-pools","update-using-custom-machine-config-pools-mcp-remove_update-using-custom-machine-config-pools","/documentation/openshift_container_platform/4.8/html/updating_clusters/update-using-custom-machine-config-pools",{"title":3536,"visible":17,"weight":876,"urlFragment":3537,"anchor":23,"singlePageAnchor":3537,"subChapters":3538,"url":3545,"docTitle":3465},"Updating a cluster that includes RHEL compute machines","updating-cluster-rhel-compute",[1045,3539,3540,3541,3542,3543,3544],"update-upgrading-web_updating-cluster-rhel-compute","updating-cluster-rhel-compute-hooks","rhel-compute-about-hooks_updating-cluster-rhel-compute","rhel-compute-using-hooks_updating-cluster-rhel-compute","rhel-compute-available-hooks_updating-cluster-rhel-compute","rhel-compute-updating-minor_updating-cluster-rhel-compute","/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-cluster-rhel-compute",{"title":3547,"visible":17,"weight":884,"urlFragment":3548,"anchor":23,"singlePageAnchor":3548,"subChapters":3549,"url":3582,"docTitle":3465},"Updating a cluster in a disconnected environment","updating-a-cluster-in-a-disconnected-environment",[3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578,1096,3579,3580,3581,521],"about-restricted-network-updates","about-disconnected-updates-mirroring","about-disconnected-updates-update","mirroring-ocp-image-repository","prerequisites_mirroring-ocp-image-repository","updating-restricted-network-mirror-host","cli-installing-cli_mirroring-ocp-image-repository","installation-adding-registry-pull-secret_mirroring-ocp-image-repository","update-mirror-repository_mirroring-ocp-image-repository","updating-restricted-network-cluster-OSUS","update-service-overview_updating-restricted-network-cluster-osus","update-service-prereqs","registry-configuration-for-update-service","images-update-global-pull-secret_updating-restricted-network-cluster-osus","update-service-install","update-service-install-web-console_updating-restricted-network-cluster-osus","update-service-install-cli_updating-restricted-network-cluster-osus","update-service-graph-data_updating-restricted-network-cluster-osus","update-service-create-service","update-service-create-service-web-console_updating-restricted-network-cluster-osus","update-service-create-service-cli_updating-restricted-network-cluster-osus","update-service-configure-cvo","update-service-delete-service","update-service-delete-service-web-console_updating-restricted-network-cluster-osus","update-service-delete-service-cli_updating-restricted-network-cluster-osus","update-service-uninstall","update-service-uninstall-web-console_updating-restricted-network-cluster-osus","update-service-uninstall-cli_updating-restricted-network-cluster-osus","updating-restricted-network-cluster","update-restricted_updating-restricted-network-cluster","images-configuration-registry-mirror_updating-restricted-network-cluster","generating-icsp-object-scoped-to-a-registry_updating-restricted-network-cluster","/documentation/openshift_container_platform/4.8/html/updating_clusters/updating-a-cluster-in-a-disconnected-environment",{"title":3584,"visible":17,"categoryName":17,"sections":3585},"Configure",[3586,3811,4120,4688,4775],{"title":3587,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":3588,"url":3589,"docTitle":3590,"sections":3591},"Storage",[],"/documentation/openshift_container_platform/4.8/html/storage/index","storage",[3592,3603,3612,3640,3716,3782,3792],{"title":3593,"visible":17,"weight":30,"urlFragment":3594,"anchor":23,"singlePageAnchor":3594,"subChapters":3595,"url":3602,"docTitle":3590},"OpenShift Container Platform storage overview","storage-overview",[3596,3597,3598,3599,3600,3601],"openshift-storage-common-terms_storage-overview","storage-types","ephemeral-storage","persistent-storage","container-storage-interface","dynamic-provisioning-overview","/documentation/openshift_container_platform/4.8/html/storage/storage-overview",{"title":3604,"visible":17,"weight":42,"urlFragment":3605,"anchor":23,"singlePageAnchor":3605,"subChapters":3606,"url":3611,"docTitle":3590},"Understanding ephemeral storage","understanding-ephemeral-storage",[3607,3608,3609,3610],"storage-ephemeral-storage-overview_understanding-ephemeral-storage","storage-ephemeral-storage-types_understanding-ephemeral-storage","storage-ephemeral-storage-manage_understanding-ephemeral-storage","storage-ephemeral-storage-monitoring_understanding-ephemeral-storage","/documentation/openshift_container_platform/4.8/html/storage/understanding-ephemeral-storage",{"title":3613,"visible":17,"weight":53,"urlFragment":3614,"anchor":23,"singlePageAnchor":3614,"subChapters":3615,"url":3639,"docTitle":3590},"Understanding persistent storage","understanding-persistent-storage",[3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638],"persistent-storage-overview_understanding-persistent-storage","lifecycle-volume-claim_understanding-persistent-storage","provisioning_understanding-persistent-storage","binding_understanding-persistent-storage","using-pods_understanding-persistent-storage","pvcprotection_understanding-persistent-storage","releasing_understanding-persistent-storage","reclaiming_understanding-persistent-storage","reclaim-manual_understanding-persistent-storage","reclaim-policy_understanding-persistent-storage","persistent-volumes_understanding-persistent-storage","types-of-persistent-volumes_understanding-persistent-storage","pv-capacity_understanding-persistent-storage","pv-access-modes_understanding-persistent-storage","pv-phase_understanding-persistent-storage","pv-mount-options_understanding-persistent-storage","persistent-volume-claims_understanding-persistent-storage","pvc-storage-class_understanding-persistent-storage","pvc-access-modes_understanding-persistent-storage","pvc-resources_understanding-persistent-storage","pvc-claims-as-volumes_understanding-persistent-storage","block-volume-support_understanding-persistent-storage","block-volume-examples_understanding-persistent-storage","/documentation/openshift_container_platform/4.8/html/storage/understanding-persistent-storage",{"title":3641,"visible":17,"weight":75,"urlFragment":3642,"anchor":23,"singlePageAnchor":3642,"subChapters":3643,"url":3715,"docTitle":3590},"Configuring persistent storage","configuring-persistent-storage",[3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,3696,3697,3698,3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,1013,3711,3712,3713,3714],"persistent-storage-aws","storage-create-EBS-storage-class_persistent-storage-aws","creating-the-persistent-volume-claim","volume-format-AWS_persistent-storage-aws","maximum-number-of-ebs-volumes-on-a-node_persistent-storage-aws","additional-resources_persistent-storage-aws","persistent-storage-using-azure","storage-create-azure-storage-class_persistent-storage-azure","creating-the-persistent-volume-claim-2","volume-format-azure_persistent-storage-azure","persistent-storage-using-azure-file","create-azure-file-secret_persistent-storage-azure-file","create-azure-file-pod_persistent-storage-azure-file","persistent-storage-cinder","persistent-storage-cinder-provisioning_persistent-storage-cinder","persistent-storage-cinder-creating-pv_persistent-storage-cinder","persistent-storage-cinder-pv-format_persistent-storage-cinder","persistent-storage-cinder-volume-security_persistent-storage-cinder","persistent-storage-cinder-maximum-volume_persistent-storage-cinder","persistent-storage-using-fibre","provisioning-fibre_persistent-storage-fibre","enforcing-disk-quota_persistent-storage-fibre","fibre-volume-security_persistent-storage-fibre","persistent-storage-using-flexvolume","flexvolume-drivers_persistent-storage-flexvolume","flexvolume-driver-example_persistent-storage-flexvolume","flexvolume-installing_persistent-storage-flexvolume","flexvolume-driver-consuming_persistent-storage-flexvolume","persistent-storage-using-gce","storage-create-GCE-storage-class_persistent-storage-gce","creating-the-persistent-volume-claim-3","volume-format-GCE_persistent-storage-gce","persistent-storage-using-hostpath","persistent-storage-hostpath-about_persistent-storage-hostpath","hostpath-static-provisioning_persistent-storage-hostpath","persistent-storage-hostpath-pod_persistent-storage-hostpath","persistent-storage-using-iscsi","persistent-storage-iscsi-provisioning_persistent-storage-iscsi","enforcing-disk-quotas-iscsi_persistent-storage-iscsi","volume-security-iscsi_persistent-storage-iscsi","challenge-handshake-authentication-protocol-chap-configuration","iscsi-multipath_persistent-storage-iscsi","iscsi-custom-iqn_persistent-storage-iscsi","persistent-storage-using-local-volume","local-storage-install_persistent-storage-local","local-volume-cr_persistent-storage-local","local-create-cr-manual_persistent-storage-local","create-local-pvc_persistent-storage-local","local-pod_persistent-storage-local","local-storage-discovery_persistent-storage-local","local-tolerations_persistent-storage-local","deleting-the-local-storage-operator-resources","local-removing-device_persistent-storage-local","local-storage-uninstall_persistent-storage-local","persistent-storage-using-nfs","persistent-storage-nfs-provisioning_persistent-storage-nfs","nfs-enforcing-disk-quota_persistent-storage-nfs","nfs-volume-security_persistent-storage-nfs","storage-persistent-storage-nfs-group-ids_persistent-storage-nfs","nfs-user-id_persistent-storage-nfs","nfs-selinux_persistent-storage-nfs","export-settings","nfs-reclaiming-resources_persistent-storage-nfs","additional-configuration-and-troubleshooting","red-hat-openshift-container-storage","persistent-storage-using-vsphere","dynamically-provisioning-vmware-vsphere-volumes","vsphere-dynamic-provisioning_persistent-storage-efs","vsphere-dynamic-provisioning-cli_persistent-storage-efs","vsphere-static-provisioning_persistent-storage-efs","vsphere-formatting-volumes_persistent-storage-efs","/documentation/openshift_container_platform/4.8/html/storage/configuring-persistent-storage",{"title":3717,"visible":17,"weight":442,"urlFragment":3718,"anchor":23,"singlePageAnchor":3718,"subChapters":3719,"url":3781,"docTitle":3590},"Using Container Storage Interface (CSI)","using-container-storage-interface-csi",[3720,3721,3722,3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743,3744,3745,3746,3747,3748,3749,3750,1553,3751,3752,3753,3754,3755,3756,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,3771,3772,3773,3774,3775,3776,3777,3778,3779,3780,1605],"persistent-storage-csi","persistent-storage-csi-architecture_persistent-storage-csi","external-csi-contollers_persistent-storage-csi","csi-driver-daemonset_persistent-storage-csi","csi-drivers-supported_persistent-storage-csi","csi-dynamic-provisioning_persistent-storage-csi","csi-example-usage_persistent-storage-csi","ephemeral-storage-csi-inline","ephemeral-storage-csi-inline-overview_ephemeral-storage-csi-inline","support-limitations","ephemeral-storage-csi-inline-pod_ephemeral-storage-csi-inline","persistent-storage-csi-snapshots","persistent-storage-csi-snapshots-overview_persistent-storage-csi-snapshots","persistent-storage-csi-snapshots-controller-sidecar_persistent-storage-csi-snapshots","external-controller","external-sidecar","persistent-storage-csi-snapshots-operator_persistent-storage-csi-snapshots","volume-snapshot-crds","persistent-storage-csi-snapshots-provision_persistent-storage-csi-snapshots","snapshots-dynamic-provisioning_persistent-storage-csi-snapshots","snapshots-manual-provisioning_persistent-storage-csi-snapshots","persistent-storage-csi-snapshots-create_persistent-storage-csi-snapshots","persistent-storage-csi-snapshots-delete_persistent-storage-csi-snapshots","persistent-storage-csi-snapshots-restore_persistent-storage-csi-snapshots","persistent-storage-csi-cloning","persistent-storage-csi-cloning-overview_persistent-storage-csi-cloning","support-limitations-2","persistent-storage-csi-cloning-provisioning_persistent-storage-csi-cloning","persistent-storage-csi-migration","persistent-storage-csi-migration-overview_persistent-storage-csi-migration","persistent-storage-csi-migration-enable_persistent-storage-csi-migration","persistent-storage-csi-ebs","overview","csi-about_persistent-storage-csi-ebs","persistent-storage-csi-azure-disk","overview-2","csi-about_persistent-storage-csi-azure","csi-tp-enable_persistent-storage-csi-azure","persistent-storage-csi-gcp-pd","overview-3","csi-about_persistent-storage-csi-gcp-pd","persistent-storage-csi-gcp-pd-storage-class-ref_persistent-storage-csi-gcp-pd","persistent-storage-csi-gcp-pd-encrypted-pv_persistent-storage-csi-gcp-pd","persistent-storage-csi-cinder","overview-4","csi-about_persistent-storage-csi-cinder","persistent-storage-csi-cinder_persistent-storage-csi-cinder","persistent-storage-csi-manila","overview-5","csi-about_persistent-storage-csi-manila","persistent-storage-csi-manila-limitations_persistent-storage-csi-manila","persistent-storage-csi-manila-dynamic-provisioning_persistent-storage-csi-manila","persistent-storage-csi-ovirt","overview-6","csi-about_persistent-storage-csi-ovirt","ovirt-csi-driver-storage-class_persistent-storage-csi-ovirt","persistent-storage-rhv_persistent-storage-csi-ovirt","persistent-storage-vsphere","overview-7","csi-about_persistent-storage-csi-vsphere","csi-tp-enable_persistent-storage-csi-vsphere","/documentation/openshift_container_platform/4.8/html/storage/using-container-storage-interface-csi",{"title":3783,"visible":17,"weight":460,"urlFragment":3784,"anchor":23,"singlePageAnchor":3784,"subChapters":3785,"url":3791,"docTitle":3590},"Expanding persistent volumes","expanding-persistent-volumes",[3786,3787,3788,3789,3790],"add-volume-expansion_expanding-persistent-volumes","expanding-csi-volumes_expanding-persistent-volumes","expanding-flexvolume_expanding-persistent-volumes","expanding-pvc-filesystem_expanding-persistent-volumes","expanding-recovering-from-failure_expanding-persistent-volumes","/documentation/openshift_container_platform/4.8/html/storage/expanding-persistent-volumes",{"title":3793,"visible":17,"weight":475,"urlFragment":3794,"anchor":23,"singlePageAnchor":3794,"subChapters":3795,"url":3810,"docTitle":3590},"Dynamic provisioning","dynamic-provisioning",[3796,3797,3798,3799,3800,3801,3802,3803,3804,3805,3806,3807,3808,3809],"about_dynamic-provisioning","available-plug-ins_dynamic-provisioning","defining-storage-classes_dynamic-provisioning","basic-storage-class-definition_dynamic-provisioning","storage-class-annotations_dynamic-provisioning","openstack-cinder-storage-class_dynamic-provisioning","openstack-manila-csi-definition_dynamic-provisioning","aws-definition_dynamic-provisioning","azure-disk-definition_dynamic-provisioning","azure-file-definition_dynamic-provisioning","azure-file-considerations_dynamic-provisioning","gce-persistentdisk-storage-class_dynamic-provisioning","vsphere-definition_dynamic-provisioning","change-default-storage-class_dynamic-provisioning","/documentation/openshift_container_platform/4.8/html/storage/dynamic-provisioning",{"title":3812,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":3813,"url":3814,"docTitle":3815,"sections":3816},"Authentication and authorization",[],"/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/index","authentication_and_authorization",[3817,3825,3837,3851,3859,3867,3877,3953,3972,3979,3987,3998,4005,4013,4020,4041,4049,4078],{"title":3818,"visible":17,"weight":30,"urlFragment":3819,"anchor":23,"singlePageAnchor":3819,"subChapters":3820,"url":3824,"docTitle":3815},"Overview of authentication and authorization","overview-of-authentication-authorization",[3821,3822,3823],"openshift-auth-common-terms_overview-of-authentication-authorization","authentication-overview","authorization-overview","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/overview-of-authentication-authorization",{"title":3826,"visible":17,"weight":42,"urlFragment":3827,"anchor":23,"singlePageAnchor":3827,"subChapters":3828,"url":3836,"docTitle":3815},"Understanding authentication","understanding-authentication",[3829,3830,3831,3832,3833,3834,3835],"rbac-users_understanding-authentication","rbac-groups_understanding-authentication","rbac-api-authentication_understanding-authentication","oauth-server-overview_understanding-authentication","oauth-token-requests_understanding-authentication","authentication-api-impersonation_understanding-authentication","authentication-prometheus-system-metrics_understanding-authentication","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/understanding-authentication",{"title":3838,"visible":17,"weight":53,"urlFragment":3839,"anchor":23,"singlePageAnchor":3839,"subChapters":3840,"url":3850,"docTitle":3815},"Configuring the internal OAuth server","configuring-internal-oauth",[3841,3842,3843,3844,3845,3846,3847,3848,3849],"oauth-server-overview_configuring-internal-oauth","oauth-token-request-flows_configuring-internal-oauth","oauth-internal-options_configuring-internal-oauth","oauth-token-duration_configuring-internal-oauth","oauth-grant-options_configuring-internal-oauth","oauth-configuring-internal-oauth_configuring-internal-oauth","oauth-token-inactivity-timeout_configuring-internal-oauth","oauth-server-metadata_configuring-internal-oauth","oauth-troubleshooting-api-events_configuring-internal-oauth","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/configuring-internal-oauth",{"title":3852,"visible":17,"weight":75,"urlFragment":3853,"anchor":23,"singlePageAnchor":3853,"subChapters":3854,"url":3858,"docTitle":3815},"Configuring OAuth clients","configuring-oauth-clients",[3855,3856,3857,1553],"oauth-default-clients_configuring-oauth-clients","oauth-register-additional-client_configuring-oauth-clients","oauth-token-inactivity-timeout_configuring-oauth-clients","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/configuring-oauth-clients",{"title":3860,"visible":17,"weight":442,"urlFragment":3861,"anchor":23,"singlePageAnchor":3861,"subChapters":3862,"url":3866,"docTitle":3815},"Managing user-owned OAuth access tokens","managing-oauth-access-tokens",[3863,3864,3865],"oauth-list-tokens_managing-oauth-access-tokens","oauth-view-details-tokens_managing-oauth-access-tokens","oauth-delete-tokens_managing-oauth-access-tokens","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/managing-oauth-access-tokens",{"title":3868,"visible":17,"weight":460,"urlFragment":3869,"anchor":23,"singlePageAnchor":3869,"subChapters":3870,"url":3876,"docTitle":3815},"Understanding identity provider configuration","understanding-identity-provider",[3871,3872,3873,3874,3875],"identity-provider-overview_understanding-identity-provider","supported-identity-providers","removing-kubeadmin_understanding-identity-provider","identity-provider-parameters_understanding-identity-provider","identity-provider-default-CR_understanding-identity-provider","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/understanding-identity-provider",{"title":3878,"visible":17,"weight":475,"urlFragment":3879,"anchor":23,"singlePageAnchor":3879,"subChapters":3880,"url":3952,"docTitle":3815},"Configuring identity providers","configuring-identity-providers",[3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951],"configuring-htpasswd-identity-provider","identity-provider-overview_configuring-htpasswd-identity-provider","identity-provider-htpasswd-about_configuring-htpasswd-identity-provider","creating-htpasswd-file","identity-provider-creating-htpasswd-file-linux_configuring-htpasswd-identity-provider","identity-provider-creating-htpasswd-file-windows_configuring-htpasswd-identity-provider","identity-provider-creating-htpasswd-secret_configuring-htpasswd-identity-provider","identity-provider-htpasswd-CR_configuring-htpasswd-identity-provider","add-identity-provider_configuring-htpasswd-identity-provider","identity-provider-htpasswd-update-users_configuring-htpasswd-identity-provider","identity-provider-configuring-using-the-web-console_configuring-htpasswd-identity-provider","configuring-keystone-identity-provider","identity-provider-overview_configuring-keystone-identity-provider","identity-provider-keystone-about_configuring-keystone-identity-provider","identity-provider-creating-secret-tls_configuring-keystone-identity-provider","identity-provider-creating-configmap_configuring-keystone-identity-provider","identity-provider-keystone-CR_configuring-keystone-identity-provider","add-identity-provider_configuring-keystone-identity-provider","configuring-ldap-identity-provider","identity-provider-overview_configuring-ldap-identity-provider","identity-provider-about-ldap_configuring-ldap-identity-provider","identity-provider-creating-ldap-secret_configuring-ldap-identity-provider","identity-provider-creating-configmap_configuring-ldap-identity-provider","identity-provider-ldap-CR_configuring-ldap-identity-provider","add-identity-provider_configuring-ldap-identity-provider","configuring-basic-authentication-identity-provider","identity-provider-overview_configuring-basic-authentication-identity-provider","identity-provider-about-basic-authentication_configuring-basic-authentication-identity-provider","identity-provider-creating-secret-tls_configuring-basic-authentication-identity-provider","identity-provider-creating-configmap_configuring-basic-authentication-identity-provider","identity-provider-basic-authentication-CR_configuring-basic-authentication-identity-provider","add-identity-provider_configuring-basic-authentication-identity-provider","example-apache-httpd-configuration_configuring-basic-authentication-identity-provider","file-requirements","identity-provider-basic-authentication-troubleshooting_configuring-basic-authentication-identity-provider","configuring-request-header-identity-provider","identity-provider-overview_configuring-request-header-identity-provider","identity-provider-about-request-header_configuring-request-header-identity-provider","sspi-windows_configuring-request-header-identity-provider","identity-provider-creating-configmap_configuring-request-header-identity-provider","identity-provider-request-header-CR_configuring-request-header-identity-provider","add-identity-provider_configuring-request-header-identity-provider","example-apache-auth-config-using-request-header","configuring-github-identity-provider","identity-provider-overview_configuring-github-identity-provider","identity-provider-github-about_configuring-github-identity-provider","identity-provider-registering-github_configuring-github-identity-provider","identity-provider-creating-secret_configuring-github-identity-provider","identity-provider-creating-configmap_configuring-github-identity-provider","identity-provider-github-CR_configuring-github-identity-provider","add-identity-provider_configuring-github-identity-provider","configuring-gitlab-identity-provider","identity-provider-overview_configuring-gitlab-identity-provider","identity-provider-gitlab-about_configuring-gitlab-identity-provider","identity-provider-creating-secret_configuring-gitlab-identity-provider","identity-provider-creating-configmap_configuring-gitlab-identity-provider","identity-provider-gitlab-CR_configuring-gitlab-identity-provider","add-identity-provider_configuring-gitlab-identity-provider","configuring-google-identity-provider","identity-provider-overview_configuring-google-identity-provider","identity-provider-google-about_configuring-google-identity-provider","identity-provider-creating-secret_configuring-google-identity-provider","identity-provider-google-CR_configuring-google-identity-provider","add-identity-provider_configuring-google-identity-provider","configuring-oidc-identity-provider","identity-provider-overview_configuring-oidc-identity-provider","identity-provider-creating-secret_configuring-oidc-identity-provider","identity-provider-creating-configmap_configuring-oidc-identity-provider","identity-provider-oidc-CR_configuring-oidc-identity-provider","add-identity-provider_configuring-oidc-identity-provider","identity-provider-configuring-using-the-web-console_configuring-oidc-identity-provider","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/configuring-identity-providers",{"title":3954,"visible":17,"weight":876,"urlFragment":3955,"anchor":23,"singlePageAnchor":3955,"subChapters":3956,"url":3971,"docTitle":3815},"Using RBAC to define and apply permissions","using-rbac",[3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970],"authorization-overview_using-rbac","default-roles_using-rbac","evaluating-authorization_using-rbac","cluster-role-aggregations_using-rbac","rbac-projects-namespaces_using-rbac","rbac-default-projects_using-rbac","viewing-cluster-roles_using-rbac","viewing-local-roles_using-rbac","adding-roles_using-rbac","creating-local-role_using-rbac","creating-cluster-role_using-rbac","local-role-binding-commands_using-rbac","cluster-role-binding-commands_using-rbac","creating-cluster-admin_using-rbac","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/using-rbac",{"title":3973,"visible":17,"weight":884,"urlFragment":3974,"anchor":23,"singlePageAnchor":3974,"subChapters":3975,"url":3978,"docTitle":3815},"Removing the kubeadmin user","removing-kubeadmin",[3976,3977],"understanding-kubeadmin_removing-kubeadmin","removing-kubeadmin_removing-kubeadmin","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/removing-kubeadmin",{"title":3980,"visible":17,"weight":895,"urlFragment":3981,"anchor":23,"singlePageAnchor":3981,"subChapters":3982,"url":3986,"docTitle":3815},"Understanding and creating service accounts","understanding-and-creating-service-accounts",[3983,3984,3985],"service-accounts-overview_understanding-service-accounts","service-accounts-managing_understanding-service-accounts","service-accounts-granting-roles_understanding-service-accounts","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/understanding-and-creating-service-accounts",{"title":3988,"visible":17,"weight":906,"urlFragment":3989,"anchor":23,"singlePageAnchor":3989,"subChapters":3990,"url":3997,"docTitle":3815},"Using service accounts in applications","using-service-accounts",[3991,3992,3993,3994,3995,3996],"service-accounts-overview_using-service-accounts","service-accounts-default_using-service-accounts","default-cluster-service-accounts_using-service-accounts","default-service-accounts-and-roles_using-service-accounts","service-accounts-managing_using-service-accounts","service-accounts-using-credentials-externally_using-service-accounts","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/using-service-accounts",{"title":3999,"visible":17,"weight":913,"urlFragment":4000,"anchor":23,"singlePageAnchor":4000,"subChapters":4001,"url":4004,"docTitle":3815},"Using a service account as an OAuth client","using-service-accounts-as-oauth-client",[4002,4003],"service-accounts-as-oauth-clients_using-service-accounts-as-oauth-client","redirect-uris-for-service-accounts_using-service-accounts-as-oauth-client","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/using-service-accounts-as-oauth-client",{"title":4006,"visible":17,"weight":922,"urlFragment":4007,"anchor":23,"singlePageAnchor":4007,"subChapters":4008,"url":4012,"docTitle":3815},"Scoping tokens","tokens-scoping",[4009,4010,4011],"tokens-scoping-about_configuring-internal-oauth","scoping-tokens-user-scopes_configuring-internal-oauth","scoping-tokens-role-scope_configuring-internal-oauth","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/tokens-scoping",{"title":4014,"visible":17,"weight":2806,"urlFragment":4015,"anchor":23,"singlePageAnchor":4015,"subChapters":4016,"url":4019,"docTitle":3815},"Using bound service account tokens","bound-service-account-tokens",[4017,4018],"bound-sa-tokens-about_bound-service-account-tokens","bound-sa-tokens-configuring_bound-service-account-tokens","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/bound-service-account-tokens",{"title":4021,"visible":17,"weight":3071,"urlFragment":4022,"anchor":23,"singlePageAnchor":4022,"subChapters":4023,"url":4040,"docTitle":3815},"Managing security context constraints","managing-pod-security-policies",[4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039],"security-context-constraints-about_configuring-internal-oauth","default-sccs_configuring-internal-oauth","scc-settings_configuring-internal-oauth","authorization-SCC-strategies_configuring-internal-oauth","authorization-controlling-volumes_configuring-internal-oauth","admission_configuring-internal-oauth","scc-prioritization_configuring-internal-oauth","security-context-constraints-pre-allocated-values_configuring-internal-oauth","security-context-constraints-example_configuring-internal-oauth","security-context-constraints-creating_configuring-internal-oauth","role-based-access-to-ssc_configuring-internal-oauth","security-context-constraints-command-reference_configuring-internal-oauth","listing-security-context-constraints_configuring-internal-oauth","examining-a-security-context-constraints-object_configuring-internal-oauth","deleting-security-context-constraints_configuring-internal-oauth","updating-security-context-constraints_configuring-internal-oauth","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/managing-pod-security-policies",{"title":4042,"visible":17,"weight":3339,"urlFragment":4043,"anchor":23,"singlePageAnchor":4043,"subChapters":4044,"url":4048,"docTitle":3815},"Impersonating the system:admin user","impersonating-system-admin",[4045,4046,4047],"authentication-api-impersonation_impersonating-system-admin","impersonation-system-admin-user_impersonating-system-admin","impersonation-system-admin-group_impersonating-system-admin","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/impersonating-system-admin",{"title":4050,"visible":17,"weight":3395,"urlFragment":4051,"anchor":23,"singlePageAnchor":4051,"subChapters":4052,"url":4077,"docTitle":3815},"Syncing LDAP groups","ldap-syncing",[4053,4054,4055,4056,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,4074,4075,4076],"ldap-syncing-about_ldap-syncing-groups","ldap-syncing-config-rfc2307_ldap-syncing-groups","ldap-syncing-config-activedir_ldap-syncing-groups","ldap-syncing-config-augmented-activedir_ldap-syncing-groups","ldap-syncing-running_ldap-syncing-groups","ldap-syncing-running-all-ldap_ldap-syncing-groups","ldap-syncing-running-openshift_ldap-syncing-groups","ldap-syncing-running-subset_ldap-syncing-groups","ldap-syncing-pruning_ldap-syncing-groups","ldap-auto-syncing_ldap-syncing-groups","ldap-syncing-examples_ldap-syncing-groups","ldap-syncing-rfc2307_ldap-syncing-groups","ldap-syncing-rfc2307-user-defined_ldap-syncing-groups","ldap-syncing-rfc2307-user-defined-error_ldap-syncing-groups","ldap-syncing-activedir_ldap-syncing-groups","ldap-syncing-augmented-activedir_ldap-syncing-groups","ldap-syncing-nesting_ldap-syncing-groups","ldap-syncing-spec_ldap-syncing-groups","sync-ldap-v1-ldapsyncconfig","sync-ldap-v1-stringsource","sync-ldap-v1-ldapquery","sync-ldap-v1-rfc2307config","sync-ldap-v1-activedirectoryconfig","sync-ldap-v1-augmentedactivedirectoryconfig","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/ldap-syncing",{"title":4079,"visible":17,"weight":3421,"urlFragment":4080,"anchor":23,"singlePageAnchor":4080,"subChapters":4081,"url":4119,"docTitle":3815},"Managing cloud provider credentials","managing-cloud-provider-credentials",[4082,4083,4084,4085,4086,4087,4088,4089,4090,4091,4092,4093,1605,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,4104,4105,1633,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118],"about-cloud-credential-operator","about-cloud-credential-operator-modes","about-cloud-credential-operator-default","additional-resources_about-cloud-credential-operator","cco-mode-mint","mint-mode-permissions","mint-mode-permissions-aws","mint-mode-permissions-gcp","admin-credentials-root-secret-formats_cco-mode-mint","mint-mode-with-removal-or-rotation-of-admin-credential_cco-mode-mint","manually-rotating-cloud-creds_cco-mode-mint","manually-removing-cloud-creds_cco-mode-mint","cco-mode-passthrough","passthrough-mode-permissions","passthrough-mode-permissions-aws","passthrough-mode-permissions-azure","passthrough-mode-permissions-gcp","passthrough-mode-permissions-rhosp","passthrough-mode-permissions-rhv","passthrough-mode-permissions-vsware","admin-credentials-root-secret-formats_cco-mode-passthrough","passthrough-mode-maintenance","manually-rotating-cloud-creds_cco-mode-passthrough","passthrough-mode-reduce-permissions","cco-mode-manual","manual-mode-sts-blurb","manually-maintained-credentials-upgrade_cco-mode-manual","additional-resources_cco-mode-manual","cco-mode-sts","sts-mode-about","sts-mode-installing","cco-ccoctl-configuring_cco-mode-sts","sts-mode-create-aws-resources-ccoctl","cco-ccoctl-creating-individually_cco-mode-sts","cco-ccoctl-creating-at-once_cco-mode-sts","sts-mode-installing-manual-run-installer_cco-mode-sts","sts-mode-installing-verifying_cco-mode-sts","/documentation/openshift_container_platform/4.8/html/authentication_and_authorization/managing-cloud-provider-credentials",{"title":4121,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":4122,"url":4123,"docTitle":4124,"sections":4125},"Networking",[],"/documentation/openshift_container_platform/4.8/html/networking/index","networking",[4126,4135,4141,4149,4162,4173,4208,4217,4225,4238,4247,4258,4294,4347,4419,4486,4561,4583,4622,4651,4658,4667,4679],{"title":4127,"visible":17,"weight":30,"urlFragment":4128,"anchor":23,"singlePageAnchor":4128,"subChapters":4129,"url":4134,"docTitle":4124},"Understanding networking","understanding-networking",[4130,4131,4132,4133],"nw-ne-openshift-dns_understanding-networking","nw-ne-openshift-ingress_understanding-networking","nw-ne-comparing-ingress-route_understanding-networking","nw-networking-glossary-terms_understanding-networking","/documentation/openshift_container_platform/4.8/html/networking/understanding-networking",{"title":4136,"visible":17,"weight":42,"urlFragment":4137,"anchor":23,"singlePageAnchor":4137,"subChapters":4138,"url":4140,"docTitle":4124},"Accessing hosts","accessing-hosts",[4139],"accessing-hosts-on-aws_accessing-hosts","/documentation/openshift_container_platform/4.8/html/networking/accessing-hosts",{"title":4142,"visible":17,"weight":53,"urlFragment":4143,"anchor":23,"singlePageAnchor":4143,"subChapters":4144,"url":4148,"docTitle":4124},"Networking Operators overview","networking-operators-overview",[4145,4146,4147],"networking-operators-overview-cluster-network-operator","networking-operators-overview-dns-operator","networking-operators-overview-ingress-operator","/documentation/openshift_container_platform/4.8/html/networking/networking-operators-overview",{"title":4150,"visible":17,"weight":75,"urlFragment":4151,"anchor":23,"singlePageAnchor":4151,"subChapters":4152,"url":4161,"docTitle":4124},"Cluster Network Operator in OpenShift Container Platform","cluster-network-operator",[4153,4154,4155,4156,4157,4158,4159,4160],"nw-cluster-network-operator_cluster-network-operator","nw-cno-view_cluster-network-operator","nw-cno-status_cluster-network-operator","nw-cno-logs_cluster-network-operator","nw-operator-cr_cluster-network-operator","nw-operator-cr-cno-object_cluster-network-operator","nw-operator-example-cr_cluster-network-operator","cluster-network-operator-additional-resources","/documentation/openshift_container_platform/4.8/html/networking/cluster-network-operator",{"title":4163,"visible":17,"weight":442,"urlFragment":4164,"anchor":23,"singlePageAnchor":4164,"subChapters":4165,"url":4172,"docTitle":4124},"DNS Operator in OpenShift Container Platform","dns-operator",[4166,4167,4168,4169,4170,4171],"dns-operator_dns-operator","nw-controlling-dns-pod-placement_dns-operator","nw-dns-view_dns-operator","nw-dns-forward_dns-operator","nw-dns-operator-status_dns-operator","nw-dns-operator-logs_dns-operator","/documentation/openshift_container_platform/4.8/html/networking/dns-operator",{"title":4174,"visible":17,"weight":460,"urlFragment":4175,"anchor":23,"singlePageAnchor":4175,"subChapters":4176,"url":4207,"docTitle":4124},"Ingress Operator in OpenShift Container Platform","configuring-ingress",[4177,4178,4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189,4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,1553],"nw-ne-openshift-ingress_configuring-ingress","nw-installation-ingress-config-asset_configuring-ingress","nw-ingress-controller-configuration-parameters_configuring-ingress","configuring-ingress-controller-tls","tls-profiles-understanding_configuring-ingress","tls-profiles-ingress-configuring_configuring-ingress","nw-ingress-controller-endpoint-publishing-strategies_configuring-ingress","nw-ingress-view_configuring-ingress","nw-ingress-operator-status_configuring-ingress","nw-ingress-operator-logs_configuring-ingress","nw-ingress-controller-status_configuring-ingress","configuring-ingress-controller","nw-ingress-setting-a-custom-default-certificate_configuring-ingress","nw-ingress-custom-default-certificate-remove_configuring-ingress","nw-ingress-controller-configuration_configuring-ingress","nw-configure-ingress-access-logging_configuring-ingress","nw-ingress-setting-thread-count_configuring-ingress","nw-ingress-sharding_configuring-ingress","nw-ingress-sharding-route-labels_configuring-ingress","nw-ingress-sharding-namespace-labels_configuring-ingress","nw-ingress-setting-internal-lb_configuring-ingress","nw-ingress-controller-configuration-gcp-global-access_configuring-ingress","nw-ingress-default-internal_configuring-ingress","nw-route-admission-policy_configuring-ingress","using-wildcard-routes_configuring-ingress","nw-using-ingress-forwarded_configuring-ingress","nw-http2-haproxy_configuring-ingress","nw-ingress-controller-configuration-proxy-protocol_configuring-ingress","nw-ingress-configuring-application-domain_configuring-ingress","nw-ingress-converting-http-header-case_configuring-ingress","/documentation/openshift_container_platform/4.8/html/networking/configuring-ingress",{"title":4209,"visible":17,"weight":475,"urlFragment":4210,"anchor":23,"singlePageAnchor":4210,"subChapters":4211,"url":4216,"docTitle":4124},"Verifying connectivity to an endpoint","verifying-connectivity-endpoint",[4212,4213,4214,4215],"nw-pod-network-connectivity-checks_verifying-connectivity-endpoint","nw-pod-network-connectivity-implementation_verifying-connectivity-endpoint","nw-pod-network-connectivity-check-object_verifying-connectivity-endpoint","nw-pod-network-connectivity-verify_verifying-connectivity-endpoint","/documentation/openshift_container_platform/4.8/html/networking/verifying-connectivity-endpoint",{"title":4218,"visible":17,"weight":876,"urlFragment":4219,"anchor":23,"singlePageAnchor":4219,"subChapters":4220,"url":4224,"docTitle":4124},"Configuring the node port service range","configuring-node-port-service-range",[4221,4222,4223],"configuring-node-port-service-range-prerequisites","nw-nodeport-service-range-edit_configuring-node-port-service-range","configuring-node-port-service-range-additional-resources","/documentation/openshift_container_platform/4.8/html/networking/configuring-node-port-service-range",{"title":4226,"visible":17,"weight":884,"urlFragment":4227,"anchor":23,"singlePageAnchor":4227,"subChapters":4228,"url":4237,"docTitle":4124},"Configuring IP failover","configuring-ipfailover",[4229,4230,4231,4232,4233,4234,4235,4236],"nw-ipfailover-environment-variables_configuring-ipfailover","nw-ipfailover-configuration_configuring-ipfailover","nw-ipfailover-virtual-ip-addresses-concept_configuring-ipfailover","nw-ipfailover-configuring-check-notify-scripts_configuring-ipfailover","nw-ipfailover-configuring-vrrp-preemption_configuring-ipfailover","nw-ipfailover-vrrp-ip-offset_configuring-ipfailover","nw-ipfailover-configuring-more-than-254_configuring-ipfailover","nw-ipfailover-cluster-ha-ingress_configuring-ipfailover","/documentation/openshift_container_platform/4.8/html/networking/configuring-ipfailover",{"title":4239,"visible":17,"weight":895,"urlFragment":4240,"anchor":23,"singlePageAnchor":4240,"subChapters":4241,"url":4246,"docTitle":4124},"Using the Stream Control Transmission Protocol (SCTP) on a bare metal cluster","using-sctp",[4242,4243,4244,4245],"nw-sctp-about_using-sctp","example_configurations_using-sctp","nw-sctp-enabling_using-sctp","nw-sctp-verifying_using-sctp","/documentation/openshift_container_platform/4.8/html/networking/using-sctp",{"title":4248,"visible":17,"weight":906,"urlFragment":4249,"anchor":23,"singlePageAnchor":4249,"subChapters":4250,"url":4257,"docTitle":4124},"Configuring PTP hardware","configuring-ptp",[4251,4252,4253,4254,4255,4256],"about-using-ptp-hardware","discover-ptp-devices_configuring-ptp","installing-ptp-operator_configuring-ptp","install-ptp-operator-cli_configuring-ptp","install-ptp-operator-web-console_configuring-ptp","configuring-linuxptp_configuring-ptp","/documentation/openshift_container_platform/4.8/html/networking/configuring-ptp",{"title":4259,"visible":17,"weight":913,"urlFragment":4260,"anchor":23,"singlePageAnchor":4260,"subChapters":4261,"url":4293,"docTitle":4124},"Network policy","network-policy",[4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292],"about-network-policy","nw-networkpolicy-about_about-network-policy","nw-networkpolicy-optimize_about-network-policy","about-network-policy-next-steps","about-network-policy-additional-resources","logging-network-policy","nw-networkpolicy-audit-concept_logging-network-policy","network-policy-audit-configuration","nw-networkpolicy-audit-configure_logging-network-policy","nw-networkpolicy-audit-enable_logging-network-policy","nw-networkpolicy-audit-disable_logging-network-policy","logging-network-policy-additional-resources","creating-network-policy","nw-networkpolicy-create_creating-network-policy","nw-networkpolicy-object_creating-network-policy","viewing-network-policy","nw-networkpolicy-view_viewing-network-policy","nw-networkpolicy-object_viewing-network-policy","editing-network-policy","nw-networkpolicy-edit_editing-network-policy","nw-networkpolicy-object_editing-network-policy","editing-network-policy-additional-resources","deleting-network-policy","nw-networkpolicy-delete_deleting-network-policy","default-network-policy","modifying-template-for-new-projects_default-network-policy","nw-networkpolicy-project-defaults_default-network-policy","multitenant-network-policy","nw-networkpolicy-multitenant-isolation_multitenant-network-policy","multitenant-network-policy-next-steps","multitenant-network-policy-additional-resources","/documentation/openshift_container_platform/4.8/html/networking/network-policy",{"title":4295,"visible":17,"weight":922,"urlFragment":4296,"anchor":23,"singlePageAnchor":4296,"subChapters":4297,"url":4346,"docTitle":4124},"Multiple networks","multiple-networks",[4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327,4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345],"understanding-multiple-networks","additional-network-considerations","additional-networks-provided","configuring-additional-network","configuring-additional-network_approaches-managing-additional-network","configuring-additional-network_configuration-additional-network-attachment","configuring-additional-network_configuration-additional-network-cno","configuring-additional-network_configuration-additional-network-yaml","configuring-additional-network_configuration-additional-network-types","nw-multus-bridge-object_configuring-additional-network","nw-multus-bridge-config-example_configuring-additional-network","nw-multus-host-device-object_configuring-additional-network","nw-multus-hostdev-config-example_configuring-additional-network","nw-multus-ipvlan-object_configuring-additional-network","nw-multus-ipvlan-config-example_configuring-additional-network","nw-multus-macvlan-object_configuring-additional-network","nw-multus-macvlan-config-example_configuring-additional-network","nw-multus-ipam-object_configuring-additional-network","nw-multus-static_configuring-additional-network","nw-multus-dhcp_configuring-additional-network","nw-multus-whereabouts_configuring-additional-network","nw-multus-create-network_configuring-additional-network","nw-multus-create-network-apply_configuring-additional-network","about-virtual-routing-and-forwarding","cnf-about-virtual-routing-and-forwarding_about-virtual-routing-and-forwarding","cnf-benefits-secondary-networks-telecommunications-operators_about-virtual-routing-and-forwarding","configuring-multi-network-policy","nw-multi-network-policy-differences_configuring-multi-network-policy","nw-multi-network-policy-enable_configuring-multi-network-policy","configuring-multi-network-policy_working-with-multi-network-policy","configuring-multi-network-policy_prerequisites","nw-networkpolicy-create_configuring-multi-network-policy","nw-networkpolicy-edit_configuring-multi-network-policy","nw-networkpolicy-view_configuring-multi-network-policy","nw-networkpolicy-delete_configuring-multi-network-policy","configuring-multi-network-policy_additional-resources","attaching-pod","nw-multus-add-pod_attaching-pod","nw-multus-advanced-annotations_attaching-pod","removing-pod","nw-multus-remove-pod_removing-pod","edit-additional-network","nw-multus-edit-network_edit-additional-network","remove-additional-network","nw-multus-delete-network_remove-additional-network","assigning-a-secondary-network-to-a-vrf","cnf-assigning-a-secondary-network-to-a-vrf_assigning-a-secondary-network-to-a-vrf","cnf-creating-an-additional-network-attachment-with-the-cni-vrf-plug-in_assigning-a-secondary-network-to-a-vrf","/documentation/openshift_container_platform/4.8/html/networking/multiple-networks",{"title":4348,"visible":17,"weight":2806,"urlFragment":4349,"anchor":23,"singlePageAnchor":4349,"subChapters":4350,"url":4418,"docTitle":4124},"Hardware networks","hardware-networks",[4351,4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417],"about-sriov","components-sr-iov-network-devices","nw-sriov-supported-platforms_about-sriov","supported-devices_about-sriov","discover-sr-iov-devices_about-sriov","example-sriovnetworknodestate_about-sriov","example-vf-use-in-pod_about-sriov","nw-sriov-app-netutil_about-sriov","nw-sriov-hugepages_about-sriov","about-sriov-next-steps","installing-sriov-operator","installing-sr-iov-operator_installing-sriov-operator","install-operator-cli_installing-sriov-operator","install-operator-web-console_installing-sriov-operator","installing-sriov-operator-next-steps","configuring-sriov-operator","nw-sriov-configuring-operator_configuring-sriov-operator","about-network-resource-injector_configuring-sriov-operator","about-sr-iov-operator-admission-control-webhook_configuring-sriov-operator","about-custom-node-selectors_configuring-sriov-operator","disable-enable-network-resource-injector_configuring-sriov-operator","disable-enable-sr-iov-operator-admission-control-webhook_configuring-sriov-operator","configuring-custom-nodeselector_configuring-sriov-operator","configuring-sriov-operator-next-steps","configuring-sriov-device","nw-sriov-networknodepolicy-object_configuring-sriov-device","sr-iov-network-node-configuration-examples_configuring-sriov-device","nw-sriov-nic-partitioning_configuring-sriov-device","nw-sriov-configuring-device_configuring-sriov-device","nw-sriov-troubleshooting_configuring-sriov-device","cnf-assigning-a-sriov-network-to-a-vrf_configuring-sriov-device","cnf-creating-an-additional-sriov-network-with-vrf-plug-in_configuring-sriov-device","configuring-sriov-device-next-steps","configuring-sriov-net-attach","nw-sriov-network-object_configuring-sriov-net-attach","nw-multus-ipam-object_configuring-sriov-net-attach","nw-multus-static_configuring-sriov-net-attach","nw-multus-dhcp_configuring-sriov-net-attach","nw-multus-whereabouts_configuring-sriov-net-attach","nw-sriov-network-attachment_configuring-sriov-net-attach","configuring-sriov-net-attach-next-steps","configuring-sriov-net-attach-additional-resources","configuring-sriov-ib-attach","nw-sriov-ibnetwork-object_configuring-sriov-ib-attach","nw-multus-ipam-object_configuring-sriov-ib-attach","nw-multus-static_configuring-sriov-ib-attach","nw-multus-dhcp_configuring-sriov-ib-attach","nw-multus-whereabouts_configuring-sriov-ib-attach","nw-sriov-network-attachment_configuring-sriov-ib-attach","configuring-sriov-ib-attach-next-steps","configuring-sriov-ib-attach-additional-resources","add-pod","nw-sriov-runtime-config_configuring-sr-iov","runtime-config-ethernet_configuring-sr-iov","runtime-config-infiniband_configuring-sr-iov","nw-multus-add-pod_configuring-sr-iov","nw-sriov-topology-manager_configuring-sr-iov","add-pod-additional-resources","using-sriov-multicast","nw-high-performance-multicast_using-sriov-multicast","nw-using-an-sriov-interface-for-multicast_using-sriov-multicast","using-dpdk-and-rdma","example-vf-use-in-dpdk-mode-intel_using-dpdk-and-rdma","example-vf-use-in-dpdk-mode-mellanox_using-dpdk-and-rdma","example-vf-use-in-rdma-mode-mellanox_using-dpdk-and-rdma","uninstalling-sriov-operator","nw-sriov-operator-uninstall_uninstalling-sr-iov-operator","/documentation/openshift_container_platform/4.8/html/networking/hardware-networks",{"title":4420,"visible":17,"weight":3071,"urlFragment":4421,"anchor":23,"singlePageAnchor":4421,"subChapters":4422,"url":4485,"docTitle":4124},"OpenShift SDN default CNI network provider","openshift-sdn-default-cni-network-provider",[4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,1013,4478,4479,4480,4481,4482,4483,4484],"about-openshift-sdn","nw-openshift-sdn-modes_about-openshift-sdn","nw-ovn-kubernetes-matrix_about-openshift-sdn","assigning-egress-ips","nw-egress-ips-about_egress-ips","considerations-automatic-egress-ips","considerations-manual-egress-ips","nw-egress-ips-automatic_egress-ips","nw-egress-ips-static_egress-ips","configuring-egress-firewall","nw-egressnetworkpolicy-about_openshift-sdn-egress-firewall","limitations-of-an-egress-firewall_openshift-sdn-egress-firewall","policy-rule-order_openshift-sdn-egress-firewall","domain-name-server-resolution_openshift-sdn-egress-firewall","nw-egressnetworkpolicy-object_openshift-sdn-egress-firewall","egressnetworkpolicy-rules_openshift-sdn-egress-firewall","egressnetworkpolicy-example_openshift-sdn-egress-firewall","nw-networkpolicy-create_openshift-sdn-egress-firewall","openshift-sdn-viewing-egress-firewall","nw-egressnetworkpolicy-view_openshift-sdn-viewing-egress-firewall","editing-egress-firewall","nw-egressnetworkpolicy-edit_openshift-sdn-egress-firewall","removing-egress-firewall","nw-egressnetworkpolicy-delete_openshift-sdn-egress-firewall","using-an-egress-router","nw-egress-router-about_using-an-egress-router","nw-egress-router-about-modes_using-an-egress-router","nw-egress-router-about-router-pod-implementation_using-an-egress-router","nw-egress-router-about-deployments_using-an-egress-router","nw-egress-router-about-failover_using-an-egress-router","using-an-egress-router-additional-resources","deploying-egress-router-layer3-redirection","nw-egress-router-pod_deploying-egress-router-layer3-redirection","nw-egress-router-dest-var_deploying-egress-router-layer3-redirection","nw-egress-router-redirect-mode_deploying-egress-router-layer3-redirection","deploying-egress-router-layer3-redirection-additional-resources","deploying-egress-router-http-redirection","nw-egress-router-pod_deploying-egress-router-http-redirection","nw-egress-router-dest-var_deploying-egress-router-http-redirection","nw-egress-router-http-proxy-mode_deploying-egress-router-http-redirection","deploying-egress-router-http-redirection-additional-resources","deploying-egress-router-dns-redirection","nw-egress-router-pod_deploying-egress-router-dns-redirection","nw-egress-router-dest-var_deploying-egress-router-dns-redirection","nw-egress-router-dns-mode_deploying-egress-router-dns-redirection","deploying-egress-router-dns-redirection-additional-resources","configuring-egress-router-configmap","configuring-egress-router-configmap_configuring-egress-router-configmap","configuring-egress-router-configmap-additional-resources","enabling-multicast","nw-about-multicast_openshift-sdn-enabling-multicast","nw-enabling-multicast_openshift-sdn-enabling-multicast","disabling-multicast","nw-disabling-multicast_openshift-sdn-disabling-multicast","configuring-multitenant-isolation","nw-multitenant-joining_multitenant-isolation","nw-multitenant-isolation_multitenant-isolation","nw-multitenant-global_multitenant-isolation","configuring-kube-proxy","nw-kube-proxy-sync_configuring-kube-proxy","nw-kube-proxy-config_configuring-kube-proxy","nw-kube-proxy-configuring_configuring-kube-proxy","/documentation/openshift_container_platform/4.8/html/networking/openshift-sdn-default-cni-network-provider",{"title":4487,"visible":17,"weight":3339,"urlFragment":4488,"anchor":23,"singlePageAnchor":4488,"subChapters":4489,"url":4560,"docTitle":4124},"OVN-Kubernetes default CNI network provider","ovn-kubernetes-default-cni-network-provider",[4490,4491,4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559],"about-ovn-kubernetes","nw-ovn-kubernetes-features_about-ovn-kubernetes","nw-ovn-kubernetes-matrix_about-ovn-kubernetes","nw-ovn-kubernetes-limitations_about-ovn-kubernetes","migrate-from-openshift-sdn","nw-ovn-kubernetes-migration-about_migrate-from-openshift-sdn","considerations-migrating-ovn-kubernetes-network-provider_migrate-from-openshift-sdn","how-the-migration-process-works_migrate-from-openshift-sdn","nw-ovn-kubernetes-migration_migrate-from-openshift-sdn","migrate-from-openshift-sdn-additional-resources","rollback-to-openshift-sdn","nw-ovn-kubernetes-rollback_rollback-to-openshift-sdn","converting-to-dual-stack","nw-dual-stack-convert_converting-to-dual-stack","about-ipsec-ovn","nw-ovn-ipsec-traffic_about-ipsec-ovn","network-connectivity-requirements-when-ipsec-is-enabled","nw-ovn-ipsec-encryption_about-ipsec-ovn","nw-ovn-ipsec-certificates_about-ipsec-ovn","configuring-egress-firewall-ovn","nw-egressnetworkpolicy-about_configuring-egress-firewall-ovn","limitations-of-an-egress-firewall_configuring-egress-firewall-ovn","policy-rule-order_configuring-egress-firewall-ovn","domain-name-server-resolution_configuring-egress-firewall-ovn","nw-egressnetworkpolicy-object_configuring-egress-firewall-ovn","egressnetworkpolicy-rules_configuring-egress-firewall-ovn","egressnetworkpolicy-example_configuring-egress-firewall-ovn","nw-networkpolicy-create_configuring-egress-firewall-ovn","viewing-egress-firewall-ovn","nw-egressnetworkpolicy-view_viewing-egress-firewall-ovn","editing-egress-firewall-ovn","nw-egressnetworkpolicy-edit_editing-egress-firewall-ovn","removing-egress-firewall-ovn","nw-egressnetworkpolicy-delete_removing-egress-firewall-ovn","configuring-egress-ips-ovn","nw-egress-ips-about_configuring-egress-ips-ovn","nw-egress-ips-platform-support_configuring-egress-ips-ovn","nw-egress-ips-considerations_configuring-egress-ips-ovn","nw-egress-ips-node-assignment_configuring-egress-ips-ovn","nw-egress-ips-node-architecture_configuring-egress-ips-ovn","nw-egress-ips-object_configuring-egress-ips-ovn","nw-egress-ips-node_configuring-egress-ips-ovn","configuring-egress-ips-next-steps","configuring-egress-ips-additional-resources","assigning-egress-ips-ovn","nw-egress-ips-assign_assigning-egress-ips-ovn","assigning-egress-ips-additional-resources","using-an-egress-router-ovn","nw-egress-router-about_using-an-egress-router-ovn","nw-egress-router-about-modes_using-an-egress-router-ovn","nw-egress-router-about-router-pod-implementation_using-an-egress-router-ovn","nw-egress-router-about-deployments_using-an-egress-router-ovn","nw-egress-router-about-failover_using-an-egress-router-ovn","using-an-egress-router-ovn-additional-resources","deploying-egress-router-ovn-redirection","nw-egress-router-ovn-cr_deploying-egress-router-ovn-redirection","nw-egress-router-redirect-mode-ovn_deploying-egress-router-ovn-redirection","nw-ovn-kubernetes-enabling-multicast","nw-about-multicast_ovn-kubernetes-enabling-multicast","nw-enabling-multicast_ovn-kubernetes-enabling-multicast","nw-ovn-kubernetes-disabling-multicast","nw-disabling-multicast_ovn-kubernetes-disabling-multicast","tracking-network-flows","nw-network-flows-object_tracking-network-flows","nw-network-flows-create_tracking-network-flows","nw-network-flows-delete_tracking-network-flows","additional-resources_tracking-network-flows","configuring-hybrid-networking","configuring-hybrid-ovnkubernetes_configuring-hybrid-networking","configuring-hybrid-networking-additional-resources","/documentation/openshift_container_platform/4.8/html/networking/ovn-kubernetes-default-cni-network-provider",{"title":4562,"visible":17,"weight":3395,"urlFragment":4563,"anchor":23,"singlePageAnchor":4563,"subChapters":4564,"url":4582,"docTitle":4124},"Configuring Routes","configuring-routes",[4565,4566,4567,4568,4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581],"route-configuration","nw-creating-a-route_route-configuration","nw-configuring-route-timeouts_route-configuration","nw-enabling-hsts_route-configuration","nw-throughput-troubleshoot_route-configuration","nw-using-cookies-keep-route-statefulness_route-configuration","nw-annotating-a-route-with-a-cookie-name_route-configuration","nw-path-based-routes_route-configuration","nw-route-specific-annotations_route-configuration","nw-route-admission-policy_route-configuration","nw-ingress-creating-a-route-via-an-ingress_route-configuration","creating-edge-route-with-default-certificate_route-configuration","nw-router-configuring-dual-stack_route-configuration","configuring-default-certificate","nw-ingress-creating-a-reencrypt-route-with-a-custom-certificate_secured-routes","nw-ingress-creating-an-edge-route-with-a-custom-certificate_secured-routes","nw-ingress-creating-a-passthrough-route_secured-routes","/documentation/openshift_container_platform/4.8/html/networking/configuring-routes",{"title":4584,"visible":17,"weight":3421,"urlFragment":4585,"anchor":23,"singlePageAnchor":4585,"subChapters":4586,"url":4621,"docTitle":4124},"Configuring ingress cluster traffic","configuring-ingress-cluster-traffic",[4587,4588,1024,4589,4590,4591,4592,4593,4594,4595,4596,4597,1045,4598,4599,4600,4601,1605,4602,4603,1096,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,4614,4615,4616,4617,1121,4618,4619,4620],"overview-traffic","configuring-externalip","nw-externalip-about_configuring-externalip","configuration-externalip_configuring-externalip","restrictions-on-ip-assignment_configuring-externalip","example-policy-objects_configuring-externalip","nw-externalip-object_configuring-externalip","nw-externalip-configuring_configuring-externalip","configuring-externalip-next-steps","configuring-ingress-cluster-traffic-ingress-controller","nw-using-ingress-and-routes_configuring-ingress-cluster-traffic-ingress-controller","nw-creating-project-and-service_configuring-ingress-cluster-traffic-ingress-controller","nw-exposing-service_configuring-ingress-cluster-traffic-ingress-controller","nw-ingress-sharding-route-labels_configuring-ingress-cluster-traffic-ingress-controller","nw-ingress-sharding-namespace-labels_configuring-ingress-cluster-traffic-ingress-controller","configuring-ingress-cluster-traffic-load-balancer","nw-using-load-balancer-getting-traffic_configuring-ingress-cluster-traffic-load-balancer","nw-creating-project-and-service_configuring-ingress-cluster-traffic-load-balancer","nw-exposing-service_configuring-ingress-cluster-traffic-load-balancer","nw-create-load-balancer-service_configuring-ingress-cluster-traffic-load-balancer","configuring-ingress-cluster-traffic-aws-network-load-balancer","nw-aws-replacing-clb-with-nlb_configuring-ingress-cluster-traffic-aws-network-load-balancer","nw-aws-nlb-existing-cluster_configuring-ingress-cluster-traffic-aws-network-load-balancer","nw-aws-nlb-new-cluster_configuring-ingress-cluster-traffic-aws-network-load-balancer","configuring-ingress-cluster-traffic-aws-network-load-balancer-addtl-resources","configuring-ingress-cluster-traffic-service-external-ip","configuring-ingress-cluster-traffic-service-external-ip-prerequisites","nw-service-externalip-create_configuring-ingress-cluster-traffic-service-external-ip","configuring-ingress-cluster-traffic-service-external-ip-additional-resources","configuring-ingress-cluster-traffic-nodeport","nw-using-nodeport_configuring-ingress-cluster-traffic-nodeport","nw-creating-project-and-service_configuring-ingress-cluster-traffic-nodeport","nw-exposing-service_configuring-ingress-cluster-traffic-nodeport","configuring-ingress-cluster-traffic-nodeport-additional-resources","/documentation/openshift_container_platform/4.8/html/networking/configuring-ingress-cluster-traffic",{"title":4623,"visible":17,"weight":3436,"urlFragment":4624,"anchor":23,"singlePageAnchor":4624,"subChapters":4625,"url":4650,"docTitle":4124},"Kubernetes NMState","kubernetes-nmstate",[4626,4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649],"k8s-nmstate-about-the-k8s-nmstate-operator","installing-the-kubernetes-nmstate-operator_k8s-nmstate-operator","k8s-nmstate-observing-node-network-state","virt-about-nmstate_k8s-nmstate-observing-node-network-state","virt-viewing-network-state-of-node_k8s-nmstate-observing-node-network-state","k8s-nmstate-updating-node-network-config","virt-about-nmstate_k8s_nmstate-updating-node-network-config","virt-creating-interface-on-nodes_k8s_nmstate-updating-node-network-config","virt-confirming-policy-updates-on-nodes_k8s_nmstate-updating-node-network-config","virt-removing-interface-from-nodes_k8s_nmstate-updating-node-network-config","virt-nmstate-example-policy-configurations","virt-example-bridge-nncp_k8s_nmstate-updating-node-network-config","virt-example-vlan-nncp_k8s_nmstate-updating-node-network-config","virt-example-bond-nncp_k8s_nmstate-updating-node-network-config","virt-example-ethernet-nncp_k8s_nmstate-updating-node-network-config","virt-example-nmstate-multiple-interfaces_k8s_nmstate-updating-node-network-config","virt-example-nmstate-IP-management_k8s_nmstate-updating-node-network-config","virt-example-nmstate-IP-management-static_k8s_nmstate-updating-node-network-config","virt-example-nmstate-IP-management-no-ip_k8s_nmstate-updating-node-network-config","virt-example-nmstate-IP-management-dhcp_k8s_nmstate-updating-node-network-config","virt-example-nmstate-IP-management-dns_k8s_nmstate-updating-node-network-config","virt-example-nmstate-IP-management-static-routing_k8s_nmstate-updating-node-network-config","k8s-nmstate-troubleshooting-node-network","virt-troubleshooting-incorrect-policy-config_k8s-nmstate-troubleshooting-node-network","/documentation/openshift_container_platform/4.8/html/networking/kubernetes-nmstate",{"title":4652,"visible":17,"weight":3448,"urlFragment":4653,"anchor":23,"singlePageAnchor":4653,"subChapters":4654,"url":4657,"docTitle":4124},"Configuring the cluster-wide proxy","enable-cluster-wide-proxy",[1149,4655,4656],"nw-proxy-configure-object_config-cluster-wide-proxy","nw-proxy-remove_config-cluster-wide-proxy","/documentation/openshift_container_platform/4.8/html/networking/enable-cluster-wide-proxy",{"title":4659,"visible":17,"weight":4660,"urlFragment":4661,"anchor":23,"singlePageAnchor":4661,"subChapters":4662,"url":4666,"docTitle":4124},"Configuring a custom PKI",22,"configuring-a-custom-pki",[4663,4664,4665],"installation-configure-proxy_configuring-a-custom-pki","nw-proxy-configure-object_configuring-a-custom-pki","certificate-injection-using-operators_configuring-a-custom-pki","/documentation/openshift_container_platform/4.8/html/networking/configuring-a-custom-pki",{"title":4668,"visible":17,"weight":4669,"urlFragment":4670,"anchor":23,"singlePageAnchor":4670,"subChapters":4671,"url":4678,"docTitle":4124},"Load balancing on RHOSP",23,"load-balancing-openstack",[4672,4673,4674,4675,4676,4677],"installation-osp-kuryr-octavia-configure_load-balancing-openstack","installation-osp-api-octavia_load-balancing-openstack","installation-osp-api-scaling_load-balancing-openstack","installation-osp-kuryr-api-scaling_load-balancing-openstack","installation-osp-kuryr-octavia-scale_load-balancing-openstack","nw-osp-configuring-external-load-balancer_load-balancing-openstack","/documentation/openshift_container_platform/4.8/html/networking/load-balancing-openstack",{"title":4680,"visible":17,"weight":4681,"urlFragment":4682,"anchor":23,"singlePageAnchor":4682,"subChapters":4683,"url":4687,"docTitle":4124},"Associating secondary interfaces metrics to network attachments",24,"associating-secondary-interfaces-metrics-to-network-attachments",[4684,4685,4686],"cnf-associating-secondary-interfaces-metrics-to-network-attachments_secondary-interfaces-metrics","cnf-associating-secondary-interfaces-metrics-to-network-attachments-network-metrics-daemon_secondary-interfaces-metrics","cnf-associating-secondary-interfaces-metrics-with-network-name_secondary-interfaces-metrics","/documentation/openshift_container_platform/4.8/html/networking/associating-secondary-interfaces-metrics-to-network-attachments",{"title":4689,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":4690,"url":4691,"docTitle":4692,"sections":4693},"Registry",[],"/documentation/openshift_container_platform/4.8/html/registry/index","registry",[4694,4706,4718,4758,4768],{"title":4695,"visible":17,"weight":30,"urlFragment":4696,"anchor":23,"singlePageAnchor":4696,"subChapters":4697,"url":4705,"docTitle":4692},"OpenShift Container Platform registry overview","registry-overview",[4698,4699,4700,4701,4702,4703,4704],"openshift-registry-common-terms_registry-overview","registry-integrated-openshift-registry_registry-overview","registry-third-party-registries_registry-overview","authentication_registry-overview","registry-authentication_registry-overview","registry-quay-overview_registry-overview","registry-authentication-enabled-registry-overview_registry-overview","/documentation/openshift_container_platform/4.8/html/registry/registry-overview",{"title":4707,"visible":17,"weight":42,"urlFragment":4708,"anchor":23,"singlePageAnchor":4708,"subChapters":4709,"url":4717,"docTitle":4692},"Image Registry Operator in OpenShift Container Platform","configuring-registry-operator",[4710,4711,4712,4713,4714,4715,4716,1553],"image-registry-on-cloud","image-registry-on-bare-metal-vsphere","registry-removed_configuring-registry-operator","registry-operator-configuration-resource-overview_configuring-registry-operator","registry-operator-default-crd_configuring-registry-operator","images-configuration-cas_configuring-registry-operator","registry-operator-config-resources-storage-credentials_configuring-registry-operator","/documentation/openshift_container_platform/4.8/html/registry/configuring-registry-operator",{"title":4719,"visible":17,"weight":53,"urlFragment":4720,"anchor":23,"singlePageAnchor":4720,"subChapters":4721,"url":4757,"docTitle":4692},"Setting up and configuring the registry","setting-up-and-configuring-the-registry",[4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748,4749,4750,4751,4752,4753,4754,4755,4756],"configuring-registry-storage-aws-user-infrastructure","registry-operator-config-resources-secret-aws_configuring-registry-storage-aws-user-infrastructure","registry-configuring-storage-aws-user-infra_configuring-registry-storage-aws-user-infrastructure","registry-operator-configuration-resource-overview-aws-s3_configuring-registry-storage-aws-user-infrastructure","configuring-registry-storage-gcp-user-infrastructure","registry-operator-config-resources-secret-gcp_configuring-registry-storage-gcp-user-infrastructure","registry-configuring-storage-gcp-user-infra_configuring-registry-storage-gcp-user-infrastructure","registry-operator-configuration-resource-overview-gcp-gcs_configuring-registry-storage-gcp-user-infrastructure","configuring-registry-storage-openstack-user-infrastructure","registry-configuring-registry-storage-swift-trust_configuring-registry-storage-openstack-user-infrastructure","registry-operator-config-resources-secret-openstack_configuring-registry-storage-openstack-user-infrastructure","registry-configuring-storage-openstack-user-infra_configuring-registry-storage-openstack-user-infrastructure","registry-operator-configuration-resource-overview-openstack-swift_configuring-registry-storage-openstack-user-infrastructure","configuring-registry-storage-azure-user-infrastructure","registry-operator-config-resources-secret-azure_configuring-registry-storage-azure-user-infrastructure","registry-configuring-storage-azure-user-infra_configuring-registry-storage-azure-user-infrastructure","registry-configuring-storage-azure-gov-cloud_configuring-registry-storage-azure-user-infrastructure","configuring-registry-storage-openstack","installation-registry-osp-creating-custom-pvc_configuring-registry-storage-openstack","configuring-registry-storage-baremetal","registry-removed_configuring-registry-storage-baremetal","registry-change-management-state_configuring-registry-storage-baremetal","installation-registry-storage-config_configuring-registry-storage-baremetal","registry-configuring-storage-baremetal_configuring-registry-storage-baremetal","installation-registry-storage-non-production_configuring-registry-storage-baremetal","installation-registry-storage-block-recreate-rollout-bare-metal_configuring-registry-storage-baremetal","configuring-registry-storage-baremetal-addtl-resources","configuring-registry-storage-vsphere","registry-removed_configuring-registry-storage-vsphere","registry-change-management-state_configuring-registry-storage-vsphere","installation-registry-storage-config_configuring-registry-storage-vsphere","registry-configuring-storage-vsphere_configuring-registry-storage-vsphere","installation-registry-storage-non-production_configuring-registry-storage-vsphere","installation-registry-storage-block-recreate-rollout_configuring-registry-storage-vsphere","configuring-registry-storage-vsphere-addtl-resources","/documentation/openshift_container_platform/4.8/html/registry/setting-up-and-configuring-the-registry",{"title":4759,"visible":17,"weight":75,"urlFragment":4760,"anchor":23,"singlePageAnchor":4760,"subChapters":4761,"url":4767,"docTitle":4692},"Accessing the registry","accessing-the-registry",[1013,4762,4763,4764,4765,4766],"registry-accessing-directly_accessing-the-registry","checking-the-status-of-registry-pods_accessing-the-registry","registry-viewing-logs_accessing-the-registry","registry-accessing-metrics_accessing-the-registry","accessing-the-registry-additional-resources","/documentation/openshift_container_platform/4.8/html/registry/accessing-the-registry",{"title":4769,"visible":17,"weight":442,"urlFragment":4770,"anchor":23,"singlePageAnchor":4770,"subChapters":4771,"url":4774,"docTitle":4692},"Exposing the registry","securing-exposing-registry",[4772,4773],"registry-exposing-default-registry-manually_securing-exposing-registry","registry-exposing-secure-registry-manually_securing-exposing-registry","/documentation/openshift_container_platform/4.8/html/registry/securing-exposing-registry",{"title":4776,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":4777,"url":4778,"docTitle":4779,"sections":4780},"Post-installation configuration",[],"/documentation/openshift_container_platform/4.8/html/post-installation_configuration/index","post-installation_configuration",[4781,4787,4796,4819,4875,4961,4998,5027,5062,5070],{"title":4782,"visible":17,"weight":30,"urlFragment":4783,"anchor":23,"singlePageAnchor":4783,"subChapters":4784,"url":4786,"docTitle":4779},"Post-installation configuration overview","post-install-configuration-overview",[4785],"post-install-tasks","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-configuration-overview",{"title":4788,"visible":17,"weight":42,"urlFragment":4789,"anchor":23,"singlePageAnchor":4789,"subChapters":4790,"url":4795,"docTitle":4779},"Configuring a private cluster","configuring-private-cluster",[4791,4792,4793,4794],"private-clusters-about_configuring-private-cluster","private-clusters-setting-dns-private_configuring-private-cluster","private-clusters-setting-ingress-private_configuring-private-cluster","private-clusters-setting-api-private_configuring-private-cluster","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/configuring-private-cluster",{"title":4797,"visible":17,"weight":53,"urlFragment":4798,"anchor":23,"singlePageAnchor":4798,"subChapters":4799,"url":4818,"docTitle":4779},"Post-installation machine configuration tasks","post-install-machine-configuration-tasks",[4800,4801,4802,4803,4804,4805,4806,4807,4808,4809,4810,4811,4812,4813,4814,4815,4816,4817],"understanding-the-machine-config-operator","machine-config-operator_post-install-machine-configuration-tasks","machine-config-overview-post-install-machine-configuration-tasks","what-can-you-change-with-machine-configs","project-2","checking-mco-status_post-install-machine-configuration-tasks","using-machineconfigs-to-change-machines","installation-special-config-chrony_post-install-machine-configuration-tasks","nodes-nodes-kernel-arguments_post-install-machine-configuration-tasks","rhcos-enabling-multipath-day-2_post-install-machine-configuration-tasks","nodes-nodes-rtkernel-arguments_post-install-machine-configuration-tasks","machineconfig-modify-journald_post-install-machine-configuration-tasks","rhcos-add-extensions_post-install-machine-configuration-tasks","rhcos-load-firmware-blobs_post-install-machine-configuration-tasks","configuring-machines-with-custom-resources","create-a-kubeletconfig-crd-to-edit-kubelet-parameters_post-install-machine-configuration-tasks","create-a-containerruntimeconfig_post-install-machine-configuration-tasks","set-the-default-max-container-root-partition-size-for-overlay-with-crio_post-install-machine-configuration-tasks","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-machine-configuration-tasks",{"title":4820,"visible":17,"weight":75,"urlFragment":4821,"anchor":23,"singlePageAnchor":4821,"subChapters":4822,"url":4874,"docTitle":4779},"Post-installation cluster tasks","post-install-cluster-tasks",[4823,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,4869,4870,4871,4872,4873],"available_cluster_customizations","configuration-resources_post-install-cluster-tasks","operator-configuration-resources_post-install-cluster-tasks","additional-configuration-resources_post-install-cluster-tasks","informational-resources_post-install-cluster-tasks","images-update-global-pull-secret_post-install-cluster-tasks","post-install-adjust-worker-nodes","differences-between-machinesets-and-machineconfigpool_post-install-cluster-tasks","machineset-manually-scaling_post-install-cluster-tasks","machineset-delete-policy_post-install-cluster-tasks","nodes-scheduler-node-selectors-cluster_post-install-cluster-tasks","post-install-creating-infrastructure-machinesets-production","machineset-creating_post-install-cluster-tasks","creating-an-infra-node_post-install-cluster-tasks","creating-infra-machines_post-install-cluster-tasks","assigning-machine-set-resources-to-infra-nodes","binding-infra-node-workloads-using-taints-tolerations_post-install-cluster-tasks","moving-resources-to-infrastructure-machinesets","infrastructure-moving-router_post-install-cluster-tasks","infrastructure-moving-registry_post-install-cluster-tasks","infrastructure-moving-monitoring_post-install-cluster-tasks","infrastructure-moving-logging_post-install-cluster-tasks","cluster-autoscaler-about_post-install-cluster-tasks","cluster-autoscaler-cr_post-install-cluster-tasks","ClusterAutoscaler-deploying_post-install-cluster-tasks","machine-autoscaler-about_post-install-cluster-tasks","machine-autoscaler-cr_post-install-cluster-tasks","MachineAutoscaler-deploying_post-install-cluster-tasks","post-install-tp-tasks","nodes-cluster-enabling-features-about_post-install-cluster-tasks","nodes-cluster-enabling-features-console_post-install-cluster-tasks","nodes-cluster-enabling-features-cli_post-install-cluster-tasks","post-install-etcd-tasks","about-etcd_post-install-cluster-tasks","enabling-etcd-encryption_post-install-cluster-tasks","disabling-etcd-encryption_post-install-cluster-tasks","backing-up-etcd-data_post-install-cluster-tasks","etcd-defrag_post-install-cluster-tasks","dr-scenario-2-restoring-cluster-state_post-install-cluster-tasks","dr-scenario-cluster-state-issues_post-install-cluster-tasks","post-install-pod-disruption-budgets","nodes-pods-configuring-pod-distruption-about_post-install-cluster-tasks","nodes-pods-pod-disruption-configuring_post-install-cluster-tasks","post-install-rotate-remove-cloud-creds","manually-rotating-cloud-creds_post-install-cluster-tasks","manually-removing-cloud-creds_post-install-cluster-tasks","post-install-must-gather-disconnected","installation-images-samples-disconnected-mirroring-assist_post-install-cluster-tasks","installation-restricted-network-samples_post-install-cluster-tasks","installation-preparing-restricted-cluster-to-gather-support-data_post-install-cluster-tasks","images-cluster-sample-imagestream-import_post-install-cluster-tasks","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-cluster-tasks",{"title":4876,"visible":17,"weight":442,"urlFragment":4877,"anchor":23,"singlePageAnchor":4877,"subChapters":4878,"url":4960,"docTitle":4779},"Post-installation node tasks","post-install-node-tasks",[4879,4880,4881,4882,4883,4884,4885,4886,4887,4888,1013,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4955,4956,4957,4958,4959],"post-install-config-adding-rhel-compute","rhel-compute-overview_post-install-node-tasks","rhel-compute-requirements_post-install-node-tasks","csr-management_post-install-node-tasks","rhel-preparing-playbook-machine_post-install-node-tasks","rhel-preparing-node_post-install-node-tasks","rhel-adding-node_post-install-node-tasks","rhel-ansible-parameters_post-install-node-tasks","rhel-removing-rhcos_post-install-node-tasks","post-install-config-adding-fcos-compute","machine-user-infra-machines-iso_post-install-node-tasks","machine-user-infra-machines-pxe_post-install-node-tasks","installation-approve-csrs_post-install-node-tasks","post-installation-config-deploying-machine-health-checks","machine-health-checks-about_post-install-node-tasks","machine-health-checks-limitations_post-install-node-tasks","machine-health-checks-resource_post-install-node-tasks","machine-health-checks-short-circuiting_post-install-node-tasks","setting-literal-maxunhealthy-literal-by-using-an-absolute-value","setting-literal-maxunhealthy-literal-by-using-percentages","machine-health-checks-creating_post-install-node-tasks","machineset-manually-scaling_post-install-node-tasks","differences-between-machinesets-and-machineconfigpool_post-install-node-tasks","recommended-node-host-practices_post-install-node-tasks","create-a-kubeletconfig-crd-to-edit-kubelet-parameters_post-install-node-tasks","modify-unavailable-workers_post-install-node-tasks","master-node-sizing_post-install-node-tasks","seting_up_cpu_manager_post-install-node-tasks","post-install-huge-pages","what-huge-pages-do_post-install-node-tasks","how-huge-pages-are-consumed-by-apps_post-install-node-tasks","configuring-huge-pages_post-install-node-tasks","at-boot-time","nodes-pods-plugins-about_post-install-node-tasks","methods-for-deploying-a-device-plugin_post-install-node-tasks","nodes-pods-plugins-device-mgr_post-install-node-tasks","nodes-pods-plugins-install_post-install-node-tasks","post-install-taints-tolerations","nodes-scheduler-taints-tolerations-about_post-install-node-tasks","nodes-scheduler-taints-tolerations-about-seconds_post-install-node-tasks","nodes-scheduler-taints-tolerations-about-multiple_post-install-node-tasks","nodes-scheduler-taints-tolerations-about-taintNodesByCondition_post-install-node-tasks","nodes-scheduler-taints-tolerations-about-taintBasedEvictions_post-install-node-tasks","nodes-scheduler-taints-tolerations-all_post-install-node-tasks","nodes-scheduler-taints-tolerations-adding_post-install-node-tasks","nodes-scheduler-taints-tolerations-adding-machineset_post-install-node-tasks","nodes-scheduler-taints-tolerations-bindings_post-install-node-tasks","nodes-scheduler-taints-tolerations-special_post-install-node-tasks","nodes-scheduler-taints-tolerations-removing_post-install-node-tasks","post-install-topology-manager","topology_manager_policies_post-install-node-tasks","seting_up_topology_manager_post-install-node-tasks","pod-interactions-with-topology-manager_post-install-node-tasks","nodes-cluster-overcommit-resource-requests_post-install-node-tasks","nodes-cluster-resource-override_post-install-node-tasks","nodes-cluster-resource-override-deploy-console_post-install-node-tasks","nodes-cluster-resource-override-deploy-cli_post-install-node-tasks","nodes-cluster-resource-configure_post-install-node-tasks","nodes-cluster-node-overcommit_post-install-node-tasks","nodes-cluster-overcommit-reserving-memory_post-install-node-tasks","understanding-container-CPU-requests_post-install-node-tasks","understanding-memory-requests-container_post-install-node-tasks","nodes-cluster-overcommit-qos-about_post-install-node-tasks","qos-about-reserve_post-install-node-tasks","nodes-qos-about-swap_post-install-node-tasks","nodes-cluster-overcommit-configure-nodes_post-install-node-tasks","nodes-cluster-overcommit-node-enforcing_post-install-node-tasks","nodes-cluster-overcommit-node-resources_post-install-node-tasks","nodes-cluster-overcommit-node-disable_post-install-node-tasks","nodes-cluster-project-overcommit_post-install-node-tasks","nodes-cluster-overcommit-project-disable_post-install-node-tasks","post-install-garbage-collection","nodes-nodes-garbage-collection-containers_post-install-node-tasks","nodes-nodes-garbage-collection-images_post-install-node-tasks","nodes-nodes-garbage-collection-configuring_post-install-node-tasks","post-using-node-tuning-operator","accessing-an-example-node-tuning-operator-specification_post-install-node-tasks","custom-tuning-specification_post-install-node-tasks","custom-tuning-default-profiles-set_post-install-node-tasks","supported-tuned-daemon-plug-ins_post-install-node-tasks","nodes-nodes-managing-max-pods-about_post-install-node-tasks","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-node-tasks",{"title":4962,"visible":17,"weight":460,"urlFragment":4963,"anchor":23,"singlePageAnchor":4963,"subChapters":4964,"url":4997,"docTitle":4779},"Post-installation network configuration","post-install-network-configuration",[4965,4966,4967,4968,4969,4970,4971,4972,4973,4974,4975,4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996],"nw-operator-cr_post-install-network-configuration","nw-proxy-configure-object_post-install-network-configuration","private-clusters-setting-dns-private_post-install-network-configuration","post-install-configuring_ingress_cluster_traffic","post-install-configuring-node-port-service-range","post-install-configuring-node-port-service-range-prerequisites","nw-nodeport-service-range-edit_post-install-network-configuration","post-install-configuring-network-policy","nw-networkpolicy-about_post-install-network-configuration","nw-networkpolicy-object_post-install-network-configuration","nw-networkpolicy-create_post-install-network-configuration","nw-networkpolicy-multitenant-isolation_post-install-network-configuration","post-install-nw-networkpolicy-creating-default-networkpolicy-objects-for-a-new-project","modifying-template-for-new-projects_post-install-network-configuration","nw-networkpolicy-project-defaults_post-install-network-configuration","ossm-supported-configurations_post-install-network-configuration","ossm-supported-platforms_post-install-network-configuration","ossm-unsupported-configurations_post-install-network-configuration","ossm-supported-configurations-networks_post-install-network-configuration","ossm-supported-configurations-sm_post-install-network-configuration","ossm-supported-configurations-kiali_post-install-network-configuration","ossm-supported-configurations-jaeger_post-install-network-configuration","ossm-supported-configurations-webassembly_post-install-network-configuration","ossm-installation-activities_post-install-network-configuration","post-installationrouting-optimization","baseline-router-performance_post-install-network-configuration","router-performance-optimizations_post-install-network-configuration","post-installation-osp-fips","installation-osp-configuring-api-floating-ip_post-install-network-configuration","installation-osp-kuryr-port-pools_post-install-network-configuration","installation-osp-kuryr-settings-active_post-install-network-configuration","nw-osp-configure-octavia-load-balancing-services_post-install-network-configuration","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-network-configuration",{"title":4999,"visible":17,"weight":475,"urlFragment":5000,"anchor":23,"singlePageAnchor":5000,"subChapters":5001,"url":5026,"docTitle":4779},"Post-installation storage configuration","post-install-storage-configuration",[5002,5003,5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,5019,4692,5020,5021,5022,5023,5024,5025],"post-install-dynamic-provisioning","about_post-install-storage-configuration","available-plug-ins_post-install-storage-configuration","defining-storage-classes_post-install-storage-configuration","basic-storage-class-definition_post-install-storage-configuration","storage-class-annotations_post-install-storage-configuration","openstack-cinder-storage-class_post-install-storage-configuration","aws-definition_post-install-storage-configuration","azure-disk-definition_post-install-storage-configuration","azure-file-definition_post-install-storage-configuration","azure-file-considerations_post-install-storage-configuration","gce-persistentdisk-storage-class_post-install-storage-configuration","vsphere-definition_post-install-storage-configuration","change-default-storage-class_post-install-storage-configuration","post-install-optimizing-storage","available-persistent-storage-options_post-install-storage-configuration","recommended-configurable-storage-technology_post-install-storage-configuration","specific-application-storage-recommendations","scaled-registry","metrics","logging","applications","other-specific-application-storage-recommendations","post-install-deploy-OCS","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-storage-configuration",{"title":5028,"visible":17,"weight":876,"urlFragment":5029,"anchor":23,"singlePageAnchor":5029,"subChapters":5030,"url":5061,"docTitle":4779},"Preparing for users","post-install-preparing-for-users",[5031,5032,5033,5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060],"post-install-understanding-identity-provider","identity-provider-overview_post-install-preparing-for-users","post-install-supported-identity-providers","identity-provider-parameters_post-install-preparing-for-users","identity-provider-default-CR_post-install-preparing-for-users","post-install-using-rbac-to-define-and-apply-permissions","authorization-overview_post-install-preparing-for-users","default-roles_post-install-preparing-for-users","evaluating-authorization_post-install-preparing-for-users","cluster-role-aggregations_post-install-preparing-for-users","rbac-projects-namespaces_post-install-preparing-for-users","rbac-default-projects_post-install-preparing-for-users","viewing-cluster-roles_post-install-preparing-for-users","viewing-local-roles_post-install-preparing-for-users","adding-roles_post-install-preparing-for-users","creating-local-role_post-install-preparing-for-users","creating-cluster-role_post-install-preparing-for-users","local-role-binding-commands_post-install-preparing-for-users","cluster-role-binding-commands_post-install-preparing-for-users","creating-cluster-admin_post-install-preparing-for-users","understanding-kubeadmin_post-install-preparing-for-users","removing-kubeadmin_post-install-preparing-for-users","post-install-image-configuration-resources","images-configuration-parameters_post-install-preparing-for-users","images-configuration-file_post-install-preparing-for-users","images-configuration-cas_post-install-preparing-for-users","images-configuration-registry-mirror_post-install-preparing-for-users","olm-installing-operators-from-operatorhub_post-install-preparing-for-users","olm-installing-from-operatorhub-using-web-console_post-install-preparing-for-users","olm-installing-operator-from-operatorhub-using-cli_post-install-preparing-for-users","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-preparing-for-users",{"title":5063,"visible":17,"weight":884,"urlFragment":5064,"anchor":23,"singlePageAnchor":5064,"subChapters":5065,"url":5069,"docTitle":4779},"Configuring alert notifications","configuring-alert-notifications",[5066,5067,5068],"sending-notifications-to-external-systems_configuring-alert-notifications","configuring-alert-receivers_configuring-alert-notifications","configuring-alert-notifications-additional-resources","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/configuring-alert-notifications",{"title":5071,"visible":17,"weight":895,"urlFragment":5072,"anchor":23,"singlePageAnchor":5072,"subChapters":5073,"url":5082,"docTitle":4779},"Configuring additional devices in an IBM Z or LinuxONE environment","post-install-configure-additional-devices-ibmz",[5074,5075,5076,5077,5078,5079,5080,5081],"configure-additional-devices-using-mco_post-install-configure-additional-devices-ibmz","configuring-fcp-host","configuring-fcp-lun","configuring-dasd","configuring-qeth","configure-additional-devices-manually_post-install-configure-additional-devices-ibmz","roce-network-cards","enabling-multipathing-fcp-luns_post-install-configure-additional-devices-ibmz","/documentation/openshift_container_platform/4.8/html/post-installation_configuration/post-install-configure-additional-devices-ibmz",{"title":5084,"visible":17,"categoryName":17,"sections":5085},"Migrate",[5086,5316],{"title":5087,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":5088,"url":5089,"docTitle":5090,"sections":5091},"Migrating from version 3 to 4",[],"/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/index","migrating_from_version_3_to_4",[5092,5107,5112,5125,5134,5145,5175,5202,5210,5219,5231,5269],{"title":5093,"visible":17,"weight":30,"urlFragment":5094,"anchor":23,"singlePageAnchor":5094,"subChapters":5095,"url":5106,"docTitle":5090},"Migration from OpenShift Container Platform 3 to 4 overview","migration-from-version-3-to-4-overview",[5096,5097,5098,5099,5100,5101,5102,5103,5104,5105],"mtc-3-to-4-overview-differences-mtc","mtc-3-to-4-overview-planning-network-considerations-mtc","mtc-overview-install-mtc","mtc-overview-upgrade-mtc","mtc-overview-mtc-checklists","mtc-overview-migrate-mtc-applications","mtc-overview-advanced-migration-options","mtc-overview-troubleshooting-mtc","mtc-overview-roll-back-mtc","mtc-overview-uninstall-mtc","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/migration-from-version-3-to-4-overview",{"title":5108,"visible":17,"weight":42,"urlFragment":5109,"anchor":23,"singlePageAnchor":5109,"subChapters":5110,"url":5111,"docTitle":5090},"About migrating from OpenShift Container Platform 3 to 4","about-migrating-from-3-to-4",[],"/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/about-migrating-from-3-to-4",{"title":5113,"visible":17,"weight":53,"urlFragment":5114,"anchor":23,"singlePageAnchor":5114,"subChapters":5115,"url":5124,"docTitle":5090},"Differences between OpenShift Container Platform 3 and 4","planning-migration-3-4",[5116,5117,5118,5119,5120,5121,5122,5123],"migration-differences-architecture","migration-differences-install","migration-considerations","migration-preparing-storage","migration-preparing-networking","migration-preparing-logging","migration-preparing-security","migration-preparing-monitoring","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/planning-migration-3-4",{"title":5126,"visible":17,"weight":75,"urlFragment":5127,"anchor":23,"singlePageAnchor":5127,"subChapters":5128,"url":5133,"docTitle":5090},"Network considerations","planning-considerations-3-4",[5129,5130,5131,5132],"dns-considerations_planning-considerations-3-4","migration-isolating-dns-domain-of-target-cluster-from-clients_planning-considerations-3-4","migration-setting-up-target-cluster-to-accept-source-dns-domain_planning-considerations-3-4","migration-network-traffic-redirection-strategies_planning-considerations-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/planning-considerations-3-4",{"title":5135,"visible":17,"weight":442,"urlFragment":5136,"anchor":23,"singlePageAnchor":5136,"subChapters":5137,"url":5144,"docTitle":5090},"About the Migration Toolkit for Containers","about-mtc-3-4",[5138,5139,5140,5141,5142,5143],"migration-terminology_about-mtc-3-4","migration-mtc-workflow_about-mtc-3-4","migration-understanding-data-copy-methods_about-mtc-3-4","file-system-copy-method_about-mtc-3-4","snapshot-copy-method_about-mtc-3-4","migration-direct-volume-migration-and-direct-image-migration_about-mtc-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/about-mtc-3-4",{"title":5146,"visible":17,"weight":460,"urlFragment":5147,"anchor":23,"singlePageAnchor":5147,"subChapters":5148,"url":5174,"docTitle":5090},"Installing the Migration Toolkit for Containers","installing-3-4",[5149,5150,5151,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173],"migration-compatibility-guidelines_installing-3-4","migration-installing-legacy-operator_installing-3-4","migration-installing-mtc-on-ocp-4_installing-3-4","migration-about-configuring-proxies_installing-3-4","direct-volume-migration_installing-3-4","tcp-proxy-setup-for-dvm_installing-3-4","why-tcp-proxy-instead-of-an-http-https-proxy_installing-3-4","dvm-known-issues_installing-3-4","tuning-network-policies-for-migrations_installing-3-4","dvm-network-policy-configuration_installing-3-4","egress-traffic-from-rsync-pods_installing-3-4","ingress-traffic-to-rsync-pods_installing-3-4","egressnetworkpolicy-config_installing-3-4","configuring-supplemental-groups-for-rsync-podsinstalling-3-4","migration-configuring-proxies_installing-3-4","configuring-replication-repository_installing-3-4","replication-repository-prerequisites_installing-3-4","migration-configuring-mcg_installing-3-4","installing-the-ocs-operator_installing-3-4","configuring-mcg-storage-bucket_installing-3-4","migration-configuring-aws-s3_installing-3-4","migration-configuring-gcp_installing-3-4","migration-configuring-azure_installing-3-4","installing-3-4_configuring-replication-repository-additional-resources","migration-uninstalling-mtc-clean-up_installing-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/installing-3-4",{"title":5176,"visible":17,"weight":475,"urlFragment":5177,"anchor":23,"singlePageAnchor":5177,"subChapters":5178,"url":5201,"docTitle":5090},"Installing the Migration Toolkit for Containers in a restricted network environment","installing-restricted-3-4",[5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200],"migration-compatibility-guidelines_installing-restricted-3-4","migration-installing-mtc-on-ocp-4_installing-restricted-3-4","migration-installing-legacy-operator_installing-restricted-3-4","migration-about-configuring-proxies_installing-restricted-3-4","direct-volume-migration_installing-restricted-3-4","tcp-proxy-setup-for-dvm_installing-restricted-3-4","why-tcp-proxy-instead-of-an-http-https-proxy_installing-restricted-3-4","dvm-known-issues_installing-restricted-3-4","tuning-network-policies-for-migrations_installing-restricted-3-4","dvm-network-policy-configuration_installing-restricted-3-4","egress-traffic-from-rsync-pods_installing-restricted-3-4","ingress-traffic-to-rsync-pods_installing-restricted-3-4","egressnetworkpolicy-config_installing-restricted-3-4","configuring-supplemental-groups-for-rsync-podsinstalling-restricted-3-4","migration-configuring-proxies_installing-restricted-3-4","configuring-replication-repository_installing-restricted-3-4","replication-repository-prerequisites_installing-restricted-3-4","migration-configuring-mcg_installing-restricted-3-4","installing-the-ocs-operator_installing-restricted-3-4","configuring-mcg-storage-bucket_installing-restricted-3-4","installing-restricted-3-4_configuring-replication-repository-additional-resources","migration-uninstalling-mtc-clean-up_installing-restricted-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/installing-restricted-3-4",{"title":5203,"visible":17,"weight":876,"urlFragment":5204,"anchor":23,"singlePageAnchor":5204,"subChapters":5205,"url":5209,"docTitle":5090},"Upgrading the Migration Toolkit for Containers","upgrading-3-4",[5206,5207,5208],"migration-upgrading-mtc-on-ocp-4_upgrading-3-4","migration-upgrading-mtc-with-legacy-operator_upgrading-3-4","migration-upgrading-from-mtc-1-3_upgrading-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/upgrading-3-4",{"title":5211,"visible":17,"weight":884,"urlFragment":5212,"anchor":23,"singlePageAnchor":5212,"subChapters":5213,"url":5218,"docTitle":5090},"Premigration checklists","premigration-checklists-3-4",[5214,5215,5216,5217],"resources_premigration-checklists-3-4","source-cluster_premigration-checklists-3-4","target-cluster_premigration-checklists-3-4","performance_premigration-checklists-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/premigration-checklists-3-4",{"title":5220,"visible":17,"weight":895,"urlFragment":5221,"anchor":23,"singlePageAnchor":5221,"subChapters":5222,"url":5230,"docTitle":5090},"Migrating your applications","migrating-applications-3-4",[5223,5224,5225,5226,5227,5228,5229],"migration-prerequisites_migrating-applications-3-4","migrating-applications-mtc-web-console_migrating-applications-3-4","migration-launching-cam_migrating-applications-3-4","migration-adding-cluster-to-cam_migrating-applications-3-4","migration-adding-replication-repository-to-cam_migrating-applications-3-4","migration-creating-migration-plan-cam_migrating-applications-3-4","migration-running-migration-plan-cam_migrating-applications-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/migrating-applications-3-4",{"title":5232,"visible":17,"weight":906,"urlFragment":5233,"anchor":23,"singlePageAnchor":5233,"subChapters":5234,"url":5268,"docTitle":5090},"Advanced migration options","advanced-migration-options-3-4",[5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267],"migration-terminology_advanced-migration-options-3-4","migrating-applications-cli_advanced-migration-options-3-4","migration-prerequisites_advanced-migration-options-3-4","migration-creating-registry-route-for-dim_advanced-migration-options-3-4","migration-about-configuring-proxies_advanced-migration-options-3-4","direct-volume-migration_advanced-migration-options-3-4","tcp-proxy-setup-for-dvm_advanced-migration-options-3-4","why-tcp-proxy-instead-of-an-http-https-proxy_advanced-migration-options-3-4","dvm-known-issues_advanced-migration-options-3-4","tuning-network-policies-for-migrations_advanced-migration-options-3-4","dvm-network-policy-configuration_advanced-migration-options-3-4","egress-traffic-from-rsync-pods_advanced-migration-options-3-4","ingress-traffic-to-rsync-pods_advanced-migration-options-3-4","egressnetworkpolicy-config_advanced-migration-options-3-4","configuring-supplemental-groups-for-rsync-podsadvanced-migration-options-3-4","migration-configuring-proxies_advanced-migration-options-3-4","migration-migrating-applications-api_advanced-migration-options-3-4","migration-state-migration-cli_advanced-migration-options-3-4","migration-hooks_advanced-migration-options-3-4","migration-writing-ansible-playbook-hook_advanced-migration-options-3-4","migration-writing-ansible-playbook-hook-ansible-modules_advanced-migration-options-3-4","migration-writing-ansible-playbook-hook-environment-variables_advanced-migration-options-3-4","migration-plan-options_advanced-migration-options-3-4","migration-excluding-resources_advanced-migration-options-3-4","migration-mapping-destination-namespaces-in-the-migplan-cr_advanced-migration-options-3-4","migration-excluding-pvcs_advanced-migration-options-3-4","migration-mapping-pvcs_advanced-migration-options-3-4","migration-editing-pvs-in-migplan_advanced-migration-options-3-4","migration-kubernetes-objects_advanced-migration-options-3-4","migration-controller-options_advanced-migration-options-3-4","migration-changing-migration-plan-limits_advanced-migration-options-3-4","migration-enabling-pv-resizing-dvm_advanced-migration-options-3-4","migration-enabling-cached-kubernetes-clients_advanced-migration-options-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/advanced-migration-options-3-4",{"title":5270,"visible":17,"weight":913,"urlFragment":5271,"anchor":23,"singlePageAnchor":5271,"subChapters":5272,"url":5315,"docTitle":5090},"Troubleshooting","troubleshooting-3-4",[5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314],"migration-mtc-workflow_troubleshooting-3-4","migration-mtc-cr-manifests_troubleshooting-3-4","directimagemigration_troubleshooting-3-4","directimagestreammigration_troubleshooting-3-4","directvolumemigration_troubleshooting-3-4","directvolumemigrationprogress_troubleshooting-3-4","miganalytic_troubleshooting-3-4","migcluster_troubleshooting-3-4","mighook_troubleshooting-3-4","migmigration_troubleshooting-3-4","migplan_troubleshooting-3-4","migstorage_troubleshooting-3-4","logs-and-debugging-tools_troubleshooting-3-4","migration-viewing-migration-plan-resources_troubleshooting-3-4","migration-viewing-migration-plan-log_troubleshooting-3-4","migration-using-mig-log-reader_troubleshooting-3-4","migration-accessing-performance-metrics_troubleshooting-3-4","migration-provided-metrics_troubleshooting-3-4","cam_app_workload_migrations-metric_troubleshooting-3-4","mtc_client_request_count-metric_troubleshooting-3-4","mtc_client_request_elapsed-metric_troubleshooting-3-4","useful-queries_troubleshooting-3-4","migration-using-must-gather_troubleshooting-3-4","migration-debugging-velero-resources_troubleshooting-3-4","migration-partial-failure-velero_troubleshooting-3-4","migration-using-mtc-crs-for-troubleshooting_troubleshooting-3-4","common-issues-and-concerns_troubleshooting-3-4","migration-updating-deprecated-internal-images_troubleshooting-3-4","migration-dvm-error-node-selectors_troubleshooting-3-4","migration-error-messages_troubleshooting-3-4","ca-certificate-error-displayed-when-accessing-console-for-first-time_troubleshooting-3-4","oauth-timeout-error-in-console_troubleshooting-3-4","certificate-signed-by-unknown-authority-error_troubleshooting-3-4","backup-storage-location-errors-in-velero-pod-log_troubleshooting-3-4","pod-volume-backup-timeout-error-in-velero-pod-log_troubleshooting-3-4","restic-verification-errors-in-migmigration-custom-resource_troubleshooting-3-4","restic-permission-error-when-migrating-from-nfs-storage-with-root-squash-enabled_troubleshooting-3-4","migration-known-issues_troubleshooting-3-4","rolling-back-migration_troubleshooting-3-4","migration-rolling-back-migration-web-console_troubleshooting-3-4","migration-rolling-back-migration-cli_troubleshooting-3-4","migration-rolling-back-migration-manually_troubleshooting-3-4","/documentation/openshift_container_platform/4.8/html/migrating_from_version_3_to_4/troubleshooting-3-4",{"title":5317,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":5318,"url":5319,"docTitle":5320,"sections":5321},"Migration Toolkit for Containers",[],"/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/index","migration_toolkit_for_containers",[5322,5332,5348,5377,5403,5410,5417,5425,5436,5473],{"title":5135,"visible":17,"weight":30,"urlFragment":5323,"anchor":23,"singlePageAnchor":5323,"subChapters":5324,"url":5331,"docTitle":5320},"about-mtc",[5325,5326,5327,5328,5329,5330],"migration-terminology_about-mtc","migration-mtc-workflow_about-mtc","migration-understanding-data-copy-methods_about-mtc","file-system-copy-method_about-mtc","snapshot-copy-method_about-mtc","migration-direct-volume-migration-and-direct-image-migration_about-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/about-mtc",{"title":5333,"visible":17,"weight":42,"urlFragment":5334,"anchor":23,"singlePageAnchor":5334,"subChapters":5335,"url":5347,"docTitle":5320},"Migration Toolkit for Containers release notes","mtc-release-notes",[5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346],"migration-mtc-release-notes-1-6_mtc-release-notes","new-features-and-enhancements-1-6_mtc-release-notes","deprecated-features-1-6_mtc-release-notes","known-issues-1-6_mtc-release-notes","migration-mtc-release-notes-1-5_mtc-release-notes","new-features-and-enhancements-1-5_mtc-release-notes","deprecated-features-1-5_mtc-release-notes","known-issues-1-5_mtc-release-notes","technical-changes-1-5_mtc-release-notes","migration-mtc-release-notes-1-4_mtc-release-notes","known-issues-1-4_mtc-release-notes","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/mtc-release-notes",{"title":5146,"visible":17,"weight":53,"urlFragment":5349,"anchor":23,"singlePageAnchor":5349,"subChapters":5350,"url":5376,"docTitle":5320},"installing-mtc",[5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375],"migration-compatibility-guidelines_installing-mtc","migration-installing-legacy-operator_installing-mtc","migration-installing-mtc-on-ocp-4_installing-mtc","migration-about-configuring-proxies_installing-mtc","direct-volume-migration_installing-mtc","tcp-proxy-setup-for-dvm_installing-mtc","why-tcp-proxy-instead-of-an-http-https-proxy_installing-mtc","dvm-known-issues_installing-mtc","tuning-network-policies-for-migrations_installing-mtc","dvm-network-policy-configuration_installing-mtc","egress-traffic-from-rsync-pods_installing-mtc","ingress-traffic-to-rsync-pods_installing-mtc","egressnetworkpolicy-config_installing-mtc","configuring-supplemental-groups-for-rsync-podsinstalling-mtc","migration-configuring-proxies_installing-mtc","configuring-replication-repository_installing-mtc","replication-repository-prerequisites_installing-mtc","migration-configuring-mcg_installing-mtc","installing-the-ocs-operator_installing-mtc","configuring-mcg-storage-bucket_installing-mtc","migration-configuring-aws-s3_installing-mtc","migration-configuring-gcp_installing-mtc","migration-configuring-azure_installing-mtc","installing-mtc_configuring-replication-repository-additional-resources","migration-uninstalling-mtc-clean-up_installing-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/installing-mtc",{"title":5176,"visible":17,"weight":75,"urlFragment":5378,"anchor":23,"singlePageAnchor":5378,"subChapters":5379,"url":5402,"docTitle":5320},"installing-mtc-restricted",[5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,5399,5400,5401],"migration-compatibility-guidelines_installing-mtc-restricted","migration-installing-mtc-on-ocp-4_installing-mtc-restricted","migration-installing-legacy-operator_installing-mtc-restricted","migration-about-configuring-proxies_installing-mtc-restricted","direct-volume-migration_installing-mtc-restricted","tcp-proxy-setup-for-dvm_installing-mtc-restricted","why-tcp-proxy-instead-of-an-http-https-proxy_installing-mtc-restricted","dvm-known-issues_installing-mtc-restricted","tuning-network-policies-for-migrations_installing-mtc-restricted","dvm-network-policy-configuration_installing-mtc-restricted","egress-traffic-from-rsync-pods_installing-mtc-restricted","ingress-traffic-to-rsync-pods_installing-mtc-restricted","egressnetworkpolicy-config_installing-mtc-restricted","configuring-supplemental-groups-for-rsync-podsinstalling-mtc-restricted","migration-configuring-proxies_installing-mtc-restricted","configuring-replication-repository_installing-mtc-restricted","replication-repository-prerequisites_installing-mtc-restricted","migration-configuring-mcg_installing-mtc-restricted","installing-the-ocs-operator_installing-mtc-restricted","configuring-mcg-storage-bucket_installing-mtc-restricted","installing-mtc-restricted_configuring-replication-repository-additional-resources","migration-uninstalling-mtc-clean-up_installing-mtc-restricted","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/installing-mtc-restricted",{"title":5203,"visible":17,"weight":442,"urlFragment":5404,"anchor":23,"singlePageAnchor":5404,"subChapters":5405,"url":5409,"docTitle":5320},"upgrading-mtc",[5406,5407,5408],"migration-upgrading-mtc-on-ocp-4_upgrading-mtc","migration-upgrading-mtc-with-legacy-operator_upgrading-mtc","migration-upgrading-from-mtc-1-3_upgrading-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/upgrading-mtc",{"title":5211,"visible":17,"weight":460,"urlFragment":5411,"anchor":23,"singlePageAnchor":5411,"subChapters":5412,"url":5416,"docTitle":5320},"premigration-checklists-mtc",[5413,5414,5415],"cluster-health-checklist_premigration-checklists-mtc","source-cluster-checklist_premigration-checklists-mtc","target-cluster-checklist_premigration-checklists-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/premigration-checklists-mtc",{"title":5126,"visible":17,"weight":475,"urlFragment":5418,"anchor":23,"singlePageAnchor":5418,"subChapters":5419,"url":5424,"docTitle":5320},"network-considerations-mtc",[5420,5421,5422,5423],"dns-considerations_network-considerations-mtc","migration-isolating-dns-domain-of-target-cluster-from-clients_network-considerations-mtc","migration-setting-up-target-cluster-to-accept-source-dns-domain_network-considerations-mtc","migration-network-traffic-redirection-strategies_network-considerations-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/network-considerations-mtc",{"title":5220,"visible":17,"weight":876,"urlFragment":5426,"anchor":23,"singlePageAnchor":5426,"subChapters":5427,"url":5435,"docTitle":5320},"migrating-applications-with-mtc",[5428,5429,5430,5431,5432,5433,5434],"migration-prerequisites_migrating-applications-with-mtc","migrating-applications-mtc-web-console_migrating-applications-with-mtc","migration-launching-cam_migrating-applications-with-mtc","migration-adding-cluster-to-cam_migrating-applications-with-mtc","migration-adding-replication-repository-to-cam_migrating-applications-with-mtc","migration-creating-migration-plan-cam_migrating-applications-with-mtc","migration-running-migration-plan-cam_migrating-applications-with-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/migrating-applications-with-mtc",{"title":5232,"visible":17,"weight":884,"urlFragment":5437,"anchor":23,"singlePageAnchor":5437,"subChapters":5438,"url":5472,"docTitle":5320},"advanced-migration-options-mtc",[5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471],"migration-terminology_advanced-migration-options-mtc","migrating-applications-cli_advanced-migration-options-mtc","migration-prerequisites_advanced-migration-options-mtc","migration-creating-registry-route-for-dim_advanced-migration-options-mtc","migration-about-configuring-proxies_advanced-migration-options-mtc","direct-volume-migration_advanced-migration-options-mtc","tcp-proxy-setup-for-dvm_advanced-migration-options-mtc","why-tcp-proxy-instead-of-an-http-https-proxy_advanced-migration-options-mtc","dvm-known-issues_advanced-migration-options-mtc","tuning-network-policies-for-migrations_advanced-migration-options-mtc","dvm-network-policy-configuration_advanced-migration-options-mtc","egress-traffic-from-rsync-pods_advanced-migration-options-mtc","ingress-traffic-to-rsync-pods_advanced-migration-options-mtc","egressnetworkpolicy-config_advanced-migration-options-mtc","configuring-supplemental-groups-for-rsync-podsadvanced-migration-options-mtc","migration-configuring-proxies_advanced-migration-options-mtc","migration-migrating-applications-api_advanced-migration-options-mtc","migration-state-migration-cli_advanced-migration-options-mtc","migration-hooks_advanced-migration-options-mtc","migration-writing-ansible-playbook-hook_advanced-migration-options-mtc","migration-writing-ansible-playbook-hook-ansible-modules_advanced-migration-options-mtc","migration-writing-ansible-playbook-hook-environment-variables_advanced-migration-options-mtc","migration-plan-options_advanced-migration-options-mtc","migration-excluding-resources_advanced-migration-options-mtc","migration-mapping-destination-namespaces-in-the-migplan-cr_advanced-migration-options-mtc","migration-excluding-pvcs_advanced-migration-options-mtc","migration-mapping-pvcs_advanced-migration-options-mtc","migration-editing-pvs-in-migplan_advanced-migration-options-mtc","migration-kubernetes-objects_advanced-migration-options-mtc","migration-controller-options_advanced-migration-options-mtc","migration-changing-migration-plan-limits_advanced-migration-options-mtc","migration-enabling-pv-resizing-dvm_advanced-migration-options-mtc","migration-enabling-cached-kubernetes-clients_advanced-migration-options-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/advanced-migration-options-mtc",{"title":5270,"visible":17,"weight":895,"urlFragment":5474,"anchor":23,"singlePageAnchor":5474,"subChapters":5475,"url":5516,"docTitle":5320},"troubleshooting-mtc",[5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515],"migration-mtc-workflow_troubleshooting-mtc","migration-mtc-cr-manifests_troubleshooting-mtc","directimagemigration_troubleshooting-mtc","directimagestreammigration_troubleshooting-mtc","directvolumemigration_troubleshooting-mtc","directvolumemigrationprogress_troubleshooting-mtc","miganalytic_troubleshooting-mtc","migcluster_troubleshooting-mtc","mighook_troubleshooting-mtc","migmigration_troubleshooting-mtc","migplan_troubleshooting-mtc","migstorage_troubleshooting-mtc","logs-and-debugging-tools_troubleshooting-mtc","migration-viewing-migration-plan-resources_troubleshooting-mtc","migration-viewing-migration-plan-log_troubleshooting-mtc","migration-using-mig-log-reader_troubleshooting-mtc","migration-accessing-performance-metrics_troubleshooting-mtc","migration-provided-metrics_troubleshooting-mtc","cam_app_workload_migrations-metric_troubleshooting-mtc","mtc_client_request_count-metric_troubleshooting-mtc","mtc_client_request_elapsed-metric_troubleshooting-mtc","useful-queries_troubleshooting-mtc","migration-using-must-gather_troubleshooting-mtc","migration-debugging-velero-resources_troubleshooting-mtc","migration-partial-failure-velero_troubleshooting-mtc","migration-using-mtc-crs-for-troubleshooting_troubleshooting-mtc","common-issues-and-concerns_troubleshooting-mtc","migration-dvm-error-node-selectors_troubleshooting-mtc","migration-error-messages_troubleshooting-mtc","ca-certificate-error-displayed-when-accessing-console-for-first-time_troubleshooting-mtc","oauth-timeout-error-in-console_troubleshooting-mtc","certificate-signed-by-unknown-authority-error_troubleshooting-mtc","backup-storage-location-errors-in-velero-pod-log_troubleshooting-mtc","pod-volume-backup-timeout-error-in-velero-pod-log_troubleshooting-mtc","restic-verification-errors-in-migmigration-custom-resource_troubleshooting-mtc","restic-permission-error-when-migrating-from-nfs-storage-with-root-squash-enabled_troubleshooting-mtc","rolling-back-migration_troubleshooting-mtc","migration-rolling-back-migration-web-console_troubleshooting-mtc","migration-rolling-back-migration-cli_troubleshooting-mtc","migration-rolling-back-migration-manually_troubleshooting-mtc","/documentation/openshift_container_platform/4.8/html/migration_toolkit_for_containers/troubleshooting-mtc",{"title":5518,"visible":17,"categoryName":17,"sections":5519},"Manage",[5520,5659,5842,5972],{"title":5521,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":5522,"url":5523,"docTitle":5524,"sections":5525},"Backup and restore",[],"/documentation/openshift_container_platform/4.8/html/backup_and_restore/index","backup_and_restore",[5526,5534,5540,5546,5637],{"title":5521,"visible":17,"weight":30,"urlFragment":5527,"anchor":23,"singlePageAnchor":5527,"subChapters":5528,"url":5533,"docTitle":5524},"backup-restore-overview",[5529,5530,5531,5532],"backup-restore-operations-overview","application-backup-restore-operations-overview","oadp-requirements","backing-up-and-restoring-applications","/documentation/openshift_container_platform/4.8/html/backup_and_restore/backup-restore-overview",{"title":5535,"visible":17,"weight":42,"urlFragment":5536,"anchor":23,"singlePageAnchor":5536,"subChapters":5537,"url":5539,"docTitle":5524},"Shutting down the cluster gracefully","graceful-shutdown-cluster",[1013,5538],"graceful-shutdown_graceful-shutdown-cluster","/documentation/openshift_container_platform/4.8/html/backup_and_restore/graceful-shutdown-cluster",{"title":5541,"visible":17,"weight":53,"urlFragment":5542,"anchor":23,"singlePageAnchor":5542,"subChapters":5543,"url":5545,"docTitle":5524},"Restarting the cluster gracefully","graceful-restart-cluster",[1024,5544],"graceful-restart_graceful-restart-cluster","/documentation/openshift_container_platform/4.8/html/backup_and_restore/graceful-restart-cluster",{"title":5547,"visible":17,"weight":75,"urlFragment":5548,"anchor":23,"singlePageAnchor":5548,"subChapters":5549,"url":5636,"docTitle":5524},"Application backup and restore","application-backup-and-restore",[5550,5551,5552,5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,5634,5635],"oadp-features-plugins","oadp-features_oadp-features-plugins","oadp-plugins_oadp-features-plugins","oadp-configuring-velero-plugins_oadp-features-plugins","default-velero-cloud-provider-plugins","custom-velero-plugins","installing-and-configuring-oadp","about-installing-oadp","installing-oadp-aws","oadp-installing-operator_installing-oadp-aws","migration-configuring-aws-s3_installing-oadp-aws","oadp-creating-secret_installing-oadp-aws","oadp-secrets-for-different-credentials_installing-oadp-aws","configuring-dpa-aws","oadp-setting-resource-limits-and-requests_installing-oadp-aws","oadp-self-signed-certificate_installing-oadp-aws","oadp-installing-dpa_installing-oadp-aws","oadp-enabling-csi-dpa_installing-oadp-aws","installing-oadp-azure","oadp-installing-operator_installing-oadp-azure","migration-configuring-azure_installing-oadp-azure","oadp-creating-secret_installing-oadp-azure","oadp-secrets-for-different-credentials_installing-oadp-azure","configuring-dpa-azure","oadp-setting-resource-limits-and-requests_installing-oadp-azure","oadp-self-signed-certificate_installing-oadp-azure","oadp-installing-dpa_installing-oadp-azure","oadp-enabling-csi-dpa_installing-oadp-azure","installing-oadp-gcp","oadp-installing-operator_installing-oadp-gcp","migration-configuring-gcp_installing-oadp-gcp","oadp-creating-secret_installing-oadp-gcp","oadp-secrets-for-different-credentials_installing-oadp-gcp","configuring-dpa-gcp","oadp-setting-resource-limits-and-requests_installing-oadp-gcp","oadp-self-signed-certificate_installing-oadp-gcp","oadp-installing-dpa_installing-oadp-gcp","oadp-enabling-csi-dpa_installing-oadp-gcp","installing-oadp-mcg","oadp-installing-operator_installing-oadp-mcg","migration-configuring-mcg_installing-oadp-mcg","installing-the-ocs-operator_installing-oadp-mcg","configuring-mcg-storage-bucket_installing-oadp-mcg","oadp-creating-secret_installing-oadp-mcg","oadp-secrets-for-different-credentials_installing-oadp-mcg","configuring-dpa-mcg","oadp-setting-resource-limits-and-requests_installing-oadp-mcg","oadp-self-signed-certificate_installing-oadp-mcg","oadp-installing-dpa_installing-oadp-mcg","oadp-enabling-csi-dpa_installing-oadp-mcg","installing-oadp-ocs","oadp-installing-operator_installing-oadp-ocs","oadp-creating-secret_installing-oadp-ocs","oadp-secrets-for-different-credentials_installing-oadp-ocs","configuring-dpa-ocs","oadp-setting-resource-limits-and-requests_installing-oadp-ocs","oadp-self-signed-certificate_installing-oadp-ocs","oadp-installing-dpa_installing-oadp-ocs","oadp-enabling-csi-dpa_installing-oadp-ocs","uninstalling-oadp","backing-up-and-restoring","backing-up-applications","oadp-creating-backup-cr_backing-up-applications","oadp-backing-up-pvs-csi_backing-up-applications","oadp-backing-up-applications-restic_backing-up-applications","oadp-creating-backup-hooks_backing-up-applications","oadp-scheduling-backups_backing-up-applications","restoring-applications","oadp-creating-restore-cr_restoring-applications","oadp-creating-restore-hooks_restoring-applications","troubleshooting","velero-obtaining-by-downloading_oadp-troubleshooting","velero-obtaining-by-accessing-binary_oadp-troubleshooting","oadp-debugging-oc-cli_oadp-troubleshooting","migration-debugging-velero-resources_oadp-troubleshooting","oadp-installation-issues_oadp-troubleshooting","oadp-backup-location-contains-invalid-directories_oadp-troubleshooting","oadp-incorrect-aws-credentials_oadp-troubleshooting","oadp-backup-restore-cr-issues_oadp-troubleshooting","backup-cannot-retrieve-volume_oadp-troubleshooting","backup-cr-remains-in-progress_oadp-troubleshooting","oadp-restic-issues_oadp-troubleshooting","restic-permission-error-nfs-root-squash-enabled_oadp-troubleshooting","restic-restore-deploymentconfig-issue_oadp-troubleshooting","restic-backup-cannot-be-recreated-after-s3-bucket-emptied_oadp-troubleshooting","migration-using-must-gather_oadp-troubleshooting","/documentation/openshift_container_platform/4.8/html/backup_and_restore/application-backup-and-restore",{"title":5638,"visible":17,"weight":442,"urlFragment":5639,"anchor":23,"singlePageAnchor":5639,"subChapters":5640,"url":5658,"docTitle":5524},"Control plane backup and restore","control-plane-backup-and-restore",[5641,5642,5643,1045,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657],"backup-etcd","backing-up-etcd-data_backup-etcd","replacing-unhealthy-etcd-member","restore-identify-unhealthy-etcd-member_replacing-unhealthy-etcd-member","restore-determine-state-etcd-member_replacing-unhealthy-etcd-member","replacing-the-unhealthy-etcd-member","restore-replace-stopped-etcd-member_replacing-unhealthy-etcd-member","restore-replace-crashlooping-etcd-member_replacing-unhealthy-etcd-member","restore-replace-stopped-baremetal-etcd-member_replacing-unhealthy-etcd-member","disaster-recovery","about-dr","dr-restoring-cluster-state","dr-scenario-2-restoring-cluster-state-about_dr-restoring-cluster-state","dr-scenario-2-restoring-cluster-state_dr-restoring-cluster-state","dr-scenario-cluster-state-issues_dr-restoring-cluster-state","dr-recovering-expired-certs","dr-scenario-3-recovering-expired-certs_dr-recovering-expired-certs","/documentation/openshift_container_platform/4.8/html/backup_and_restore/control-plane-backup-and-restore",{"title":5660,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":5661,"url":5662,"docTitle":5663,"sections":5664},"Machine management",[],"/documentation/openshift_container_platform/4.8/html/machine_management/index","machine_management",[5665,5670,5712,5719,5728,5735,5748,5771,5789,5805,5828],{"title":5666,"visible":17,"weight":30,"urlFragment":5667,"anchor":23,"singlePageAnchor":5667,"subChapters":5668,"url":5669,"docTitle":5663},"Overview of machine management","overview-of-machine-management",[],"/documentation/openshift_container_platform/4.8/html/machine_management/overview-of-machine-management",{"title":5671,"visible":17,"weight":42,"urlFragment":5672,"anchor":23,"singlePageAnchor":5672,"subChapters":5673,"url":5711,"docTitle":5663},"Creating machine sets","creating-machine-sets",[5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710],"creating-machineset-aws","machine-api-overview_creating-machineset-aws","machineset-yaml-aws_creating-machineset-aws","machineset-creating_creating-machineset-aws","machineset-non-guaranteed-instance_creating-machineset-aws","machineset-creating-non-guaranteed-instance_creating-machineset-aws","machineset-dedicated-instance_creating-machineset-aws","machineset-creating-dedicated-instance_creating-machineset-aws","creating-machineset-azure","machine-api-overview_creating-machineset-azure","machineset-yaml-azure_creating-machineset-azure","machineset-creating_creating-machineset-azure","installation-azure-marketplace-subscribe_creating-machineset-azure","machineset-non-guaranteed-instance_creating-machineset-azure","machineset-creating-non-guaranteed-instance_creating-machineset-azure","machineset-enabling-customer-managed-encryption-azure_creating-machineset-azure","creating-machineset-gcp","machine-api-overview_creating-machineset-gcp","machineset-yaml-gcp_creating-machineset-gcp","machineset-creating_creating-machineset-gcp","machineset-non-guaranteed-instance_creating-machineset-gcp","machineset-creating-non-guaranteed-instance_creating-machineset-gcp","machineset-enabling-customer-managed-encryption_creating-machineset-gcp","creating-machineset-osp","machine-api-overview_creating-machineset-osp","machineset-yaml-osp_creating-machineset-osp","machineset-yaml-osp-sr-iov_creating-machineset-osp","machineset-yaml-osp-sr-iov-port-security_creating-machineset-osp","machineset-creating_creating-machineset-osp","creating-machineset-rhv","machine-api-overview_creating-machineset-rhv","machineset-yaml-rhv_creating-machineset-rhv","machineset-creating_creating-machineset-rhv","creating-machineset-vsphere","machine-api-overview_creating-machineset-vsphere","machineset-yaml-vsphere_creating-machineset-vsphere","machineset-creating_creating-machineset-vsphere","/documentation/openshift_container_platform/4.8/html/machine_management/creating-machine-sets",{"title":5713,"visible":17,"weight":53,"urlFragment":5714,"anchor":23,"singlePageAnchor":5714,"subChapters":5715,"url":5718,"docTitle":5663},"Manually scaling a machine set","manually-scaling-machineset",[1013,5716,5717],"machineset-manually-scaling_manually-scaling-machineset","machineset-delete-policy_manually-scaling-machineset","/documentation/openshift_container_platform/4.8/html/machine_management/manually-scaling-machineset",{"title":5720,"visible":17,"weight":75,"urlFragment":5721,"anchor":23,"singlePageAnchor":5721,"subChapters":5722,"url":5727,"docTitle":5663},"Modifying a machine set","modifying-machineset",[5723,5724,5725,5726],"machineset-modifying_modifying-machineset","migrating-nodes-to-a-different-storage-domain-rhv_modifying-machineset","machineset-migrating-compute-nodes-to-diff-sd-rhv_modifying-machineset","machineset-migrating-control-plane-nodes-to-diff-sd-rhv_modifying-machineset","/documentation/openshift_container_platform/4.8/html/machine_management/modifying-machineset",{"title":5729,"visible":17,"weight":442,"urlFragment":5730,"anchor":23,"singlePageAnchor":5730,"subChapters":5731,"url":5734,"docTitle":5663},"Deleting a machine","deleting-machine",[5732,5733],"machine-delete_deleting-machine","additional-resources_unhealthy-etcd-member","/documentation/openshift_container_platform/4.8/html/machine_management/deleting-machine",{"title":5736,"visible":17,"weight":460,"urlFragment":5737,"anchor":23,"singlePageAnchor":5737,"subChapters":5738,"url":5747,"docTitle":5663},"Applying autoscaling to an OpenShift Container Platform cluster","applying-autoscaling",[5739,5740,5741,5742,5743,978,5744,5745,5746,1553],"cluster-autoscaler-about_applying-autoscaling","machine-autoscaler-about_applying-autoscaling","configuring-clusterautoscaler","cluster-autoscaler-cr_applying-autoscaling","ClusterAutoscaler-deploying_applying-autoscaling","configuring-machineautoscaler","machine-autoscaler-cr_applying-autoscaling","MachineAutoscaler-deploying_applying-autoscaling","/documentation/openshift_container_platform/4.8/html/machine_management/applying-autoscaling",{"title":5749,"visible":17,"weight":475,"urlFragment":5750,"anchor":23,"singlePageAnchor":5750,"subChapters":5751,"url":5770,"docTitle":5663},"Creating infrastructure machine sets","creating-infrastructure-machinesets",[5752,5753,5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,4840,5766,5767,5768,5769],"infrastructure-components_creating-infrastructure-machinesets","creating-infrastructure-machinesets-production","creating-infrastructure-machinesets-clouds","machineset-yaml-aws_creating-infrastructure-machinesets","machineset-yaml-azure_creating-infrastructure-machinesets","machineset-yaml-gcp_creating-infrastructure-machinesets","machineset-yaml-osp_creating-infrastructure-machinesets","machineset-yaml-rhv_creating-infrastructure-machinesets","machineset-yaml-vsphere_creating-infrastructure-machinesets","machineset-creating_creating-infrastructure-machinesets","creating-an-infra-node_creating-infrastructure-machinesets","creating-infra-machines_creating-infrastructure-machinesets","assigning-machineset-resources-to-infra-nodes","binding-infra-node-workloads-using-taints-tolerations_creating-infrastructure-machinesets","infrastructure-moving-router_creating-infrastructure-machinesets","infrastructure-moving-registry_creating-infrastructure-machinesets","infrastructure-moving-monitoring_creating-infrastructure-machinesets","infrastructure-moving-logging_creating-infrastructure-machinesets","/documentation/openshift_container_platform/4.8/html/machine_management/creating-infrastructure-machinesets",{"title":5772,"visible":17,"weight":876,"urlFragment":5773,"anchor":23,"singlePageAnchor":5773,"subChapters":5774,"url":5788,"docTitle":5663},"Adding RHEL compute machines to an OpenShift Container Platform cluster","adding-rhel-compute",[5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787],"rhel-compute-overview_adding-rhel-compute","rhel-compute-requirements_adding-rhel-compute","csr-management_adding-rhel-compute","adding-rhel-compute-preparing-image-cloud","rhel-images-aws_adding-rhel-compute","rhel-preparing-playbook-machine_adding-rhel-compute","rhel-preparing-node_adding-rhel-compute","rhel-attaching-instance-aws_adding-rhel-compute","rhel-worker-tag_adding-rhel-compute","rhel-adding-node_adding-rhel-compute","installation-approve-csrs_adding-rhel-compute","rhel-ansible-parameters_adding-rhel-compute","rhel-removing-rhcos_adding-rhel-compute","/documentation/openshift_container_platform/4.8/html/machine_management/adding-rhel-compute",{"title":5790,"visible":17,"weight":884,"urlFragment":5791,"anchor":23,"singlePageAnchor":5791,"subChapters":5792,"url":5804,"docTitle":5663},"Adding more RHEL compute machines to an OpenShift Container Platform cluster","more-rhel-compute",[5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803],"rhel-compute-overview_more-rhel-compute","rhel-compute-requirements_more-rhel-compute","csr-management_more-rhel-compute","more-rhel-compute-preparing-image-cloud","rhel-images-aws_more-rhel-compute","rhel-preparing-node_more-rhel-compute","rhel-attaching-instance-aws_more-rhel-compute","rhel-worker-tag_more-rhel-compute","rhel-adding-more-nodes_more-rhel-compute","installation-approve-csrs_more-rhel-compute","rhel-ansible-parameters_more-rhel-compute","/documentation/openshift_container_platform/4.8/html/machine_management/more-rhel-compute",{"title":5806,"visible":17,"weight":895,"urlFragment":5807,"anchor":23,"singlePageAnchor":5807,"subChapters":5808,"url":5827,"docTitle":5663},"User-provisioned infrastructure","user-provisioned-infrastructure-2",[5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,1024,5820,5821,5822,1045,5823,5824,5825,5826],"adding-compute-user-infra-general","upi-adding-compute-aws","upi-adding-compute-azure","upi-adding-compute-gcp","upi-adding-compute-vsphere","upi-adding-compute-bare-metal","adding-aws-compute-user-infra","prerequisites_adding-aws-compute-user-infra","machine-adding-aws-compute-cloudformation_adding-aws-compute-user-infra","installation-approve-csrs_adding-aws-compute-user-infra","adding-vsphere-compute-user-infra","machine-vsphere-machines_adding-vsphere-compute-user-infra","installation-approve-csrs_adding-vsphere-compute-user-infra","adding-bare-metal-compute-user-infra","creating-rhcos-machines-bare-metal","machine-user-infra-machines-iso_adding-bare-metal-compute-user-infra","machine-user-infra-machines-pxe_adding-bare-metal-compute-user-infra","installation-approve-csrs_adding-bare-metal-compute-user-infra","/documentation/openshift_container_platform/4.8/html/machine_management/user-provisioned-infrastructure-2",{"title":5829,"visible":17,"weight":906,"urlFragment":5830,"anchor":23,"singlePageAnchor":5830,"subChapters":5831,"url":5841,"docTitle":5663},"Deploying machine health checks","deploying-machine-health-checks",[5832,5833,5834,5835,4897,4898,5836,5837,5838,5839,5840],"machine-health-checks-about_deploying-machine-health-checks","machine-health-checks-limitations_deploying-machine-health-checks","machine-health-checks-resource_deploying-machine-health-checks","machine-health-checks-short-circuiting_deploying-machine-health-checks","machine-health-checks-creating_deploying-machine-health-checks","mgmt-power-remediation-baremetal-about_deploying-machine-health-checks","machine-health-checks-bare-metal_deploying-machine-health-checks","mgmt-understanding-remediation-process_deploying-machine-health-checks","mgmt-creating-mhc-baremetal_deploying-machine-health-checks","/documentation/openshift_container_platform/4.8/html/machine_management/deploying-machine-health-checks",{"title":5843,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":5844,"url":5845,"docTitle":5846,"sections":5847},"Metering",[],"/documentation/openshift_container_platform/4.8/html/metering/index","metering",[5848,5861,5873,5878,5908,5930,5937,5945,5964],{"title":5849,"visible":17,"weight":30,"urlFragment":5850,"anchor":23,"singlePageAnchor":5850,"subChapters":5851,"url":5860,"docTitle":5846},"About Metering","about-metering",[5852,5853,5854,5855,5856,5857,5858,5859],"metering-overview_about-metering","metering-overview-install-metering","metering-overview-upgrade-metering","metering-overview-use-metering","metering-overview-troubleshoot-metering","metering-overview-debug-metering","metering-overview-uninstall-metering","metering-resources_about-metering","/documentation/openshift_container_platform/4.8/html/metering/about-metering",{"title":5862,"visible":17,"weight":42,"urlFragment":5863,"anchor":23,"singlePageAnchor":5863,"subChapters":5864,"url":5872,"docTitle":5846},"Installing metering","installing-metering",[5865,5866,5867,5868,5869,1013,5870,5871],"metering-install-prerequisites_installing-metering","metering-install-operator_installing-metering","metering-install-web-console_installing-metering","metering-install-cli_installing-metering","metering-install-metering-stack_installing-metering","metering-install-verify_installing-metering","metering-install-additional-resources_installing-metering","/documentation/openshift_container_platform/4.8/html/metering/installing-metering",{"title":5874,"visible":17,"weight":53,"urlFragment":5875,"anchor":23,"singlePageAnchor":5875,"subChapters":5876,"url":5877,"docTitle":5846},"Upgrading metering","upgrading-metering",[1024],"/documentation/openshift_container_platform/4.8/html/metering/upgrading-metering",{"title":5879,"visible":17,"weight":75,"urlFragment":5880,"anchor":23,"singlePageAnchor":5880,"subChapters":5881,"url":5907,"docTitle":5846},"Configuring metering","configuring-metering",[5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906],"metering-about-configuring","metering-common-config-options","resource-requests-and-limits","node-selectors","metering-configure-persistent-storage","metering-store-data-in-s3_metering-configure-persistent-storage","metering-store-data-in-s3-compatible_metering-configure-persistent-storage","metering-store-data-in-azure_metering-configure-persistent-storage","metering-store-data-in-gcp_metering-configure-persistent-storage","metering-store-data-in-shared-volumes_metering-configure-persistent-storage","metering-configure-hive-metastore","metering-configure-persistentvolumes_metering-configure-hive-metastore","metering-configure-persistentvolumes-storage-class-hive_metering-configure-hive-metastore","metering-configure-persistentvolumes-volume-size-hive_metering-configure-hive-metastore","metering-use-mysql-or-postgresql-for-hive_metering-configure-hive-metastore","metering-configure-reporting-operator","metering-prometheus-connection_metering-configure-reporting-operator","metering-exposing-the-reporting-api_metering-configure-reporting-operator","metering-openshift-authentication_metering-configure-reporting-operator","metering-authenticate-using-service-account_metering-configure-reporting-operator","metering-authenticate-using-username-password_metering-configure-reporting-operator","metering-manually-configure-authentication_metering-configure-reporting-operator","metering-token-authentication_metering-configure-reporting-operator","metering-basic-authentication_metering-configure-reporting-operator","metering-configure-aws-billing-correlation","/documentation/openshift_container_platform/4.8/html/metering/configuring-metering",{"title":5909,"visible":17,"weight":442,"urlFragment":5910,"anchor":23,"singlePageAnchor":5910,"subChapters":5911,"url":5929,"docTitle":5846},"Reports","reports",[5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924,5925,5926,5927,5928],"metering-about-reports","metering-reports_metering-about-reports","metering-example-report-with-schedule_metering-about-reports","metering-example-report-without-schedule_metering-about-reports","metering-query_metering-about-reports","metering-schedule_metering-about-reports","metering-period_metering-about-reports","metering-reportingStart_metering-about-reports","metering-reportingEnd_metering-about-reports","metering-expiration_metering-about-reports","metering-runImmediately_metering-about-reports","metering-inputs_metering-about-reports","metering-roll-up-reports_metering-about-reports","metering-report-status_metering-about-reports","metering-storage-locations","storage-location-examples","default-storage-location","/documentation/openshift_container_platform/4.8/html/metering/reports",{"title":5931,"visible":17,"weight":460,"urlFragment":5932,"anchor":23,"singlePageAnchor":5932,"subChapters":5933,"url":5936,"docTitle":5846},"Using Metering","using-metering",[1045,5934,5935],"metering-writing-reports_using-metering","metering-viewing-report-results_using-metering","/documentation/openshift_container_platform/4.8/html/metering/using-metering",{"title":5938,"visible":17,"weight":475,"urlFragment":5939,"anchor":23,"singlePageAnchor":5939,"subChapters":5940,"url":5944,"docTitle":5846},"Examples of using metering","metering-usage-examples",[1096,5941,5942,5943],"metering-cluster-capacity-examples_metering-usage-examples","metering-cluster-usage-examples_metering-usage-examples","metering-cluster-utilization-examples_metering-usage-examples","/documentation/openshift_container_platform/4.8/html/metering/metering-usage-examples",{"title":5946,"visible":17,"weight":876,"urlFragment":5947,"anchor":23,"singlePageAnchor":5947,"subChapters":5948,"url":5963,"docTitle":5846},"Troubleshooting and debugging metering","metering-troubleshooting-debugging",[5949,5950,5951,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962],"metering-troubleshooting_metering-troubleshooting-debugging","metering-not-enough-compute-resources_metering-troubleshooting-debugging","metering-storageclass-not-configured_metering-troubleshooting-debugging","metering-secret-not-configured-correctly_metering-troubleshooting-debugging","metering-debugging_metering-troubleshooting-debugging","metering-get-reporting-operator-logs_metering-troubleshooting-debugging","metering-query-presto-using-presto-cli_metering-troubleshooting-debugging","metering-query-hive-using-beeline_metering-troubleshooting-debugging","metering-port-forward-hive-web-ui_metering-troubleshooting-debugging","metering-port-forward-hdfs_metering-troubleshooting-debugging","metering-ansible-operator_metering-troubleshooting-debugging","metering-accessing-ansible-logs_metering-troubleshooting-debugging","metering-checking-meteringconfig-status_metering-troubleshooting-debugging","metering-checking-meteringconfig-events_metering-troubleshooting-debugging","/documentation/openshift_container_platform/4.8/html/metering/metering-troubleshooting-debugging",{"title":5965,"visible":17,"weight":884,"urlFragment":5966,"anchor":23,"singlePageAnchor":5966,"subChapters":5967,"url":5971,"docTitle":5846},"Uninstalling metering","metering-uninstall",[5968,5969,5970],"metering-remove","metering-uninstall_metering-uninstall","metering-uninstall-crds_metering-uninstall","/documentation/openshift_container_platform/4.8/html/metering/metering-uninstall",{"title":5973,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":5974,"url":5975,"docTitle":5976,"sections":5977},"Web console",[],"/documentation/openshift_container_platform/4.8/html/web_console/index","web_console",[5978,5987,5993,5999,6005,6020,6030,6036],{"title":5979,"visible":17,"weight":30,"urlFragment":5980,"anchor":23,"singlePageAnchor":5980,"subChapters":5981,"url":5986,"docTitle":5976},"Web Console Overview","web-console-overview",[5982,5983,5984,5985],"about-administrator-perspective_web-console-overview","accessing-the-administrator-perspective_web-console-overview","about-developer-perspective_web-console-overview","accessing-developer-perspective_web-console-overview","/documentation/openshift_container_platform/4.8/html/web_console/web-console-overview",{"title":5988,"visible":17,"weight":42,"urlFragment":5989,"anchor":23,"singlePageAnchor":5989,"subChapters":5990,"url":5992,"docTitle":5976},"Accessing the web console","web-console",[1013,5991],"web-console-overview_web-console","/documentation/openshift_container_platform/4.8/html/web_console/web-console",{"title":5994,"visible":17,"weight":53,"urlFragment":5995,"anchor":23,"singlePageAnchor":5995,"subChapters":5996,"url":5998,"docTitle":5976},"Using the OpenShift Container Platform dashboard to get cluster information","using-dashboard-to-get-cluster-info",[5997],"virt-about-the-overview-dashboard_using-dashboard-to-get-cluster-info","/documentation/openshift_container_platform/4.8/html/web_console/using-dashboard-to-get-cluster-info",{"title":6000,"visible":17,"weight":75,"urlFragment":6001,"anchor":23,"singlePageAnchor":6001,"subChapters":6002,"url":6004,"docTitle":5976},"Configuring the web console in OpenShift Container Platform","configuring-web-console",[1024,6003],"web-console-configuration_configuring-web-console","/documentation/openshift_container_platform/4.8/html/web_console/configuring-web-console",{"title":6006,"visible":17,"weight":442,"urlFragment":6007,"anchor":23,"singlePageAnchor":6007,"subChapters":6008,"url":6019,"docTitle":5976},"Customizing the web console in OpenShift Container Platform","customizing-web-console",[6009,6010,6011,6012,6013,6014,6015,6016,6017,6018],"adding-a-custom-logo_customizing-web-console","creating-custom-links_customizing-web-console","customizing-the-web-console-url_customizing-web-console","customizing-the-console-route_customizing-web-console","customizing-the-download-route_customizing-web-console","customizing-the-login-page_customizing-web-console","defining-template-for-external-log-links_customizing-web-console","creating-custom-notification-banners_customizing-web-console","creating-custom-CLI-downloads_customizing-web-console","adding-yaml-examples-to-kube-resources_customizing-web-console","/documentation/openshift_container_platform/4.8/html/web_console/customizing-web-console",{"title":6021,"visible":17,"weight":460,"urlFragment":6022,"anchor":23,"singlePageAnchor":6022,"subChapters":6023,"url":6029,"docTitle":5976},"About the web terminal in the web console","odc-about-web-terminal",[6024,6025,6026,6027,6028],"odc-installing-web-terminal_odc-about-web-terminal","odc-using-web-terminal_odc-about-web-terminal","odc-uninstalling-web-terminal_odc-about-web-terminal","removing-the-web-terminal-operator-and-the-custom-resources-that-support-it","deleting-the-devworkspace-operator-dependency","/documentation/openshift_container_platform/4.8/html/web_console/odc-about-web-terminal",{"title":6031,"visible":17,"weight":475,"urlFragment":6032,"anchor":23,"singlePageAnchor":6032,"subChapters":6033,"url":6035,"docTitle":5976},"Disabling the web console in OpenShift Container Platform","disabling-web-console",[1045,6034],"web-console-disable_disabling-web-console","/documentation/openshift_container_platform/4.8/html/web_console/disabling-web-console",{"title":6037,"visible":17,"weight":876,"urlFragment":6038,"anchor":23,"singlePageAnchor":6038,"subChapters":6039,"url":6072,"docTitle":5976},"Creating quick start tutorials in the web console","creating-quick-start-tutorials",[6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,6070,6071],"understanding-quick-starts_creating-quick-start-tutorials","quick-start-user-workflow_creating-quick-start-tutorials","quick-start-components_creating-quick-start-tutorials","contributing-quick-starts_creating-quick-start-tutorials","viewing-quick-start-api-documentation_creating-quick-start-tutorials","understanding-quick-start-elements_creating-quick-start-tutorials","conclusion-quick-start-element_creating-quick-start-tutorials","description-quick-start-element_creating-quick-start-tutorials","displayName-quick-start-element_creating-quick-start-tutorials","duration-minutes-quick-start-element_creating-quick-start-tutorials","icon-quick-start-element_creating-quick-start-tutorials","introduction-quick-start-element_creating-quick-start-tutorials","adding-custom-icon-to-quick-start_creating-quick-start-tutorials","limiting-access-to-quick-starts_creating-quick-start-tutorials","linking-to-other-quick-starts_creating-quick-start-tutorials","supported-tags-for-quick-starts_creating-quick-start-tutorials","quick-start-highlighting-reference_creating-quick-start-tutorials","quick-start-highlighting-perspective-switcher_creating-quick-start-tutorials","quick-start-highlighting-admin-perspective_creating-quick-start-tutorials","quick-start-highlighting-dev-perspective_creating-quick-start-tutorials","quick-start-highlighting-common-nav_creating-quick-start-tutorials","quick-start-highlighting-masthead-links_creating-quick-start-tutorials","quick-starts-accessing-and-executing-code-snippets_creating-quick-start-tutorials","quick-starts-syntax-for-inline-code-snippets_creating-quick-start-tutorials","quick-starts-syntax-for-multi-line-code-snippets_creating-quick-start-tutorials","quick-start-content-guidelines_creating-quick-start-tutorials","quick-start-content-guidelines-card-copy_creating-quick-start-tutorials","quick-start-content-guidelines-introduction_creating-quick-start-tutorials","quick-start-content-guidelines-task-steps_creating-quick-start-tutorials","quick-start-content-guidelines-check-your-work-module_creating-quick-start-tutorials","quick-start-content-guidelines-formatting-UI-elements_creating-quick-start-tutorials","quick-start-tutorials-additional-resources","/documentation/openshift_container_platform/4.8/html/web_console/creating-quick-start-tutorials",{"title":6074,"visible":17,"categoryName":17,"sections":6075},"Reference",[6076],{"title":6077,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":6078,"url":6079,"docTitle":6080,"sections":6081},"CLI tools",[],"/documentation/openshift_container_platform/4.8/html/cli_tools/index","cli_tools",[6082,6088,6333,6416,6423,6514,6522],{"title":6083,"visible":17,"weight":30,"urlFragment":6084,"anchor":23,"singlePageAnchor":6084,"subChapters":6085,"url":6087,"docTitle":6080},"OpenShift Container Platform CLI tools overview","cli-tools-overview",[6086],"cli-tools-list","/documentation/openshift_container_platform/4.8/html/cli_tools/cli-tools-overview",{"title":6089,"visible":17,"weight":42,"urlFragment":6090,"anchor":23,"singlePageAnchor":6090,"subChapters":6091,"url":6332,"docTitle":6080},"OpenShift CLI (oc)","openshift-cli-oc",[6092,6093,6094,6095,6096,6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145,6146,6147,6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,6309,6310,6311,6312,6313,6314,6315,6316,6317,6318,6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331],"cli-getting-started","cli-about-cli_cli-developer-commands","installing-openshift-cli","cli-installing-cli_cli-developer-commands","cli-installing-cli-web-console_cli-developer-commands","cli-installing-cli-web-console-macos-linux_cli-developer-commands","cli-installing-cli-web-console-macos-windows_cli-developer-commands","cli-installing-cli-web-console-macos_cli-developer-commands","cli-installing-cli-rpm_cli-developer-commands","cli-installing-cli-brew_cli-developer-commands","cli-logging-in_cli-developer-commands","cli-using-cli_cli-developer-commands","creating-a-project","creating-a-new-app","viewing-pods","viewing-pod-logs","viewing-the-current-project","viewing-the-status-for-the-current-project","listing-supported-api-resources","cli-getting-help_cli-developer-commands","cli-logging-out_cli-developer-commands","cli-configuring-cli","cli-enabling-tab-completion","cli-enabling-tab-completion_cli-configuring-cli","cli-enabling-tab-completion-zsh_cli-configuring-cli","managing-cli-profiles","about-switches-between-cli-profiles_managing-cli-profiles","manual-configuration-of-cli-profiles_managing-cli-profiles","load-and-merge-rules_managing-cli-profiles","cli-extend-plugins","cli-writing-plugins_cli-extend-plugins","cli-installing-plugins_cli-extend-plugins","cli-developer-commands","openshift-cli-developer_cli-developer-commands","oc-annotate","oc-api-resources","oc-api-versions","oc-apply","oc-apply-edit-last-applied","oc-apply-set-last-applied","oc-apply-view-last-applied","oc-attach","oc-auth-can-i","oc-auth-reconcile","oc-autoscale","oc-cancel-build","oc-cluster-info","oc-cluster-info-dump","oc-completion","oc-config-current-context","oc-config-delete-cluster","oc-config-delete-context","oc-config-delete-user","oc-config-get-clusters","oc-config-get-contexts","oc-config-get-users","oc-config-rename-context","oc-config-set","oc-config-set-cluster","oc-config-set-context","oc-config-set-credentials","oc-config-unset","oc-config-use-context","oc-config-view","oc-cp","oc-create","oc-create-build","oc-create-clusterresourcequota","oc-create-clusterrole","oc-create-clusterrolebinding","oc-create-configmap","oc-create-cronjob","oc-create-deployment","oc-create-deploymentconfig","oc-create-identity","oc-create-imagestream","oc-create-imagestreamtag","oc-create-ingress","oc-create-job","oc-create-namespace","oc-create-poddisruptionbudget","oc-create-priorityclass","oc-create-quota","oc-create-role","oc-create-rolebinding","oc-create-route-edge","oc-create-route-passthrough","oc-create-route-reencrypt","oc-create-secret-docker-registry","oc-create-secret-generic","oc-create-secret-tls","oc-create-service-clusterip","oc-create-service-externalname","oc-create-service-loadbalancer","oc-create-service-nodeport","oc-create-serviceaccount","oc-create-user","oc-create-useridentitymapping","oc-debug","oc-delete","oc-describe","oc-diff","oc-edit","oc-ex-dockergc","oc-exec","oc-explain","oc-expose","oc-extract","oc-get","oc-idle","oc-image-append","oc-image-extract","oc-image-info","oc-image-mirror","oc-import-image","oc-kustomize","oc-label","oc-login","oc-logout","oc-logs","oc-new-app","oc-new-build","oc-new-project","oc-observe","oc-patch","oc-policy-add-role-to-user","oc-policy-scc-review","oc-policy-scc-subject-review","oc-port-forward","oc-process","oc-project","oc-projects","oc-proxy","oc-registry-info","oc-registry-login","oc-replace","oc-rollback","oc-rollout-cancel","oc-rollout-history","oc-rollout-latest","oc-rollout-pause","oc-rollout-restart","oc-rollout-resume","oc-rollout-retry","oc-rollout-status","oc-rollout-undo","oc-rsh","oc-rsync","oc-run","oc-scale","oc-secrets-link","oc-secrets-unlink","oc-serviceaccounts-create-kubeconfig","oc-serviceaccounts-get-token","oc-serviceaccounts-new-token","oc-set-build-hook","oc-set-build-secret","oc-set-data","oc-set-deployment-hook","oc-set-env","oc-set-image","oc-set-image-lookup","oc-set-probe","oc-set-resources","oc-set-route-backends","oc-set-selector","oc-set-serviceaccount","oc-set-subject","oc-set-triggers","oc-set-volumes","oc-start-build","oc-status","oc-tag","oc-version","oc-wait","oc-whoami","additional-resources_cli-developer-commands","cli-administrator-commands","openshift-cli-admin_cli-administrator-commands","oc-adm-build-chain","oc-adm-catalog-mirror","oc-adm-completion","oc-adm-config-current-context","oc-adm-config-delete-cluster","oc-adm-config-delete-context","oc-adm-config-delete-user","oc-adm-config-get-clusters","oc-adm-config-get-contexts","oc-adm-config-get-users","oc-adm-config-rename-context","oc-adm-config-set","oc-adm-config-set-cluster","oc-adm-config-set-context","oc-adm-config-set-credentials","oc-adm-config-unset","oc-adm-config-use-context","oc-adm-config-view","oc-adm-cordon","oc-adm-create-bootstrap-project-template","oc-adm-create-error-template","oc-adm-create-login-template","oc-adm-create-provider-selection-template","oc-adm-drain","oc-adm-groups-add-users","oc-adm-groups-new","oc-adm-groups-prune","oc-adm-groups-remove-users","oc-adm-groups-sync","oc-adm-inspect","oc-adm-migrate-template-instances","oc-adm-must-gather","oc-adm-new-project","oc-adm-node-logs","oc-adm-pod-network-isolate-projects","oc-adm-pod-network-join-projects","oc-adm-pod-network-make-projects-global","oc-adm-policy-add-role-to-user","oc-adm-policy-add-scc-to-group","oc-adm-policy-add-scc-to-user","oc-adm-policy-scc-review","oc-adm-policy-scc-subject-review","oc-adm-prune-builds","oc-adm-prune-deployments","oc-adm-prune-groups","oc-adm-prune-images","oc-adm-release-extract","oc-adm-release-info","oc-adm-release-mirror","oc-adm-release-new","oc-adm-taint","oc-adm-top-images","oc-adm-top-imagestreams","oc-adm-top-node","oc-adm-top-pod","oc-adm-uncordon","oc-adm-verify-image-signature","additional-resources_cli-administrator-commands","usage-oc-kubectl","the-oc-binary","the-kubectl-binary","/documentation/openshift_container_platform/4.8/html/cli_tools/openshift-cli-oc",{"title":6334,"visible":17,"weight":53,"urlFragment":6335,"anchor":23,"singlePageAnchor":6335,"subChapters":6336,"url":6415,"docTitle":6080},"Developer CLI (odo)","developer-cli-odo",[6337,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,624,6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414],"odo-release-notes","odo-notable-improvements_odo-release-notes","odo-fixed-issues_odo-release-notes","odo-getting-support_odo-release-notes","understanding-odo","odo-features_understanding-odo","odo-core-concepts_understanding-odo","odo-listing-components_understanding-odo","odo-telemetry_understanding-odo","installing-odo","installing-odo-on-linux_installing-odo","installing-odo-on-windows_installing-odo","installing-odo-on-macos_installing-odo","installing-odo-on-vs-code_installing-odo","installing-odo-on-linux-rpm_installing-odo","configuring-the-odo-cli","developer-cli-odo-view-config_configuring-the-odo-cli","developer-cli-odo-set-config_configuring-the-odo-cli","developer-cli-odo-unset-config_configuring-the-odo-cli","developer-cli-odo-preference-table_configuring-the-odo-cli","ignoring-files-or-patterns_configuring-the-odo-cli","odo-cli-reference","odo-build-images_odo-cli-reference","odo-catalog_odo-cli-reference","components","listing-components","getting-information-about-a-component","listing-services","searching-services","getting-information-about-a-service","odo-create_odo-cli-reference","creating-a-component","starter-projects","using-an-existing-devfile","interactive-creation","odo-delete_odo-cli-reference","deleting-a-component","undeploying-devfile-kubernetes-components","delete-all","available-flags","odo-deploy_odo-cli-reference","odo-link_odo-cli-reference","various-linking-options","default-behavior","the-literal-inlined-literal-flag","the-literal-map-literal-flag","the-literal-bind-as-files-literal-flag","examples","default-literal-odo-link-literal","using-odo-link-with-the-inlined-flag","custom-bindings","to-inline-or-not","binding-as-files","bind-as-files-examples","using-the-default-odo-link","using-literal-inlined-literal","custom-bindings-2","odo-registry_odo-cli-reference","listing-the-registries","adding-a-registry","deleting-a-registry","updating-a-registry","odo-service_odo-cli-reference","creating-a-new-service","inlining-the-manifest","configuring-the-service","using-command-line-arguments","using-a-file","deleting-a-service","listing-services-2","getting-information-about-a-service-2","odo-storage_odo-cli-reference","adding-a-storage-volume","listing-the-storage-volumes","deleting-a-storage-volume","adding-storage-to-specific-container","odo-flags_odo-cli-reference","odo-json-output_odo-cli-reference","/documentation/openshift_container_platform/4.8/html/cli_tools/developer-cli-odo",{"title":6417,"visible":17,"weight":75,"urlFragment":6418,"anchor":23,"singlePageAnchor":6418,"subChapters":6419,"url":6422,"docTitle":6080},"Knative CLI for use with OpenShift Serverless","kn-cli-tools",[6420,6421],"kn-cli-tools-key-features","kn-cli-tools-installing-kn","/documentation/openshift_container_platform/4.8/html/cli_tools/kn-cli-tools",{"title":6424,"visible":17,"weight":442,"urlFragment":6425,"anchor":23,"singlePageAnchor":6425,"subChapters":6426,"url":6513,"docTitle":6080},"Pipelines CLI (tkn)","pipelines-cli-tkn",[6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511,6512],"installing-tkn","installing-tkn-on-linux","installing-tkn-on-linux-using-rpm","installing-tkn-on-windows","installing-tkn-on-macos","op-configuring-tkn","op-tkn-enabling-tab-completion_configuring-tkn","op-tkn-reference","basic-syntax","global-options","op-tkn-utility-commands_op-tkn-reference","tkn","completion-shell","version","op-tkn-pipeline-management_op-tkn-reference","pipeline","pipeline-delete","pipeline-describe","pipeline-list","pipeline-logs","pipeline-start","op-tkn-pipeline-run_op-tkn-reference","pipelinerun","pipelinerun-cancel","pipelinerun-delete","pipelinerun-describe","pipelinerun-list","pipelinerun-logs","op-tkn-task-management_op-tkn-reference","task","task-delete","task-describe","task-list","task-logs","task-start","op-tkn-task-run_op-tkn-reference","taskrun","taskrun-cancel","taskrun-delete","taskrun-describe","taskrun-list","taskrun-logs","op-tkn-condition-management_op-tkn-reference","condition","condition-delete","condition-describe","condition-list","op-tkn-pipeline-resource-management_op-tkn-reference","resource","resource-create","resource-delete","resource-describe","resource-list","op-tkn-clustertask-management-commands_op-tkn-reference","clustertask","clustertask-delete","clustertask-describe","clustertask-list","clustertask-start","op-tkn-trigger-management_op-tkn-reference","eventlistener","eventlistener-delete","eventlistener-describe","eventlistener-list","eventlistener-logs","triggerbinding","triggerbinding-delete","triggerbinding-describe","triggerbinding-list","triggertemplate","triggertemplate-delete","triggertemplate-describe","triggertemplate-list","clustertriggerbinding","clustertriggerbinding-delete","clustertriggerbinding-describe","clustertriggerbinding-list","op-tkn-hub-interaction_op-tkn-reference","hub","hub-downgrade","hub-get","hub-info","hub-install","hub-reinstall","hub-search","hub-upgrade","/documentation/openshift_container_platform/4.8/html/cli_tools/pipelines-cli-tkn",{"title":6515,"visible":17,"weight":460,"urlFragment":6516,"anchor":23,"singlePageAnchor":6516,"subChapters":6517,"url":6521,"docTitle":6080},"opm CLI","opm-cli",[6518,6519,6520],"olm-about-opm_opm-cli","olm-installing-opm_opm-cli","opm-addtl-resources","/documentation/openshift_container_platform/4.8/html/cli_tools/opm-cli",{"title":6523,"visible":17,"weight":475,"urlFragment":6524,"anchor":23,"singlePageAnchor":6524,"subChapters":6525,"url":6544,"docTitle":6080},"Operator SDK","operator-sdk",[6526,6527,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543],"cli-osdk-install","osdk-installing-cli-linux-macos_cli-osdk-install","cli-osdk-ref","osdk-cli-ref-bundle_cli-osdk-ref","osdk-cli-ref-bundle-validate_cli-osdk-ref","osdk-cli-ref-cleanup_cli-osdk-ref","osdk-cli-ref-completion_cli-osdk-ref","osdk-cli-ref-create_cli-osdk-ref","osdk-cli-ref-create-api_cli-osdk-ref","osdk-cli-ref-generate_cli-osdk-ref","osdk-cli-ref-generate-bundle_cli-osdk-ref","osdk-cli-ref-generate-kustomize_cli-osdk-ref","osdk-cli-ref-generate-kustomize-manifests_cli-osdk-ref","osdk-cli-ref-init_cli-osdk-ref","osdk-cli-ref-run_cli-osdk-ref","osdk-cli-ref-run-bundle_cli-osdk-ref","osdk-cli-ref-run-bundle-upgrade_cli-osdk-ref","osdk-cli-ref-scorecard_cli-osdk-ref","/documentation/openshift_container_platform/4.8/html/cli_tools/operator-sdk",{"title":6546,"visible":17,"categoryName":17,"sections":6547},"Develop",[6548,6818,7233,7441,7822,7884],{"title":6549,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":6550,"url":6551,"docTitle":6552,"sections":6553},"Building Applications",[],"/documentation/openshift_container_platform/4.8/html/building_applications/index","building_applications",[6554,6565,6591,6628,6644,6670,6722,6742,6752,6759,6770,6777,6794,6803,6809],{"title":6555,"visible":17,"weight":30,"urlFragment":6556,"anchor":23,"singlePageAnchor":6556,"subChapters":6557,"url":6564,"docTitle":6552},"Building applications overview","building-applications-overview",[6558,6559,6560,6561,6562,6563],"working-on-a-project","working-on-application","creating-application","maintaining-application","deploying-application","redhat-marketplace","/documentation/openshift_container_platform/4.8/html/building_applications/building-applications-overview",{"title":6566,"visible":17,"weight":42,"urlFragment":6567,"anchor":23,"singlePageAnchor":6567,"subChapters":6568,"url":6590,"docTitle":6552},"Projects","projects",[6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589],"working-with-projects","creating-a-project-using-the-web-console_projects","odc-creating-projects-using-developer-perspective_projects","creating-a-project-using-the-CLI_projects","viewing-a-project-using-the-web-console_projects","viewing-a-project-using-the-CLI_projects","odc-providing-project-permissions-using-developer-perspective_projects","odc-customizing-available-cluster-roles-using-developer-perspective_projects","adding-to-a-project_projects","checking-project-status-using-the-web-console_projects","checking-project-status-using-the-CLI_projects","deleting-a-project-using-the-web-console_projects","deleting-a-project-using-the-CLI_projects","creating-project-other-user","authentication-api-impersonation_creating-project-other-user","impersonation-project-creation_creating-project-other-user","configuring-project-creation","about-project-creation_configuring-project-creation","modifying-template-for-new-projects_configuring-project-creation","disabling-project-self-provisioning_configuring-project-creation","customizing-project-request-message_configuring-project-creation","/documentation/openshift_container_platform/4.8/html/building_applications/projects",{"title":6592,"visible":17,"weight":53,"urlFragment":6593,"anchor":23,"singlePageAnchor":6593,"subChapters":6594,"url":6627,"docTitle":6552},"Creating Applications","creating-applications",[6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626],"odc-creating-applications-using-developer-perspective","prerequisites_odc-creating-applications-using-developer-perspective","odc-creating-sample-applications_odc-creating-applications-using-developer-perspective","odc-using-quickstarts_odc-creating-applications-using-developer-perspective","odc-importing-codebase-from-git-to-create-application_odc-creating-applications-using-developer-perspective","odc-deploying-java-applications_odc-creating-applications-using-developer-perspective","odc-using-the-developer-catalog-to-add-services-or-components_odc-creating-applications-using-developer-perspective","additional-resources_odc-creating-applications-using-developer-perspective","creating-apps-from-installed-operators","olm-creating-etcd-cluster-from-operator_creating-apps-from-installed-operators","creating-applications-using-cli","applications-create-using-cli-source-code_creating-applications-using-cli","local","remote","build-strategy-detection","language-detection","applications-create-using-cli-image_creating-applications-using-cli","docker-hub-mysql-image","image-in-a-private-registry","existing-image-stream-and-optional-image-stream-tag","applications-create-using-cli-template_creating-applications-using-cli","template-parameters","applications-create-using-cli-modify_creating-applications-using-cli","specifying-environment-variables","specifying-build-environment-variables","specifying-labels","viewing-the-output-without-creation","creating-objects-with-different-names","creating-objects-in-a-different-project","creating-multiple-objects","grouping-images-and-source-in-a-single-pod","searching-for-images-templates-and-other-inputs","/documentation/openshift_container_platform/4.8/html/building_applications/creating-applications",{"title":6629,"visible":17,"weight":75,"urlFragment":6630,"anchor":23,"singlePageAnchor":6630,"subChapters":6631,"url":6643,"docTitle":6552},"Viewing application composition using the Topology view","odc-viewing-application-composition-using-topology-view",[1013,6632,6633,6634,6635,6636,6637,6638,6639,6640,6641,6642,1553],"odc-viewing-application-topology_viewing-application-composition-using-topology-view","odc-interacting-with-applications-and-components_viewing-application-composition-using-topology-view","odc-scaling-application-pods-and-checking-builds-and-routes_viewing-application-composition-using-topology-view","odc-adding-components-to-an-existing-project_viewing-application-composition-using-topology-view","odc-grouping-multiple-components_viewing-application-composition-using-topology-view","odc-adding-services-to-your-application_viewing-application-composition-using-topology-view","odc-removing-services-from-your-application_viewing-application-composition-using-topology-view","odc-connecting-components_viewing-application-composition-using-topology-view","creating-a-visual-connection-between-components","creating-a-binding-connection-between-components","odc-labels-and-annotations-used-for-topology-view_viewing-application-composition-using-topology-view","/documentation/openshift_container_platform/4.8/html/building_applications/odc-viewing-application-composition-using-topology-view",{"title":6645,"visible":17,"weight":442,"urlFragment":6646,"anchor":23,"singlePageAnchor":6646,"subChapters":6647,"url":6669,"docTitle":6552},"Working with Helm charts","working-with-helm-charts",[6648,6649,6650,1605,6651,6652,6653,6654,6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,1024,6666,6667,6668],"understanding-helm","key-features","red-hat-certification-of-helm-charts-for-openshift","installing-helm","on-linux","on-windows-7-8","on-windows-10","on-macos","configuring-custom-helm-chart-repositories","installing-a-helm-chart-on-an-openshift-cluster_configuring-custom-helm-chart-repositories","odc-installing-helm-charts-using-developer-perspective_configuring-custom-helm-chart-repositories","using-helm-in-the-web-terminal","creating-a-custom-helm-chart-on-openshift_configuring-custom-helm-chart-repositories","adding-helm-chart-repositories_configuring-custom-helm-chart-repositories","creating-credentials-and-certificates-to-add-helm-repositories_configuring-custom-helm-chart-repositories","filtering-helm-charts-by-certification-level_configuring-custom-helm-chart-repositories","helm-disabling-helm-chart-repositories_configuring-custom-helm-chart-repositories","odc-working-with-helm-releases","odc-upgrading-helm-release_working-with-helm-releases","odc-rolling-back-helm-release_working-with-helm-releases","odc-uninstalling-helm-release_working-with-helm-releases","/documentation/openshift_container_platform/4.8/html/building_applications/working-with-helm-charts",{"title":6671,"visible":17,"weight":460,"urlFragment":6672,"anchor":23,"singlePageAnchor":6672,"subChapters":6673,"url":6721,"docTitle":6552},"Deployments","deployments",[6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720],"what-deployments-are","what-deployments-are-build-blocks","deployments-replicationcontrollers_what-deployments-are","deployments-repliasets_what-deployments-are","deployments-and-deploymentconfigs_what-deployments-are","deployments-kube-deployments_what-deployments-are","deployments-comparing-deploymentconfigs_what-deployments-are","deployments-design_what-deployments-are","delpoymentconfigs-specific-features_what-deployments-are","delpoyments-specific-features_what-deployments-are","deployment-operations","deploymentconfig-operations","deployments-starting-a-deployment_deployment-operations","deployments-viewing-a-deployment_deployment-operations","deployments-retrying-deployment_deployment-operations","deployments-rolling-back_deployment-operations","deployments-exe-cmd-in-container_deployment-operations","deployments-viewing-logs_deployment-operations","deployments-triggers_deployment-operations","deployments-setting-triggers_deployment-operations","deployments-setting-resources_deployment-operations","deployments-scaling-manually_deployment-operations","deployments-accessing-private-repos_deployment-operations","deployments-assigning-pods-to-nodes_deployment-operations","deployments-running-pod-svc-acct_deployment-operations","deployment-strategies","deployments-rolling-strategy_deployment-strategies","deployments-canary-deployments_deployment-strategies","deployments-creating-rolling-deployment_deployment-strategies","odc-starting-rolling-deployment_deployment-strategies","deployments-recreate-strategy_deployment-strategies","odc-starting-recreate-deployment_deployment-strategies","deployments-custom-strategy_deployment-strategies","deployments-lifecycle-hooks_deployment-strategies","deployments-setting-lifecycle-hooks_deployment-strategies","route-based-deployment-strategies","deployments-proxy-shard_route-based-deployment-strategies","deployments-n1-compatibility_route-based-deployment-strategies","deployments-graceful-termination_route-based-deployment-strategies","deployments-blue-green_route-based-deployment-strategies","deployments-blue-green-setting-up_route-based-deployment-strategies","deployments-ab-testing_route-based-deployment-strategies","deployments-ab-testing-lb_route-based-deployment-strategies","deployments-ab-testing-lb-web_route-based-deployment-strategies","deployments-ab-testing-lb-web-new-route_route-based-deployment-strategies","deployments-ab-testing-lb-cli_route-based-deployment-strategies","deployments-ab-one-service-multi-dc_route-based-deployment-strategies","/documentation/openshift_container_platform/4.8/html/building_applications/deployments",{"title":6723,"visible":17,"weight":475,"urlFragment":6724,"anchor":23,"singlePageAnchor":6724,"subChapters":6725,"url":6741,"docTitle":6552},"Quotas","quotas",[6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740],"quotas-setting-per-project","quotas-resources-managed_quotas-setting-per-project","quotas-scopes_quotas-setting-per-project","quota-enforcement_quotas-setting-per-project","quotas-requests-vs-limits_quotas-setting-per-project","quotas-sample-resource-quota-definitions_quotas-setting-per-project","quotas-creating-a-quota_quotas-setting-per-project","quota-creating-object-count-quotas_quotas-setting-per-project","setting-resource-quota-for-extended-resources_quotas-setting-per-project","quota-viewing-quotas_quotas-setting-per-project","configuring-explicit-resource-quotas_quotas-setting-per-project","setting-quotas-across-multiple-projects","quotas-setting-projects_setting-quotas-across-multiple-projects","quotas-viewing-clusterresourcequotas_setting-quotas-across-multiple-projects","quotas-selection-granularity_setting-quotas-across-multiple-projects","/documentation/openshift_container_platform/4.8/html/building_applications/quotas",{"title":6743,"visible":17,"weight":876,"urlFragment":6744,"anchor":23,"singlePageAnchor":6744,"subChapters":6745,"url":6751,"docTitle":6552},"Using config maps with applications","config-maps",[6746,6747,6748,6749,6750],"nodes-pods-configmap-overview_config-maps","nodes-pods-config-maps-consuming-configmap-in-pods","nodes-pods-configmaps-use-case-consuming-in-env-vars_config-maps","nodes-pods-configmaps-use-case-setting-command-line-arguments_config-maps","nodes-pods-configmaps-use-case-consuming-in-volumes_config-maps","/documentation/openshift_container_platform/4.8/html/building_applications/config-maps",{"title":6753,"visible":17,"weight":884,"urlFragment":6754,"anchor":23,"singlePageAnchor":6754,"subChapters":6755,"url":6758,"docTitle":6552},"Monitoring project and application metrics using the Developer perspective","odc-monitoring-project-and-application-metrics-using-developer-perspective",[1045,6756,6757,1633],"odc-monitoring-your-project-metrics_monitoring-project-and-application-metrics-using-developer-perspective","odc-monitoring-your-application-metrics_monitoring-project-and-application-metrics-using-developer-perspective","/documentation/openshift_container_platform/4.8/html/building_applications/odc-monitoring-project-and-application-metrics-using-developer-perspective",{"title":6760,"visible":17,"weight":895,"urlFragment":6761,"anchor":23,"singlePageAnchor":6761,"subChapters":6762,"url":6769,"docTitle":6552},"Monitoring application health by using health checks","application-health",[6763,6764,6765,6766,6767,6768],"application-health-about_application-health","application-health-configuring_application-health","odc-monitoring-application-health-using-developer-perspective","odc-adding-health-checks","odc-editing-health-checks","odc-monitoring-health-checks","/documentation/openshift_container_platform/4.8/html/building_applications/application-health",{"title":6771,"visible":17,"weight":906,"urlFragment":6772,"anchor":23,"singlePageAnchor":6772,"subChapters":6773,"url":6776,"docTitle":6552},"Editing applications","odc-editing-applications",[1096,6774,6775],"odc-editing-source-code-using-developer-perspective_odc-editing-applications","odc-editing-application-configuration-using-developer-perspective_odc-editing-applications","/documentation/openshift_container_platform/4.8/html/building_applications/odc-editing-applications",{"title":6778,"visible":17,"weight":913,"urlFragment":6779,"anchor":23,"singlePageAnchor":6779,"subChapters":6780,"url":6793,"docTitle":6552},"Pruning objects to reclaim resources","pruning-objects",[6781,6782,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792],"pruning-basic-operations_pruning-objects","pruning-groups_pruning-objects","pruning-deployments_pruning-objects","pruning-builds_pruning-objects","pruning-images_pruning-objects","pruning-images-manual_pruning-objects","pruning-images-conditions_pruning-objects","pruning-images-running-operation_pruning-objects","pruning-images-secure-insecure_pruning-objects","pruning-images-problems_pruning-objects","pruning-hard-pruning-registry_pruning-objects","pruning-cronjobs_pruning-objects","/documentation/openshift_container_platform/4.8/html/building_applications/pruning-objects",{"title":6795,"visible":17,"weight":922,"urlFragment":6796,"anchor":23,"singlePageAnchor":6796,"subChapters":6797,"url":6802,"docTitle":6552},"Idling applications","idling-applications",[6798,6799,6800,6801],"idle-idling-applications_idling-applications","idle-idling-applications-single_idling-applications","idle-idling-applications-multiple_idling-applications","idle-unidling-applications_idling-applications","/documentation/openshift_container_platform/4.8/html/building_applications/idling-applications",{"title":6804,"visible":17,"weight":2806,"urlFragment":6805,"anchor":23,"singlePageAnchor":6805,"subChapters":6806,"url":6808,"docTitle":6552},"Deleting applications","odc-deleting-applications",[6807],"odc-deleting-applications-using-developer-perspective_odc-deleting-applications","/documentation/openshift_container_platform/4.8/html/building_applications/odc-deleting-applications",{"title":6810,"visible":17,"weight":3071,"urlFragment":6811,"anchor":23,"singlePageAnchor":6811,"subChapters":6812,"url":6817,"docTitle":6552},"Using the Red Hat Marketplace","red-hat-marketplace",[6813,6814,6815,6816],"red-hat-marketplace-features_red-hat-marketplace","marketplace-clusters_red-hat-marketplace","marketplace-install-applications_red-hat-marketplace","marketplace-deploy_red-hat-marketplace","/documentation/openshift_container_platform/4.8/html/building_applications/red-hat-marketplace",{"title":6819,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":6820,"url":6821,"docTitle":6822,"sections":6823},"CI/CD",[],"/documentation/openshift_container_platform/4.8/html/cicd/index","cicd",[6824,6833,6983,6999,7108],{"title":6825,"visible":17,"weight":30,"urlFragment":6826,"anchor":23,"singlePageAnchor":6826,"subChapters":6827,"url":6832,"docTitle":6822},"OpenShift Container Platform CI/CD overview","ci-cd-overview",[6828,6829,6830,6831],"openshift-builds","openshift-pipelines","openshift-gitops","jenkins-ci-cd","/documentation/openshift_container_platform/4.8/html/cicd/ci-cd-overview",{"title":6834,"visible":17,"weight":42,"urlFragment":6835,"anchor":23,"singlePageAnchor":6835,"subChapters":6836,"url":6982,"docTitle":6822},"Builds","builds",[6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,6905,6906,6907,6908,6909,6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,1013,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968,6969,1553,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,1605],"understanding-image-builds","builds-about_understanding-image-builds","builds-strategy-docker-build_understanding-image-builds","builds-strategy-s2i-build_understanding-image-builds","builds-strategy-custom-build_understanding-image-builds","builds-strategy-pipeline-build_understanding-image-builds","understanding-buildconfigs","builds-buildconfig_understanding-builds","creating-build-inputs","builds-define-build-inputs_creating-build-inputs","builds-dockerfile-source_creating-build-inputs","builds-image-source_creating-build-inputs","builds-source-code_creating-build-inputs","builds-using-proxy-git-cloning_creating-build-inputs","builds-adding-source-clone-secrets_creating-build-inputs","builds-automatically-add-source-clone-secrets_creating-build-inputs","builds-manually-add-source-clone-secrets_creating-build-inputs","builds-gitconfig-file_creating-build-inputs","builds-gitconfig-file-secured-git_creating-build-inputs","builds-source-secret-basic-auth_creating-build-inputs","builds-source-secret-ssh-key-auth_creating-build-inputs","builds-source-secret-trusted-ca_creating-build-inputs","builds-source-secret-combinations_creating-build-inputs","builds-source-secret-combinations-ssh-gitconfig_creating-build-inputs","builds-source-secret-combinations-gitconfig-ca_creating-build-inputs","builds-source-secret-combinations-basic-auth-ca_creating-build-inputs","builds-source-secret-combinations-basic-auth-gitconfig_creating-build-inputs","builds-source-secret-combinations-basic-auth-gitconfig-ca_creating-build-inputs","builds-binary-source_creating-build-inputs","builds-input-secrets-configmaps_creating-build-inputs","builds-secrets-overview_creating-build-inputs","builds-secrets-overview-properties_creating-build-inputs","builds-secrets-overview-types_creating-build-inputs","builds-secrets-overview-updates_creating-build-inputs","builds-creating-secrets_creating-build-inputs","builds-using-secrets_creating-build-inputs","builds-adding-input-secrets-configmaps_creating-build-inputs","builds-source-to-image_creating-build-inputs","builds-docker-strategy_creating-build-inputs","builds-custom-strategy_creating-build-inputs","builds-using-external-artifacts_creating-build-inputs","builds-docker-credentials-private-registries_creating-build-inputs","builds-build-environment_creating-build-inputs","builds-using-build-fields-as-environment-variables_creating-build-inputs","builds-using-secrets-as-environment-variables_creating-build-inputs","builds-service-serving-certificate-secrets_creating-build-inputs","builds-secrets-restrictions_creating-build-inputs","managing-build-output","builds-docker-source-build-output_managing-build-output","builds-output-image-environment-variables_managing-build-output","builds-output-image-labels_managing-build-output","build-strategies","builds-strategy-docker-build_build-strategies","builds-strategy-docker-from-image_build-strategies","builds-strategy-dockerfile-path_build-strategies","builds-strategy-docker-environment-variables_build-strategies","builds-strategy-docker-build-arguments_build-strategies","builds-strategy-docker-squash-layers_build-strategies","builds-strategy-s2i-build_build-strategies","builds-strategy-s2i-incremental-builds_build-strategies","builds-strategy-s2i-override-builder-image-scripts_build-strategies","builds-strategy-s2i-environment-variables_build-strategies","builds-strategy-s2i-environment-files_build-strategies","builds-strategy-s2i-buildconfig-environment_build-strategies","builds-strategy-s2i-ignore-source-files_build-strategies","images-create-s2i_build-strategies","images-create-s2i-build_build-strategies","images-create-s2i-scripts_build-strategies","builds-strategy-custom-build_build-strategies","builds-strategy-custom-from-image_build-strategies","builds-strategy-custom-secrets_build-strategies","builds-strategy-custom-environment-variables_build-strategies","images-custom_build-strategies","images-custom-builder-image-ref_build-strategies","images-custom-builder-flow_build-strategies","builds-strategy-pipeline-build_build-strategies","builds-understanding-openshift-pipeline_build-strategies","builds-strategy-pipeline-providing-jenkinsfile_build-strategies","builds-strategy-pipeline-environment-variables_build-strategies","builds-strategy-pipeline-mapping-buildconfig-jenkins_build-strategies","builds-tutorial-pipeline_build-strategies","builds-strategy-secrets-web-console_build-strategies","builds-strategy-enable-pulling-pushing_build-strategies","custom-builds-buildah","builds-create-custom-build-artifacts_custom-builds-buildah","builds-build-custom-builder-image_custom-builds-buildah","builds-use-custom-builder-image_custom-builds-buildah","basic-build-operations","builds-basic-start-build_basic-build-operations","builds-basic-start-re-run_basic-build-operations","builds-basic-start-logs_basic-build-operations","builds-basic-start-environment-variable_basic-build-operations","builds-basic-start-source_basic-build-operations","builds-basic-cancel-build_basic-build-operations","builds-basic-cancel-multiple_basic-build-operations","builds-basic-cancel-all_basic-build-operations","builds-basic-cancel-all-state_basic-build-operations","builds-basic-delete-buildconfig_basic-build-operations","builds-basic-view-build-details_basic-build-operations","builds-basic-access-build-logs_basic-build-operations","builds-basic-access-buildconfig-logs_basic-build-operations","builds-basic-access-buildconfig-version-logs_basic-build-operations","builds-basic-access-build-verbosity_basic-build-operations","triggering-builds-build-hooks","builds-triggers_triggering-builds-build-hooks","builds-webhook-triggers_triggering-builds-build-hooks","builds-using-github-webhooks_triggering-builds-build-hooks","builds-using-gitlab-webhooks_triggering-builds-build-hooks","builds-using-bitbucket-webhooks_triggering-builds-build-hooks","builds-using-generic-webhooks_triggering-builds-build-hooks","builds-displaying-webhook-urls_triggering-builds-build-hooks","builds-using-image-change-triggers_triggering-builds-build-hooks","builds-image-change-trigger-identification_triggering-builds-build-hooks","builds-configuration-change-triggers_triggering-builds-build-hooks","builds-setting-triggers-manually_triggering-builds-build-hooks","builds-build-hooks_triggering-builds-build-hooks","builds-configuring-post-commit-build-hooks_triggering-builds-build-hooks","builds-using-cli-post-commit-build-hooks_triggering-builds-build-hooks","advanced-build-operations","builds-setting-build-resources_advanced-build-operations","builds-setting-maximum-duration_advanced-build-operations","builds-assigning-builds-to-nodes_advanced-build-operations","builds-chaining-builds_advanced-build-operations","builds-build-pruning_advanced-build-operations","builds-build-run-policy_advanced-build-operations","running-entitled-builds","builds-create-imagestreamtag_running-entitled-builds","builds-source-secrets-entitlements_running-entitled-builds","running-builds-with-subscription-manager","builds-strategy-docker-entitled-subman_running-entitled-builds","running-builds-with-red-hat-satellite-subscriptions","builds-source-input-satellite-config_running-entitled-builds","builds-strategy-docker-entitled-satellite_running-entitled-builds","securing-builds-by-strategy","builds-disabling-build-strategy-globally_securing-builds-by-strategy","builds-restricting-build-strategy-globally_securing-builds-by-strategy","builds-restricting-build-strategy-to-user_securing-builds-by-strategy","build-configuration","builds-configuration-parameters_build-configuration","builds-configuration-file_build-configuration","troubleshooting-builds_build-configuration","builds-troubleshooting-access-resources_troubleshooting-builds","builds-troubleshooting-service-certificate-generation_troubleshooting-builds","setting-up-trusted-ca","configmap-adding-ca_setting-up-trusted-ca","/documentation/openshift_container_platform/4.8/html/cicd/builds",{"title":6984,"visible":17,"weight":53,"urlFragment":6985,"anchor":23,"singlePageAnchor":6985,"subChapters":6986,"url":6998,"docTitle":6822},"Migrating from Jenkins to Tekton","migrating-from-jenkins-to-tekton",[6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997],"migrating-from-jenkins-to-tekton_setting-up-trusted-ca","jt-comparison-of-jenkins-and-tekton-concepts_migrating-from-jenkins-to-tekton","jenkins-terminology","tekton-terminology","mapping-of-concepts","jt-migrating-a-sample-pipeline-from-jenkins-to-tekton_migrating-from-jenkins-to-tekton","jenkins-pipeline","tekton-pipeline","jt-migrating-from-jenkins-plugins-to-tekton-hub-tasks_migrating-from-jenkins-to-tekton","jt-extending-tekton-capabilities-using-custom-tasks-and-scripts_migrating-from-jenkins-to-tekton","jt-comparison-of-jenkins-tekton-execution-models_migrating-from-jenkins-to-tekton","/documentation/openshift_container_platform/4.8/html/cicd/migrating-from-jenkins-to-tekton",{"title":7000,"visible":17,"weight":75,"urlFragment":7001,"anchor":23,"singlePageAnchor":7001,"subChapters":7002,"url":7107,"docTitle":6822},"Pipelines","pipelines",[7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013,7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059,1633,7060,7061,7062,7063,2643,7064,7065,7066,7067,1045,7068,7069,7070,7071,7072,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105,7106],"op-release-notes","making-open-source-more-inclusive_op-release-notes","op-release-notes-1-5_op-release-notes","compatibility-support-matrix-1-5_op-release-notes","new-features-1-5_op-release-notes","deprecated-features-1-5_op-release-notes","known-issues-1-5_op-release-notes","fixed-issues-1-5_op-release-notes","op-release-notes-1-4_op-release-notes","compatibility-support-matrix-1-4_op-release-notes","new-features-1-4_op-release-notes","deprecated-features-1-4_op-release-notes","known-issues-1-4_op-release-notes","fixed-issues-1-4_op-release-notes","op-release-notes-1-3_op-release-notes","new-features-1-3_op-release-notes","pipeline-new-features-1-3_op-release-notes","cli-new-features-1-3_op-release-notes","triggers-new-features-1-3_op-release-notes","deprecated-features-1-3_op-release-notes","known-issues-1-3_op-release-notes","fixed-issues-1-3_op-release-notes","op-release-notes-1-2_op-release-notes","new-features-1-2_op-release-notes","pipeline-new-features-1-2_op-release-notes","cli-new-features-1-2_op-release-notes","triggers-new-features-1-2_op-release-notes","deprecated-features-1-2_op-release-notes","known-issues-1-2_op-release-notes","fixed-issues-1-2_op-release-notes","op-release-notes-1-1_op-release-notes","new-features-1-1_op-release-notes","pipeline-new-features-1-1_op-release-notes","cli-new-features-1-1_op-release-notes","triggers-new-features-1-1_op-release-notes","deprecated-features-1-1_op-release-notes","known-issues-1-1_op-release-notes","fixed-issues-1-1_op-release-notes","op-release-notes-1-0_op-release-notes","new-features-1-0_op-release-notes","pipeline-new-features-1-0_op-release-notes","cli-new-features-1-0_op-release-notes","triggers-new-features-1-0_op-release-notes","deprecated-features-1-0_op-release-notes","known-issues-1-4-0_op-release-notes","fixed-issues-1-0_op-release-notes","understanding-openshift-pipelines","op-key-features","op-detailed-concepts","about-tasks_understanding-openshift-pipelines","about-whenexpression_understanding-openshift-pipelines","about-finally_tasks_understanding-openshift-pipelines","about-taskrun_understanding-openshift-pipelines","about-pipelines_understanding-openshift-pipelines","about-pipelinerun_understanding-openshift-pipelines","about-workspaces_understanding-openshift-pipelines","about-triggers_understanding-openshift-pipelines","installing-pipelines","op-installing-pipelines-operator-in-web-console_installing-pipelines","op-installing-pipelines-operator-using-the-cli_installing-pipelines","op-pipelines-operator-in-restricted-environment_installing-pipelines","uninstalling-pipelines","op-deleting-the-pipelines-component-and-custom-resources_uninstalling-pipelines","op-uninstalling-the-pipelines-operator_uninstalling-pipelines","creating-applications-with-cicd-pipelines","creating-project-and-checking-pipeline-service-account_creating-applications-with-cicd-pipelines","creating-pipeline-tasks_creating-applications-with-cicd-pipelines","assembling-a-pipeline_creating-applications-with-cicd-pipelines","op-mirroring-images-to-run-pipelines-in-restricted-environment_creating-applications-with-cicd-pipelines","running-a-pipeline_creating-applications-with-cicd-pipelines","adding-triggers_creating-applications-with-cicd-pipelines","creating-webhooks_creating-applications-with-cicd-pipelines","triggering-a-pipeline_creating-applications-with-cicd-pipelines","pipeline-addtl-resources","working-with-pipelines-using-the-developer-perspective","op-constructing-pipelines-using-pipeline-builder_working-with-pipelines-using-the-developer-perspective","creating-applications-with-openshift-pipelines","op-interacting-with-pipelines-using-the-developer-perspective_working-with-pipelines-using-the-developer-perspective","using-custom-pipeline-template-for-git-import","op-starting-pipelines_using-custom-pipeline-template-for-git-import","op-editing-pipelines_using-custom-pipeline-template-for-git-import","op-deleting-pipelines_using-custom-pipeline-template-for-git-import","reducing-pipelines-resource-consumption","op-understanding-pipelines-resource-consumption_reducing-pipelines-resource-consumption","op-mitigating-extra-pipeline-resource-consumption_reducing-pipelines-resource-consumption","additional-resources_reducing-pipelines-resource-consumption","using-pods-in-a-privileged-security-context","op-running-pipeline-and-task-run-pods-with-privileged-security-context","op-running-pipeline-run-and-task-run-with-custom-scc-and-service-account_op-running-pipeline-and-task-run-pods-with-privileged-security-context","additional-references_using-pods-in-a-privileged-security-context","securing-webhooks-with-event-listeners","op-providing-secure-connection_securing-webhooks-with-event-listeners","op-sample-eventlistener-resource_securing-webhooks-with-event-listeners","authenticating-pipelines-using-git-secret","op-understanding-credential-selection_authenticating-pipelines-using-git-secret","op-configuring-basic-authentication-for-git_authenticating-pipelines-using-git-secret","op-configuring-ssh-authentication-for-git_authenticating-pipelines-using-git-secret","op-using-ssh-authentication-in-git-type-tasks_authenticating-pipelines-using-git-secret","op-using-secrets-as-a-nonroot-user_authenticating-pipelines-using-git-secret","op-limiting-secret-access-to-specific-steps_authenticating-pipelines-using-git-secret","viewing-pipeline-logs-using-the-openshift-logging-operator","prerequisites_viewing-pipeline-logs-using-the-openshift-logging-operator","op-viewing-pipeline-logs-in-kibana_viewing-pipeline-logs-using-the-openshift-logging-operator","additional-resources_viewing-pipeline-logs-using-the-openshift-logging-operator","/documentation/openshift_container_platform/4.8/html/cicd/pipelines",{"title":7109,"visible":17,"weight":442,"urlFragment":7110,"anchor":23,"singlePageAnchor":7110,"subChapters":7111,"url":7232,"docTitle":6822},"GitOps","gitops",[7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229,7230,7231],"gitops-release-notes","compatibility-and-support-matrix","making-open-source-more-inclusive_gitops-release-notes","gitops-release-notes-1-6-6_gitops-release-notes","fixed-issues-1-6-6_gitops-release-notes","gitops-release-notes-1-6-7_gitops-release-notes","fixed-issues-1-6-7_gitops-release-notes","gitops-release-notes-1-6-2_gitops-release-notes","fixed-issues-1-6-2_gitops-release-notes","gitops-release-notes-1-6-1_gitops-release-notes","fixed-issues-1-6-1_gitops-release-notes","gitops-release-notes-1-6-0_gitops-release-notes","new-features-1-6-0_gitops-release-notes","fixed-issues-1-6-0_gitops-release-notes","known-issues-1-6-0_gitops-release-notes","gitops-release-notes-1-5-7_gitops-release-notes","fixed-issues-1-5-7_gitops-release-notes","gitops-release-notes-1-5-6_gitops-release-notes","fixed-issues-1-5-6_gitops-release-notes","gitops-release-notes-1-5-5_gitops-release-notes","new-features-1-5-5_gitops-release-notes","fixed-issues-1-5-5_gitops-release-notes","known-issues-1-5-5_gitops-release-notes","gitops-release-notes-1-5-4_gitops-release-notes","fixed-issues-1-5-4_gitops-release-notes","gitops-release-notes-1-5-3_gitops-release-notes","fixed-issues-1-5-3_gitops-release-notes","gitops-release-notes-1-5-2_gitops-release-notes","fixed-issues-1-5-2_gitops-release-notes","gitops-release-notes-1-5-1_gitops-release-notes","fixed-issues-1-5-1_gitops-release-notes","gitops-release-notes-1-5-0_gitops-release-notes","new-features-1-5-0_gitops-release-notes","fixed-issues-1-5-0_gitops-release-notes","known-issues-1-5-0_gitops-release-notes","gitops-release-notes-1-4-13_gitops-release-notes","fixed-issues-1-4-13_gitops-release-notes","gitops-release-notes-1-4-12_gitops-release-notes","fixed-issues-1-4-12_gitops-release-notes","gitops-release-notes-1-4-5_gitops-release-notes","fixed-issues-1-4-5_gitops-release-notes","gitops-release-notes-1-4-3_gitops-release-notes","fixed-issues-1-4-3_gitops-release-notes","gitops-release-notes-1-4-2_gitops-release-notes","fixed-issues-1-4-2_gitops-release-notes","gitops-release-notes-1-4-1_gitops-release-notes","fixed-issues-1-4-1_gitops-release-notes","gitops-release-notes-1-4-0_gitops-release-notes","new-features-1-4-0_gitops-release-notes","fixed-issues-1-4-0_gitops-release-notes","known-issues-1-4-0_gitops-release-notes","gitops-release-notes-1-3-7_gitops-release-notes","fixed-issues-1-3-7_gitops-release-notes","gitops-release-notes-1-3-6_gitops-release-notes","fixed-issues-1-3-6_gitops-release-notes","gitops-release-notes-1-3-2_gitops-release-notes","new-features-1-3-2_gitops-release-notes","fixed-issues-1-3-2_gitops-release-notes","gitops-release-notes-1-3-1_gitops-release-notes","fixed-issues-1-3-1_gitops-release-notes","gitops-release-notes-1-3_gitops-release-notes","new-features-1-3_gitops-release-notes","fixed-issues-1-3_gitops-release-notes","known-issues-1-3_gitops-release-notes","gitops-release-notes-1-2-2_gitops-release-notes","fixed-issues-1-2-2_gitops-release-notes","gitops-release-notes-1-2-1_gitops-release-notes","support-matrix-1-2-1_gitops-release-notes","fixed-issues-1-2-1_gitops-release-notes","gitops-release-notes-1-2_gitops-release-notes","support-matrix-1-2_gitops-release-notes","new-features-1-2_gitops-release-notes","fixed-issues-1-2_gitops-release-notes","known-issues-1-2_gitops-release-notes","gitops-release-notes-1-1_gitops-release-notes","support-matrix-1-1_gitops-release-notes","new-features-1-1_gitops-release-notes","fixed-issues-1-1_gitops-release-notes","known-issues-1-1_gitops-release-notes","breaking-change-1-1_gitops-release-notes","upgrading-from-red-hat-openshift-gitops-v1-0-1","understanding-openshift-gitops","about-gitops_understanding-openshift-gitops","about-redhat-openshift-gitops_understanding-openshift-gitops","key-features_understanding-openshift-gitops","getting-started-with-openshift-gitops","installing-gitops-operator-in-web-console_installing-openshift-gitops","logging-in-to-the-argo-cd-instance-by-using-the-argo-cd-admin-account_installing-openshift-gitops","uninstalling-openshift-gitops","go-deleting-argocd-instance_uninstalling-openshift-gitops","go-uninstalling-gitops-operator_uninstalling-openshift-gitops","configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","using-argo-cd-instance-to-manage-cluster-scoped-resourcesconfiguring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","default-permissions-of-an-argocd-instance.adocconfiguring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","run-argo-cd-instance-on-cluster_configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","creating-an-application-by-using-the-argo-cd-dashboard_configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","creating-an-application-by-using-the-oc-tool_configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","synchronizing-your-application-application-with-your-git-repository_configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","gitops-inbuilt-permissions-for-cluster-config_configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","gitops-additional-permissions-for-cluster-config_configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","gitops-installing-olm-operators-using-gitops_configuring-an-openshift-cluster-by-deploying-an-application-with-cluster-configurations","installing-cluster-scoped-operators","installing-namepace-scoped-operators","deploying-a-spring-boot-application-with-argo-cd","creating-an-application-by-using-the-argo-cd-dashboard_deploying-a-spring-boot-application-with-argo-cd","creating-an-application-by-using-the-oc-tool_deploying-a-spring-boot-application-with-argo-cd","verifying-argo-cd-self-healing-behavior_deploying-a-spring-boot-application-with-argo-cd","configuring-sso-for-argo-cd-using-dex","gitops-creating-a-new-client-in-dex_configuring-sso-for-argo-cd-using-dex","gitops-dex-role-mappings_configuring-sso-for-argo-cd-using-dex","gitops-disable-dex_configuring-sso-for-argo-cd-using-dex","configuring-sso-for-argo-cd-using-keycloak","gitops-creating-a-new-client-in-keycloak_configuring-sso-for-argo-cd-using-keycloak","gitops-logging-into-keycloak_configuring-sso-for-argo-cd-using-keycloak","gitops-additional-steps-disconnected-clusters_configuring-sso-for-argo-cd-using-keycloak","gitops-uninstalling-keycloak_configuring-sso-for-argo-cd-using-keycloak","run-gitops-control-plane-workload-on-infra-nodes","add-infra-nodes_run-gitops-control-plane-workload-on-infra-nodes","about-sizing-requirements-gitops","sizing-requirements-for-gitops_about-sizing-requirements-gitops","/documentation/openshift_container_platform/4.8/html/cicd/gitops",{"title":7234,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":7235,"url":7236,"docTitle":7237,"sections":7238},"Images",[],"/documentation/openshift_container_platform/4.8/html/images/index","images",[7239,7258,7274,7286,7305,7325,7345,7351,7359,7372,7397,7411],{"title":7240,"visible":17,"weight":30,"urlFragment":7241,"anchor":23,"singlePageAnchor":7241,"subChapters":7242,"url":7257,"docTitle":7237},"Overview of images","overview-of-images",[7243,7244,7245,7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256],"about-containers-images-and-image-streams","images-about_overview-of-images","images-image-registry-about_overview-of-images","images-container-repository-about_overview-of-images","images-tag_overview-of-images","images-id_overview-of-images","containers-about_overview-of-images","images-imagestream-use_overview-of-images","images-imagestream-tag_overview-of-images","images-imagestream-image_overview-of-images","images-imagestream-trigger_overview-of-images","how-you-can-use-the-cluster-samples-operator","about-templates","how-you-can-use-ruby-on-rails","/documentation/openshift_container_platform/4.8/html/images/overview-of-images",{"title":7259,"visible":17,"weight":42,"urlFragment":7260,"anchor":23,"singlePageAnchor":7260,"subChapters":7261,"url":7273,"docTitle":7237},"Configuring the Cluster Samples Operator","configuring-samples-operator",[7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272],"samples-operator-overview_configuring-samples-operator","samples-operator-bootstrapped","samples-operator-restricted-network-install","samples-operator-restricted-network-install-with-access","samples-operator-retries","installation-images-samples-disconnected-mirroring-assist_configuring-samples-operator","samples-operator-configuration_configuring-samples-operator","configuration-restrictions","conditions","samples-operator-crd_configuring-samples-operator","images-samples-operator-deprecated-image-stream_configuring-samples-operator","/documentation/openshift_container_platform/4.8/html/images/configuring-samples-operator",{"title":7275,"visible":17,"weight":53,"urlFragment":7276,"anchor":23,"singlePageAnchor":7276,"subChapters":7277,"url":7285,"docTitle":7237},"Using the Cluster Samples Operator with an alternate registry","samples-operator-alt-registry",[7278,7279,7280,7281,7282,7283,7284],"installation-about-mirror-registry_samples-operator-alt-registry","samples-preparing-bastion","cli-installing-cli_samples-operator-alt-registry","installation-adding-registry-pull-secret_samples-operator-alt-registry","installation-mirror-repository_samples-operator-alt-registry","installation-restricted-network-samples_samples-operator-alt-registry","installation-images-samples-disconnected-mirroring-assist_samples-operator-alt-registry","/documentation/openshift_container_platform/4.8/html/images/samples-operator-alt-registry",{"title":7287,"visible":17,"weight":75,"urlFragment":7288,"anchor":23,"singlePageAnchor":7288,"subChapters":7289,"url":7304,"docTitle":7237},"Creating images","creating-images",[7290,7291,7292,7293,7294,7295,7296,7297,7298,7299,7300,7301,7302,7303],"images-create-guidelines_create-images","images-create-guide-general_create-images","images-create-guide-openshift_create-images","images-create-metadata_create-images","defining-image-metadata","images-create-s2i_create-images","images-create-s2i-build_create-images","images-create-s2i-scripts_create-images","images-test-s2i_create-images","images-test-s2i-testing-requirements_create-images","images-test-s2i-generating-scripts-and-tools_create-images","images-test-s21-testing-locally_create-images","images-test-s21-basic-testing-workflow_create-images","images-test-s21-using-openshift-for-building-the-image_create-images","/documentation/openshift_container_platform/4.8/html/images/creating-images",{"title":7306,"visible":17,"weight":442,"urlFragment":7307,"anchor":23,"singlePageAnchor":7307,"subChapters":7308,"url":7324,"docTitle":7237},"Managing images","managing-images",[7309,7310,7311,7312,7313,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323],"managing-images-overview","images-managing-overview_managing-images-overview","tagging-images","images-tag_tagging-images","images-tagging-conventions_tagging-images","images-add-tags-to-imagestreams_tagging-images","images-remove-tag-imagestream_tagging-images","images-referencing-images-imagestreams_tagging-images","image-pull-policy","images-image-pull-policy-overview_image-pull-policy","using-image-pull-secrets","images-allow-pods-to-reference-images-across-projects_using-image-pull-secrets","images-allow-pods-to-reference-images-from-secure-registries_using-image-pull-secrets","images-pulling-from-private-registries_using-image-pull-secrets","images-update-global-pull-secret_using-image-pull-secrets","/documentation/openshift_container_platform/4.8/html/images/managing-images",{"title":7326,"visible":17,"weight":460,"urlFragment":7327,"anchor":23,"singlePageAnchor":7327,"subChapters":7328,"url":7344,"docTitle":7237},"Managing image streams","managing-image-streams",[7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343],"images-imagestream-use_image-streams-managing","images-imagestream-configure_image-streams-managing","images-using-imagestream-images_image-streams-managing","images-using-imagestream-tags_image-streams-managing","images-using-imagestream-change-triggers_image-streams-managing","images-imagestream-mapping_image-streams-managing","working-with-image-streams","images-getting-info-about-imagestreams_image-streams-managing","images-imagestream-adding-tags_image-streams-managing","images-imagestream-external-image-tags_image-streams-managing","images-imagestream-update-tag_image-streams-managing","images-imagestream-remove-tag_image-streams-managing","images-imagestream-import_image-streams-managing","images-imagestream-import-images-private-registry_image-streams-managing","images-allow-pods-to-reference-images-from-secure-registries_image-streams-managing","/documentation/openshift_container_platform/4.8/html/images/managing-image-streams",{"title":7346,"visible":17,"weight":475,"urlFragment":7347,"anchor":23,"singlePageAnchor":7347,"subChapters":7348,"url":7350,"docTitle":7237},"Using image streams with Kubernetes resources","using-imagestreams-with-kube-resources",[7349],"images-managing-images-enabling-imagestreams-kube_using-imagestreams-with-kube-resources","/documentation/openshift_container_platform/4.8/html/images/using-imagestreams-with-kube-resources",{"title":7352,"visible":17,"weight":876,"urlFragment":7353,"anchor":23,"singlePageAnchor":7353,"subChapters":7354,"url":7358,"docTitle":7237},"Triggering updates on image stream changes","triggering-updates-on-imagestream-changes",[7355,7356,7357],"openshift-resources","images-triggering-updates-imagestream-changes-kubernetes-about_triggering-updates-on-imagestream-changes","images-triggering-updates-imagestream-changes-kubernetes-cli_triggering-updates-on-imagestream-changes","/documentation/openshift_container_platform/4.8/html/images/triggering-updates-on-imagestream-changes",{"title":7360,"visible":17,"weight":884,"urlFragment":7361,"anchor":23,"singlePageAnchor":7361,"subChapters":7362,"url":7371,"docTitle":7237},"Image configuration resources","image-configuration",[7363,7364,7365,7366,7367,7368,7369,7370],"images-configuration-parameters_image-configuration","images-configuration-file_image-configuration","images-configuration-allowed_image-configuration","images-configuration-blocked_image-configuration","images-configuration-insecure_image-configuration","images-configuration-shortname_image-configuration","images-configuration-cas_image-configuration","images-configuration-registry-mirror_image-configuration","/documentation/openshift_container_platform/4.8/html/images/image-configuration",{"title":7373,"visible":17,"weight":895,"urlFragment":7374,"anchor":23,"singlePageAnchor":7374,"subChapters":7375,"url":7396,"docTitle":7237},"Using templates","using-templates",[7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391,7392,7393,7394,7395],"templates-overview_using-templates","templates-uploading_using-templates","templates-creating-from-console_using-templates","templates-using-the-cli_using-templates","templates-cli-labels_using-templates","templates-cli-parameters_using-templates","templates-cli-generating-list-of-objects_using-templates","templates-modifying-uploaded-template_using-templates","templates-using-instant-app-quickstart_using-templates","templates-quickstart_using-templates","templates-quickstart-web-framework_using-templates","templates-writing_using-templates","templates-writing-description_using-templates","templates-writing-labels_using-templates","templates-writing-parameters_using-templates","templates-writing-object-list_using-templates","templates-marking-as-bindable_using-templates","templates-exposing-object-fields_using-templates","templates-waiting-for-readiness_using-templates","templates-create-from-existing-object_using-templates","/documentation/openshift_container_platform/4.8/html/images/using-templates",{"title":7398,"visible":17,"weight":906,"urlFragment":7399,"anchor":23,"singlePageAnchor":7399,"subChapters":7400,"url":7410,"docTitle":7237},"Using Ruby on Rails","templates-using-ruby-on-rails",[1013,7401,7402,7403,7404,7405,7406,7407,7408,7409],"templates-rails-setting-up-database_templates-ruby-on-rails","templates-rails-writing-application_templates-ruby-on-rails","templates-rails-creating-welcome-page_templates-ruby-on-rails","templates-rails-configuring-application_templates-ruby-on-rails","templates-rails-storing-application-in-git_templates-ruby-on-rails","templates-rails-deploying-application_templates-ruby-on-rails","templates-rails-creating-database-service_templates-ruby-on-rails","templates-rails-creating-frontend-service_templates-ruby-on-rails","templates-rails-creating-route-for-application_templates-ruby-on-rails","/documentation/openshift_container_platform/4.8/html/images/templates-using-ruby-on-rails",{"title":7412,"visible":17,"weight":913,"urlFragment":7413,"anchor":23,"singlePageAnchor":7413,"subChapters":7414,"url":7440,"docTitle":7237},"Using images","using-images",[7415,7416,7417,7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,1633,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439],"using-images-overview","images-other-jenkins","images-other-jenkins-config-customization_images-other-jenkins","images-other-jenkins-oauth-auth_images-other-jenkins","images-other-jenkins-auth_images-other-jenkins","images-other-jenkins-env-var_images-other-jenkins","images-other-jenkins-cross-project_images-other-jenkins","images-other-jenkins-cross-volume-mount_images-other-jenkins","images-other-jenkins-customize-s2i_images-other-jenkins","images-other-jenkins-config-kubernetes_images-other-jenkins","images-other-jenkins-permissions_images-other-jenkins","images-other-jenkins-create-service_images-other-jenkins","images-other-jenkins-kubernetes-plugin_images-other-jenkins","images-other-jenkins-memory_images-other-jenkins","images-other-jenkins-agent","images-other-jenkins-agent-images_images-other-jenkins-agent","images-other-jenkins-agent-env-var_images-other-jenkins-agent","images-other-jenkins-agent-memory_images-other-jenkins-agent","images-other-jenkins-agent-gradle_images-other-jenkins-agent","images-other-jenkins-agent-pod-retention_images-other-jenkins-agent","using-s21-images","images-s2i-build-process-overview_using-s21-images","additional-resources_using-s21-images","customizing-s2i-images","images-using-customizing-s2i-images-scripts-embedded_customizing-s2i-images","/documentation/openshift_container_platform/4.8/html/images/using-images",{"title":7442,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":7443,"url":7444,"docTitle":7445,"sections":7446},"Nodes",[],"/documentation/openshift_container_platform/4.8/html/nodes/index","nodes",[7447,7455,7536,7619,7636,7703,7755,7813],{"title":7448,"visible":17,"weight":30,"urlFragment":7449,"anchor":23,"singlePageAnchor":7449,"subChapters":7450,"url":7454,"docTitle":7445},"Overview of nodes","overview-of-nodes",[7451,7452,7453],"nodes-overview","pods-overview","containers-overview","/documentation/openshift_container_platform/4.8/html/nodes/overview-of-nodes",{"title":7456,"visible":17,"weight":42,"urlFragment":7457,"anchor":23,"singlePageAnchor":7457,"subChapters":7458,"url":7535,"docTitle":7445},"Working with pods","working-with-pods",[7459,7460,7461,1553,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,1605,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534],"nodes-pods-using-pp","nodes-pods-using-about_nodes-pods-using-ssy","nodes-pods-using-example_nodes-pods-using-ssy","nodes-pods-viewing","nodes-pods-about_nodes-pods-viewing","nodes-pods-viewing-project_nodes-pods-viewing","nodes-pods-viewing-usage_nodes-pods-viewing","viewing-resource-logs-cli-console_nodes-pods-viewing","nodes-pods-configuring","nodes-pods-configuring-restart_nodes-pods-configuring","nodes-pods-configuring-bandwidth_nodes-pods-configuring","nodes-pods-configuring-pod-distruption-about_nodes-pods-configuring","nodes-pods-pod-disruption-configuring_nodes-pods-configuring","nodes-pods-configuring-critical_nodes-pods-configuring","nodes-pods-autoscaling","nodes-pods-autoscaling-about_nodes-pods-autoscaling","supported-metrics","nodes-pods-autoscaling-policies_nodes-pods-autoscaling","nodes-pods-autoscaling-creating-web-console_nodes-pods-autoscaling","nodes-pods-autoscaling-creating-cpu_nodes-pods-autoscaling","nodes-pods-autoscaling-creating-memory_nodes-pods-autoscaling","nodes-pods-autoscaling-status-about_nodes-pods-autoscaling","nodes-pods-autoscaling-status-viewing_nodes-pods-autoscaling","nodes-pods-vpa","nodes-pods-vertical-autoscaler-about_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-install_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-using-about_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-using-one-pod_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-using-auto_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-using-pod_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-using-manual_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-using-exempt_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-configuring_nodes-pods-vertical-autoscaler","nodes-pods-vertical-autoscaler-uninstall_nodes-pods-vertical-autoscaler","nodes-pods-secrets","nodes-pods-secrets-about_nodes-pods-secrets","nodes-pods-secrets-about-types_nodes-pods-secrets","nodes-pods-secrets-about-keys_nodes-pods-secrets","nodes-pods-secrets-creating_nodes-pods-secrets","secret-creation-restrictions","nodes-pods-secrets-creating-opaque_nodes-pods-secrets","nodes-pods-secrets-creating-sa_nodes-pods-secrets","nodes-pods-secrets-creating-basic_nodes-pods-secrets","nodes-pods-secrets-creating-ssh_nodes-pods-secrets","nodes-pods-secrets-creating-docker_nodes-pods-secrets","nodes-pods-secrets-updating_nodes-pods-secrets","nodes-pods-secrets-certificates-about_nodes-pods-secrets","nodes-pods-secrets-certificates-creating_nodes-pods-secrets","nodes-pods-secrets-troubleshooting_nodes-pods-secrets","configmaps","nodes-pods-configmap-overview_configmaps","nodes-pods-configmap-create-from-console_configmaps","nodes-pods-configmap-create_configmaps","nodes-pods-configmap-creating-from-directories_configmaps","nodes-pods-configmap-creating-from-files_configmaps","nodes-pods-configmap-creating-from-literal-values_configmaps","nodes-pods-configmaps-consuming-configmap-in-pods","nodes-pods-configmaps-use-case-consuming-in-env-vars_configmaps","nodes-pods-configmaps-use-case-setting-command-line-arguments_configmaps","nodes-pods-configmaps-use-case-consuming-in-volumes_configmaps","nodes-pods-device","nodes-pods-plugins-about_nodes-pods-device","methods-for-deploying-a-device-plugin_nodes-pods-device","nodes-pods-plugins-device-mgr_nodes-pods-device","nodes-pods-plugins-install_nodes-pods-device","nodes-pods-priority","nodes-pods-priority-about_nodes-pods-priority","admin-guide-priority-preemption-priority-class_nodes-pods-priority","admin-guide-priority-preemption-names_nodes-pods-priority","nodes-pods-priority-preempt-about_nodes-pods-priority","non-preempting-priority-class_nodes-pods-priority","priority-preemption-other_nodes-pods-priority","priority-preemption-graceful_nodes-pods-priority","nodes-pods-priority-configuring_nodes-pods-priority","nodes-pods-node-selectors","nodes-scheduler-node-selectors-pod_nodes-pods-node-selectors","/documentation/openshift_container_platform/4.8/html/nodes/working-with-pods",{"title":7537,"visible":17,"weight":53,"urlFragment":7538,"anchor":23,"singlePageAnchor":7538,"subChapters":7539,"url":7618,"docTitle":7445},"Controlling pod placement onto nodes (scheduling)","controlling-pod-placement-onto-nodes-scheduling",[7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,1633,7607,7608,7609,7610,7611,7612,7613,7614,7615,7616,7617],"nodes-scheduler-about","nodes-scheduler-about-use-cases_nodes-scheduler-about","infrastructure-topological-levels_nodes-scheduler-about","affinity_nodes-scheduler-about","anti-affinity_nodes-scheduler-about","nodes-scheduler-default","nodes-scheduler-default-about_nodes-scheduler-default","nodes-scheduler-default-about-understanding_nodes-scheduler-default","nodes-scheduler-default-creating_nodes-scheduler-default","nodes-scheduler-default-modifying_nodes-scheduler-default","nodes-scheduler-default-predicates_nodes-scheduler-default","static-predicates_nodes-scheduler-default","default-predicates_nodes-scheduler-default","other-predicates_nodes-scheduler-default","admin-guide-scheduler-general-predicates_nodes-scheduler-default","nodes-scheduler-default-priorities_nodes-scheduler-default","static-priority-functions_nodes-scheduler-default","default-priorities_nodes-scheduler-default","other-priorities_nodes-scheduler-default","configurable-priority-functions_nodes-scheduler-default","nodes-scheduler-default-sample_nodes-scheduler-default","nodes-scheduler-profiles","nodes-scheduler-profiles-about_nodes-scheduler-profiles","nodes-scheduler-profiles-configuring_nodes-scheduler-profiles","nodes-scheduler-pod-affinity","nodes-scheduler-pod-affinity-about_nodes-scheduler-pod-affinity","nodes-scheduler-pod-affinity-configuring_nodes-scheduler-pod-affinity","nodes-scheduler-pod-anti-affinity-configuring_nodes-scheduler-pod-affinity","nodes-scheduler-pod-affinity-example_nodes-scheduler-pod-affinity","nodes-scheduler-pod-affinity-example-affinity_nodes-scheduler-pod-affinity","nodes-scheduler-pod-affinity-example-antiaffinity_nodes-scheduler-pod-affinity","nodes-scheduler-pod-affinity-example-no-labels_nodes-scheduler-pod-affinity","nodes-scheduler-node-affinity","nodes-scheduler-node-affinity-about_nodes-scheduler-node-affinity","nodes-scheduler-node-affinity-configuring-required_nodes-scheduler-node-affinity","nodes-scheduler-node-affinity-configuring-preferred_nodes-scheduler-node-affinity","nodes-scheduler-node-affinity-examples_nodes-scheduler-node-affinity","admin-guide-sched-affinity-examples1_nodes-scheduler-node-affinity","admin-guide-sched-affinity-examples2_nodes-scheduler-node-affinity","nodes-scheduler-node-affinity-addtl-resources_nodes-scheduler-node-affinity","nodes-scheduler-overcommit","nodes-cluster-overcommit-about_nodes-scheduler-overcommit","nodes-cluster-overcommit-configure-nodes_nodes-scheduler-overcommit","nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-about_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-about-seconds_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-about-multiple_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-about-taintNodesByCondition_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-about-taintBasedEvictions_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-all_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-adding_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-adding-machineset_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-bindings_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-projects_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-special_nodes-scheduler-taints-tolerations","nodes-scheduler-taints-tolerations-removing_nodes-scheduler-taints-tolerations","nodes-scheduler-node-selectors","nodes-scheduler-node-selectors-about_nodes-scheduler-node-selectors","nodes-scheduler-node-selectors-pod_nodes-scheduler-node-selectors","nodes-scheduler-node-selectors-cluster_nodes-scheduler-node-selectors","nodes-scheduler-node-selectors-project_nodes-scheduler-node-selectors","nodes-scheduler-pod-topology-spread-constraints","nodes-scheduler-pod-topology-spread-constraints-about_nodes-scheduler-pod-topology-spread-constraints","nodes-scheduler-pod-topology-spread-constraints-configuring_nodes-scheduler-pod-topology-spread-constraints","nodes-scheduler-pod-topology-spread-constraints-examples_nodes-scheduler-pod-topology-spread-constraints","nodes-scheduler-pod-topology-spread-constraints-example-single_nodes-scheduler-pod-topology-spread-constraints","nodes-scheduler-pod-topology-spread-constraints-example-multiple_nodes-scheduler-pod-topology-spread-constraints","nodes-custom-scheduler","nodes-custom-scheduler-deploying_nodes-custom-scheduler","nodes-custom-scheduler-deploying-pods_nodes-custom-scheduler","additional-resources_nodes-custom-scheduler","nodes-descheduler","nodes-descheduler-about_nodes-descheduler","nodes-descheduler-profiles_nodes-descheduler","nodes-descheduler-installing_nodes-descheduler","nodes-descheduler-configuring-profiles_nodes-descheduler","nodes-descheduler-configuring-interval_nodes-descheduler","nodes-descheduler-uninstalling_nodes-descheduler","/documentation/openshift_container_platform/4.8/html/nodes/controlling-pod-placement-onto-nodes-scheduling",{"title":7620,"visible":17,"weight":75,"urlFragment":7621,"anchor":23,"singlePageAnchor":7621,"subChapters":7622,"url":7635,"docTitle":7445},"Using Jobs and DaemonSets","using-jobs-and-daemonsets",[7623,7624,7625,7626,7627,7628,7629,7630,7631,7632,7633,7634],"nodes-pods-daemonsets","scheduled-by-default-scheduler","nodes-pods-daemonsets-creating_nodes-pods-daemonsets","nodes-nodes-jobs","nodes-nodes-jobs-about_nodes-nodes-jobs","jobs-create_nodes-nodes-jobs","jobs-set-max_nodes-nodes-jobs","jobs-set-backoff_nodes-nodes-jobs","jobs-artifacts_nodes-nodes-jobs","jobs-limits_nodes-nodes-jobs","nodes-nodes-jobs-creating_nodes-nodes-jobs","nodes-nodes-jobs-creating-cron_nodes-nodes-jobs","/documentation/openshift_container_platform/4.8/html/nodes/using-jobs-and-daemonsets",{"title":7637,"visible":17,"weight":442,"urlFragment":7638,"anchor":23,"singlePageAnchor":7638,"subChapters":7639,"url":7702,"docTitle":7445},"Working with nodes","working-with-nodes",[7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701],"nodes-nodes-viewing","nodes-nodes-viewing-listing_nodes-nodes-viewing","nodes-nodes-viewing-listing-pods_nodes-nodes-viewing","nodes-nodes-viewing-memory_nodes-nodes-viewing","nodes-nodes-working","nodes-nodes-working-evacuating_nodes-nodes-working","nodes-nodes-working-updating_nodes-nodes-working","nodes-nodes-working-marking_nodes-nodes-working","deleting-nodes","nodes-nodes-working-deleting_nodes-nodes-working","nodes-nodes-working-deleting-bare-metal_nodes-nodes-working","nodes-nodes-managing","nodes-nodes-managing-about_nodes-nodes-managing","nodes-nodes-working-master-schedulable_nodes-nodes-managing","nodes-nodes-working-setting-booleans","nodes-nodes-kernel-arguments_nodes-nodes-managing","nodes-nodes-managing-max-pods","nodes-nodes-managing-max-pods-about_nodes-nodes-managing-max-pods","nodes-node-tuning-operator","accessing-an-example-node-tuning-operator-specification_nodes-node-tuning-operator","custom-tuning-specification_nodes-node-tuning-operator","custom-tuning-default-profiles-set_nodes-node-tuning-operator","supported-tuned-daemon-plug-ins_nodes-node-tuning-operator","poison-pill-operator-remediate-nodes","about-poison-pill-operator_poison-pill-operator-remediate-nodes","understanding-poison-pill-operator-config_poison-pill-operator-remediate-nodes","installing-poison-pill-operator-using-web-console_poison-pill-operator-remediate-nodes","installing-poison-pill-operator-using-cli_poison-pill-operator-remediate-nodes","configuring-machine-health-check-with-poison-pill_poison-pill-operator-remediate-nodes","troubleshooting-poison-pill-operator_poison-pill-operator-remediate-nodes","general-troubleshooting-poison-pill-operator_poison-pill-operator-remediate-nodes","checking-daemon-set_poison-pill-operator-remediate-nodes","unsuccessful_remediationpoison-pill-operator-remediate-nodes","daemon-set-exists_poison-pill-operator-remediate-nodes","additional-resources-poison-pill-operator-installation","nodes-nodes-rebooting","nodes-nodes-rebooting-infrastructure_nodes-nodes-rebooting","nodes-nodes-rebooting-affinity_nodes-nodes-rebooting","nodes-nodes-rebooting-router_nodes-nodes-rebooting","nodes-nodes-rebooting-gracefully_nodes-nodes-rebooting","nodes-nodes-garbage-collection","nodes-nodes-garbage-collection-containers_nodes-nodes-configuring","nodes-nodes-garbage-collection-images_nodes-nodes-configuring","nodes-nodes-garbage-collection-configuring_nodes-nodes-configuring","nodes-nodes-resources-configuring","nodes-nodes-resources-configuring-about_nodes-nodes-resources-configuring","computing-allocated-resources_nodes-nodes-resources-configuring","allocate-node-enforcement_nodes-nodes-resources-configuring","allocate-eviction-thresholds_nodes-nodes-resources-configuring","allocate-scheduler-policy_nodes-nodes-resources-configuring","nodes-nodes-resources-configuring-auto_nodes-nodes-resources-configuring","nodes-nodes-resources-configuring-setting_nodes-nodes-resources-configuring","nodes-nodes-resources-cpus","nodes-nodes-resources-cpus-reserve_nodes-nodes-resources-cpus","nodes-nodes-tls","tls-profiles-understanding_nodes-nodes-tls","tls-profiles-kubelet-configuring_nodes-nodes-tls","machine-config-daemon-metrics","machine-config-daemon-metrics_machine-config-operator","nodes-nodes-creating-infrastructure-nodes","infrastructure-components_creating-infrastructure-nodes","creating-an-infra-node_creating-infrastructure-nodes","/documentation/openshift_container_platform/4.8/html/nodes/working-with-nodes",{"title":7704,"visible":17,"weight":460,"urlFragment":7705,"anchor":23,"singlePageAnchor":7705,"subChapters":7706,"url":7754,"docTitle":7445},"Working with containers","working-with-containers",[7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753],"nodes-containers-using","nodes-containers-init","nodes-containers-init-about_nodes-containers-init","nodes-containers-init-creating_nodes-containers-init","nodes-containers-volumes","nodes-containers-volumes-about_nodes-containers-volumes","nodes-containers-volumes-cli_nodes-containers-volumes","nodes-containers-volumes-listing_nodes-containers-volumes","nodes-containers-volumes-adding_nodes-containers-volumes","nodes-containers-volumes-updating_nodes-containers-volumes","nodes-containers-volumes-removing_nodes-containers-volumes","nodes-containers-volumes-subpath_nodes-containers-volumes","nodes-containers-projected-volumes","nodes-containers-projected-volumes-about_nodes-containers-projected-volumes","projected-volumes-examples_nodes-containers-projected-volumes","projected-volumes-pathing_nodes-containers-projected-volumes","nodes-containers-projected-volumes-creating_nodes-containers-projected-volumes","nodes-containers-downward-api","nodes-containers-projected-volumes-about_nodes-containers-downward-api","nodes-containers-downward-api-container-values_nodes-containers-downward-api","nodes-containers-downward-api-container-values-envars_nodes-containers-downward-api","nodes-containers-downward-api-container-values-plugin_nodes-containers-downward-api","nodes-containers-downward-api-container-resources-api_nodes-containers-downward-api","nodes-containers-downward-api-container-resources-envars_nodes-containers-downward-api","nodes-containers-downward-api-container-resources-plugin_nodes-containers-downward-api","nodes-containers-downward-api-container-secrets_nodes-containers-downward-api","nodes-containers-downward-api-container-configmaps_nodes-containers-downward-api","nodes-containers-downward-api-container-envars_nodes-containers-downward-api","nodes-containers-downward-api-container-escaping_nodes-containers-downward-api","nodes-containers-copying-files","nodes-containers-copying-files-about_nodes-containers-copying-files","requirements","nodes-containers-copying-files-procedure_nodes-containers-copying-files","nodes-containers-copying-files-rsync_nodes-containers-copying-files","nodes-containers-remote-commands","nodes-containers-remote-commands-about_nodes-containers-remote-commands","nodes-containers-remote-commands-protocol_nodes-containers-remote-commands","nodes-containers-port-forwarding","nodes-containers-port-forwarding-about_nodes-containers-port-forwarding","nodes-containers-port-forwarding-using_nodes-containers-port-forwarding","nodes-containers-port-forwarding-protocol_nodes-containers-port-forwarding","nodes-containers-sysctls","nodes-containers-sysctls-about_nodes-containers-using","namespaced-vs-node-level-sysctls","safe-vs-unsafe-sysclts","nodes-containers-sysctls-setting_nodes-containers-using","nodes-containers-sysctls-unsafe_nodes-containers-using","/documentation/openshift_container_platform/4.8/html/nodes/working-with-containers",{"title":7756,"visible":17,"weight":475,"urlFragment":7757,"anchor":23,"singlePageAnchor":7757,"subChapters":7758,"url":7812,"docTitle":7445},"Working with clusters","working-with-clusters",[7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811],"nodes-containers-events","nodes-containers-events-about_nodes-containers-events","nodes-containers-events-viewing-cli_nodes-containers-events","nodes-containers-events-list_nodes-containers-events","nodes-cluster-resource-levels","nodes-cluster-resource-levels-about_nodes-cluster-resource-levels","nodes-cluster-resource-levels-command_nodes-cluster-resource-levels","nodes-cluster-resource-levels-job_nodes-cluster-resource-levels","nodes-cluster-limit-ranges","nodes-cluster-limit-ranges-about_nodes-cluster-limit-ranges","nodes-cluster-limit-ranges-limits_nodes-cluster-limit-ranges","nodes-cluster-limit-container-limits","nodes-cluster-limit-pod-limits","nodes-cluster-limit-image-limits","nodes-cluster-limit-stream-limits","nodes-cluster-limit-pvc-limits","nodes-cluster-limit-creating_nodes-cluster-limit-ranges","nodes-cluster-limit-viewing_nodes-cluster-limit-ranges","nodes-cluster-limit-ranges-deleting_nodes-cluster-limit-ranges","nodes-cluster-resource-configure","nodes-cluster-resource-configure-about_nodes-cluster-resource-configure","nodes-cluster-resource-configure-about-memory_nodes-cluster-resource-configure","nodes-cluster-resource-configure-jdk_nodes-cluster-resource-configure","nodes-cluster-resource-configure-jdk-heap_nodes-cluster-resource-configure","nodes-cluster-resource-configure-jdk-unused_nodes-cluster-resource-configure","nodes-cluster-resource-configure-jdk-proc_nodes-cluster-resource-configure","nodes-cluster-resource-configure-request-limit_nodes-cluster-resource-configure","nodes-cluster-resource-configure-oom_nodes-cluster-resource-configure","nodes-cluster-resource-configure-evicted_nodes-cluster-resource-configure","nodes-cluster-overcommit","nodes-cluster-overcommit-resource-requests_nodes-cluster-overcommit","nodes-cluster-resource-override_nodes-cluster-overcommit","nodes-cluster-resource-override-deploy-console_nodes-cluster-overcommit","nodes-cluster-resource-override-deploy-cli_nodes-cluster-overcommit","nodes-cluster-resource-configure_nodes-cluster-overcommit","nodes-cluster-node-overcommit_nodes-cluster-overcommit","nodes-cluster-overcommit-reserving-memory_nodes-cluster-overcommit","understanding-container-CPU-requests_nodes-cluster-overcommit","understanding-memory-requests-container_nodes-cluster-overcommit","nodes-cluster-overcommit-qos-about_nodes-cluster-overcommit","qos-about-reserve_nodes-cluster-overcommit","nodes-qos-about-swap_nodes-cluster-overcommit","nodes-cluster-overcommit-configure-nodes_nodes-cluster-overcommit","nodes-cluster-overcommit-node-enforcing_nodes-cluster-overcommit","nodes-cluster-overcommit-node-resources_nodes-cluster-overcommit","nodes-cluster-overcommit-node-disable_nodes-cluster-overcommit","nodes-cluster-project-overcommit_nodes-cluster-overcommit","nodes-cluster-overcommit-project-disable_nodes-cluster-overcommit","nodes-cluster-overcommit-addtl-resources","nodes-cluster-enabling","nodes-cluster-enabling-features-about_nodes-cluster-enabling","nodes-cluster-enabling-features-console_nodes-cluster-enabling","nodes-cluster-enabling-features-cli_nodes-cluster-enabling","/documentation/openshift_container_platform/4.8/html/nodes/working-with-clusters",{"title":7814,"visible":17,"weight":876,"urlFragment":7815,"anchor":23,"singlePageAnchor":7815,"subChapters":7816,"url":7821,"docTitle":7445},"Remote worker nodes on the network edge","remote-worker-nodes-on-the-network-edge",[7817,7818,7819,7820],"nodes-edge-remote-workers","nodes-edge-remote-workers-network_nodes-edge-remote-workers","nodes-edge-remote-workers-power_nodes-edge-remote-workers","nodes-edge-remote-workers-strategies_nodes-edge-remote-workers","/documentation/openshift_container_platform/4.8/html/nodes/remote-worker-nodes-on-the-network-edge",{"title":7823,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":7824,"url":7825,"docTitle":7826,"sections":7827},"Sandboxed Containers Support for OpenShift",[],"/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/index","sandboxed_containers_support_for_openshift",[7828,7841,7849,7865,7877],{"title":7829,"visible":17,"weight":30,"urlFragment":7830,"anchor":23,"singlePageAnchor":7830,"subChapters":7831,"url":7840,"docTitle":7826},"{sandboxed-containers-first} 1.0 release notes","sandboxed-containers-4-8-release-notes",[7832,7833,7834,7835,7836,7837,7838,7839],"ocp-1-0-about-this-release","sandboxed-containers-1-0-new-features-and-enhancements","sandboxed-containers-support-in-tech-preview","sandboxed-containers-1-0-known-issues","sandboxed-containers-1-0-asynchronous-errata-updates","sandboxed-containers-1-0-2","sandboxed-containers-1-0-1","sandboxed-containers-1-0-0","/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/sandboxed-containers-4-8-release-notes",{"title":7842,"visible":17,"weight":42,"urlFragment":7843,"anchor":23,"singlePageAnchor":7843,"subChapters":7844,"url":7848,"docTitle":7826},"Understanding OpenShift sandboxed containers","understanding-sandboxed-containers",[7845,7846,7847],"sandboxed-containers-common-terms_understanding-sandboxed-containers","sandboxed-containers-building-blocks_understanding-sandboxed-containers","sandboxed-containers-rhcos-extensions_understanding-sandboxed-containers","/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/understanding-sandboxed-containers",{"title":7850,"visible":17,"weight":53,"urlFragment":7851,"anchor":23,"singlePageAnchor":7851,"subChapters":7852,"url":7864,"docTitle":7826},"Deploying OpenShift sandboxed containers workloads","deploying-sandboxed-containers-workloads",[7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863],"sandboxed-containers-preparing-openshift-cluster_deploying-sandboxed-containers","sandboxed-containers-additional-resource-requirements_deploying-sandboxed-containers","deploying-openshift-sandboxed-containers-operator-using-the-web-console","sandboxed-containers-installing-operator-web-console_deploying-sandboxed-containers","sandboxed-containers-viewing-workloads-from-web-console_deploying-sandboxed-containers","deploying-openshift-sandboxed-containers-operator-using-the-cli","sandboxed-containers-installing-operator-cli_deploying-sandboxed-containers","sandboxed-containers-triggering-installation-kata-runtime_deploying-sandboxed-containers","sandboxed-containers-selecting-nodes_deploying-sandboxed-containers","sandboxed-containers-scheduling-workloads_deploying-sandboxed-containers","sandboxed-containers-viewing-workloads-from-cli_deploying-sandboxed-containers","/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/deploying-sandboxed-containers-workloads",{"title":7866,"visible":17,"weight":75,"urlFragment":7867,"anchor":23,"singlePageAnchor":7867,"subChapters":7868,"url":7876,"docTitle":7826},"Uninstalling OpenShift sandboxed containers","uninstalling-sandboxed-containers",[7869,7870,7871,7872,7873,7874,7875],"uninstalling-openshift-sandboxed-containers-using-the-web-console","sandboxed-containers-deleting-operator-deployment-cr_uninstalling-sandboxed-containers","sandboxed-containers-deleting-namespace-web-console_uninstalling-sandboxed-containers","sandboxed-containers-deleting-operator-web-console_uninstalling-sandboxed-containers","uninstalling-kata-runtime-from-the-cli","sandboxed-containers-deleting-resources_uninstalling-sandboxed-containers","sandboxed-containers-deleting-operator_uninstalling-sandboxed-containers","/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/uninstalling-sandboxed-containers",{"title":7878,"visible":17,"weight":442,"urlFragment":7879,"anchor":23,"singlePageAnchor":7879,"subChapters":7880,"url":7883,"docTitle":7826},"Upgrade OpenShift sandboxed containers","upgrade-sandboxed-containers",[7881,7882],"sandboxed-containers-upgrade-operator","sandboxed-containers-upgrade-artifacts","/documentation/openshift_container_platform/4.8/html/sandboxed_containers_support_for_openshift/upgrade-sandboxed-containers",{"title":7885,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":7886,"url":7887,"docTitle":7888,"sections":7889},"Operators",[],"/documentation/openshift_container_platform/4.8/html/operators/index","operators",[7890,7898,8004,8017,8072,8255],{"title":7891,"visible":17,"weight":30,"urlFragment":7892,"anchor":23,"singlePageAnchor":7892,"subChapters":7893,"url":7897,"docTitle":7888},"Operators overview","operators-overview",[7894,7895,7896],"operators-overview-developer-tasks","operators-overview-administrator-tasks","operators-overview-next-steps","/documentation/openshift_container_platform/4.8/html/operators/operators-overview",{"title":7899,"visible":17,"weight":42,"urlFragment":7900,"anchor":23,"singlePageAnchor":7900,"subChapters":7901,"url":8003,"docTitle":7888},"Understanding Operators","understanding-operators",[7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967,7968,7969,7970,7971,7972,7973,1553,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,8000,8001,8002],"olm-what-operators-are","olm-why-use-operators_olm-what-operators-are","olm-operator-framework_olm-what-operators-are","olm-maturity-model_olm-what-operators-are","olm-packaging-format","olm-bundle-format_olm-packaging-format","olm-bundle-format-manifests_olm-packaging-format","olm-bundle-format-annotations_olm-packaging-format","olm-bundle-format-dependencies_olm-packaging-format","olm-about-opm_olm-packaging-format","olm-common-terms","olm-common-terms-glossary_olm-common-terms","olm-common-terms-bundle_olm-common-terms","olm-common-terms-bundle-image_olm-common-terms","olm-common-terms-catalogsource_olm-common-terms","olm-common-terms-channel_olm-common-terms","olm-common-terms-channel-head_olm-common-terms","olm-common-terms-csv_olm-common-terms","olm-common-terms-dependency_olm-common-terms","olm-common-terms-index-image_olm-common-terms","olm-common-terms-installplan_olm-common-terms","olm-common-terms-operatorgroup_olm-common-terms","olm-common-terms-package_olm-common-terms","olm-common-terms-registry_olm-common-terms","olm-common-terms-subscription_olm-common-terms","olm-common-terms-update-graph_olm-common-terms","operator-lifecycle-manager-olm","olm-understanding-olm","olm-overview_olm-understanding-olm","olm-resources_olm-understanding-olm","olm-csv_olm-understanding-olm","olm-catalogsource_olm-understanding-olm","olm-subscription_olm-understanding-olm","olm-installplan_olm-understanding-olm","olm-operatorgroups-about_olm-understanding-olm","olm-about-operatorconditions_olm-understanding-olm","olm-arch","olm-architecture_olm-arch","olm-arch-olm-operator_olm-arch","olm-arch-catalog-operator_olm-arch","olm-arch-catalog-registry_olm-arch","olm-workflow","olm-upgrades_olm-workflow","olm-upgrades-example-upgrade-path_olm-workflow","olm-upgrades-skipping_olm-workflow","olm-upgrades-replacing-multiple_olm-workflow","olm-upgrades-z-stream_olm-workflow","olm-understanding-dependency-resolution","olm-dependency-resolution-about_olm-understanding-dependency-resolution","olm-bundle-format-dependencies_olm-understanding-dependency-resolution","olm-dependency-resolution-preferences_olm-understanding-dependency-resolution","olm-dependency-catalog-priority_olm-understanding-dependency-resolution","olm-dependency-catalog-ordering_olm-understanding-dependency-resolution","olm-dependency-order-winthin-channel_olm-understanding-dependency-resolution","olm-dependency-preferences-other_olm-understanding-dependency-resolution","olm-dependency-sub-constraint_olm-understanding-dependency-resolution","olm-dependency-package-constraint_olm-understanding-dependency-resolution","olm-dependency-resolution-crd-upgrades_olm-understanding-dependency-resolution","olm-dependency-best-practices_olm-understanding-dependency-resolution","olm-dependency-caveats_olm-understanding-dependency-resolution","olm-dependency-resolution-examples_olm-understanding-dependency-resolution","olm-understanding-operatorgroups","olm-operatorgroups-about_olm-understanding-operatorgroups","olm-operatorgroups-membership_olm-understanding-operatorgroups","olm-operatorgroups-target-namespace_olm-understanding-operatorgroups","olm-operatorgroups-csv-annotations_olm-understanding-operatorgroups","olm-operatorgroups-provided-apis-annotation_olm-understanding-operatorgroups","olm-operatorgroups-rbac_olm-understanding-operatorgroups","olm-operatorgroups-copied-csvs_olm-understanding-operatorgroups","olm-operatorgroups-static_olm-understanding-operatorgroups","olm-operatorgroups-intersection_olm-understanding-operatorgroups","olm-operatorgroups-limitations","olm-operatorgroups-troubleshooting_olm-understanding-operatorgroups","olm-operatorconditions","olm-about-operatorconditions_olm-operatorconditions","olm-supported-operatorconditions_olm-operatorconditions","olm-upgradeable-operatorcondition_olm-operatorconditions","olm-operatorconditions-addtl-resources","olm-understanding-metrics","olm-metrics_olm-understanding-metrics","olm-webhooks","olm-webhooks-additional-resources","olm-understanding-operatorhub","olm-operatorhub-overview_olm-understanding-operatorhub","olm-operatorhub-arch_olm-understanding-operatorhub","olm-operatorhub-arch-operatorhub_crd_olm-understanding-operatorhub","olm-understanding-operatorhub-resources","olm-rh-catalogs","olm-about-catalogs_olm-rh-catalogs","olm-rh-catalogs_olm-rh-catalogs","crds","crd-extending-api-with-crds","crd-custom-resource-definitions_crd-extending-api-with-crds","crd-creating-custom-resources-definition_crd-extending-api-with-crds","crd-creating-aggregated-cluster-role_crd-extending-api-with-crds","crd-creating-custom-resources-from-file_crd-extending-api-with-crds","crd-inspecting-custom-resources_crd-extending-api-with-crds","crd-managing-resources-from-crds","crd-custom-resource-definitions_crd-managing-resources-from-crds","crd-creating-custom-resources-from-file_crd-managing-resources-from-crds","crd-inspecting-custom-resources_crd-managing-resources-from-crds","/documentation/openshift_container_platform/4.8/html/operators/understanding-operators",{"title":8005,"visible":17,"weight":53,"urlFragment":8006,"anchor":23,"singlePageAnchor":8006,"subChapters":8007,"url":8016,"docTitle":7888},"User tasks","user-tasks",[8008,8009,8010,8011,8012,8013,8014,8015],"olm-creating-apps-from-installed-operators","olm-creating-etcd-cluster-from-operator_olm-creating-apps-from-installed-operators","olm-installing-operators-in-namespace","olm-installing-operators-in-namespace-prereqs","olm-installing-operators-from-operatorhub_olm-installing-operators-in-namespace","olm-installing-from-operatorhub-using-web-console_olm-installing-operators-in-namespace","olm-installing-operator-from-operatorhub-using-cli_olm-installing-operators-in-namespace","olm-installing-specific-version-cli_olm-installing-operators-in-namespace","/documentation/openshift_container_platform/4.8/html/operators/user-tasks",{"title":8018,"visible":17,"weight":75,"urlFragment":8019,"anchor":23,"singlePageAnchor":8019,"subChapters":8020,"url":8071,"docTitle":7888},"Administrator tasks","administrator-tasks",[8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031,8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063,8064,8065,8066,8067,8068,8069,8070],"olm-adding-operators-to-a-cluster","olm-installing-operators-from-operatorhub_olm-adding-operators-to-a-cluster","olm-installing-from-operatorhub-using-web-console_olm-adding-operators-to-a-cluster","olm-installing-operator-from-operatorhub-using-cli_olm-adding-operators-to-a-cluster","olm-installing-specific-version-cli_olm-adding-operators-to-a-cluster","olm-pod-placement_olm-adding-operators-to-a-cluster","olm-upgrading-operators","olm-preparing-upgrade_olm-upgrading-operators","olm-changing-update-channel_olm-upgrading-operators","olm-approving-pending-upgrade_olm-upgrading-operators","olm-deleting-operators-from-a-cluster","olm-deleting-operators-from-a-cluster-using-web-console_olm-deleting-operators-from-a-cluster","olm-deleting-operator-from-a-cluster-using-cli_olm-deleting-operators-from-a-cluster","olm-refresh-subs_olm-deleting-operators-from-a-cluster","olm-configuring-proxy-support","olm-overriding-proxy-settings_olm-configuring-proxy-support","olm-inject-custom-ca_olm-configuring-proxy-support","olm-status","olm-status-conditions_olm-status","olm-status-viewing-cli_olm-status","olm-cs-status-cli_olm-status","olm-managing-operatorconditions","olm-supported-operatorconditions_olm-managing-operatorconditions","olm-updating-use-operatorconditions_olm-managing-operatorconditions","olm-updating-use-operatorconditions-defaults_olm-managing-operatorconditions","olm-managing-operatorconditions-addtl-resources","olm-creating-policy","olm-policy-understanding_olm-creating-policy","olm-policy-scenarios_olm-creating-policy","olm-policy-workflow_olm-creating-policy","olm-policy-scoping-operator-install_olm-creating-policy","olm-policy-fine-grained-permissions_olm-creating-policy","olm-policy-catalog-access_olm-creating-policy","olm-policy-troubleshooting_olm-creating-policy","olm-managing-custom-catalogs","olm-managing-custom-catalogs-bundle-format-prereqs","olm-creating-index-image_olm-managing-custom-catalogs","olm-creating-catalog-from-index_olm-managing-custom-catalogs","olm-updating-index-image_olm-managing-custom-catalogs","olm-pruning-index-image_olm-managing-custom-catalogs","olm-accessing-images-private-registries_olm-managing-custom-catalogs","olm-restricted-networks-operatorhub_olm-managing-custom-catalogs","olm-removing-catalogs_olm-managing-custom-catalogs","olm-restricted-networks","olm-restricted-network-prereqs","olm-restricted-networks-operatorhub_olm-restricted-networks","olm-pruning-index-image_olm-restricted-networks","olm-mirror-catalog_olm-restricted-networks","olm-creating-catalog-from-index_olm-restricted-networks","olm-updating-index-image_olm-restricted-networks","/documentation/openshift_container_platform/4.8/html/operators/administrator-tasks",{"title":8073,"visible":17,"weight":442,"urlFragment":8074,"anchor":23,"singlePageAnchor":8074,"subChapters":8075,"url":8254,"docTitle":7888},"Developing Operators","developing-operators",[8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143,8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253],"osdk-about","osdk-about-what-are-operators","osdk-workflow_osdk-about","osdk-about-addtl-resources","osdk-installing-cli","osdk-installing-cli-linux-macos_osdk-installing-cli","osdk-upgrading-projects","osdk-upgrading-v130-to-v180_osdk-upgrading-projects","additional-resources_osdk-upgrading-projects","go-based-operators","osdk-golang-quickstart","osdk-common-prereqs_osdk-golang-quickstart","osdk-quickstart_osdk-golang-quickstart","osdk-golang-quickstart-next-steps","osdk-golang-tutorial","osdk-common-prereqs_osdk-golang-tutorial","osdk-create-project_osdk-golang-tutorial","osdk-project-file_osdk-golang-tutorial","osdk-golang-manager_osdk-golang-tutorial","osdk-golang-multi-group-apis_osdk-golang-tutorial","osdk-golang-create-api-controller_osdk-golang-tutorial","osdk-golang-define-api_osdk-golang-tutorial","osdk-golang-generate-crd_osdk-golang-tutorial","osdk-about-openapi-validation_osdk-golang-tutorial","osdk-golang-implement-controller_osdk-golang-tutorial","osdk-golang-controller-resources_osdk-golang-tutorial","osdk-golang-controller-configs_osdk-golang-tutorial","osdk-golang-controller-reconcile-loop_osdk-golang-tutorial","osdk-golang-controller-rbac-markers_osdk-golang-tutorial","osdk-run-operator_osdk-golang-tutorial","osdk-run-locally_osdk-golang-tutorial","osdk-run-deployment_osdk-golang-tutorial","osdk-bundle-deploy-olm_osdk-golang-tutorial","osdk-bundle-operator_osdk-golang-tutorial","osdk-deploy-olm_osdk-golang-tutorial","osdk-create-cr_osdk-golang-tutorial","osdk-golang-tutorial-addtl-resources","osdk-golang-project-layout","osdk-golang-project-layout_osdk-golang-project-layout","ansible-based-operators","osdk-ansible-quickstart","osdk-common-prereqs_osdk-ansible-quickstart","osdk-quickstart_osdk-ansible-quickstart","osdk-ansible-quickstart-next-steps","osdk-ansible-tutorial","osdk-common-prereqs_osdk-ansible-tutorial","osdk-create-project_osdk-ansible-tutorial","osdk-project-file_osdk-ansible-tutorial","osdk-ansible-create-api-controller_osdk-ansible-tutorial","osdk-ansible-modify-manager_osdk-ansible-tutorial","osdk-run-operator_osdk-ansible-tutorial","osdk-run-locally_osdk-ansible-tutorial","osdk-run-deployment_osdk-ansible-tutorial","osdk-bundle-deploy-olm_osdk-ansible-tutorial","osdk-bundle-operator_osdk-ansible-tutorial","osdk-deploy-olm_osdk-ansible-tutorial","osdk-create-cr_osdk-ansible-tutorial","osdk-ansible-tutorial-addtl-resources","osdk-ansible-project-layout","osdk-ansible-project-layout_osdk-ansible-project-layout","osdk-ansible-support","osdk-ansible-custom-resource-files_osdk-ansible-support","osdk-ansible-watches-file_osdk-ansible-support","osdk-ansible-watches-file-advanced_osdk-ansible-support","osdk-ansible-extra-variables_osdk-ansible-support","osdk-ansible-runner-directory_osdk-ansible-support","osdk-ansible-k8s-collection","osdk-ansible-installing-k8s-collection_osdk-ansible-k8s-collection","osdk-ansible-k8s-local_osdk-ansible-k8s-collection","osdk-ansible-k8s-collection-next-steps","osdk-ansible-inside-operator","osdk-ansible-custom-resource-files_osdk-ansible-inside-operator","osdk-ansible-inside-operator-local_osdk-ansible-inside-operator","osdk-run-deployment_osdk-ansible-inside-operator","osdk-ansible-inside-operator-logs_osdk-ansible-inside-operator","osdk-ansible-inside-operator-logs-view_osdk-ansible-inside-operator","osdk-ansible-inside-operator-logs-full-result_osdk-ansible-inside-operator","osdk-ansible-inside-operator-logs-verbose_osdk-ansible-inside-operator","osdk-ansible-cr-status","osdk-ansible-cr-status-about_osdk-ansible-cr-mgmt","osdk-ansible-cr-status-manual_osdk-ansible-cr-mgmt","helm-based-operators","osdk-helm-quickstart","osdk-common-prereqs_osdk-helm-quickstart","osdk-quickstart_osdk-helm-quickstart","osdk-helm-quickstart-next-steps","osdk-helm-tutorial","osdk-common-prereqs_osdk-helm-tutorial","osdk-create-project_osdk-helm-tutorial","osdk-helm-existing-chart_osdk-helm-tutorial","osdk-project-file_osdk-helm-tutorial","osdk-helm-logic_osdk-helm-tutorial","osdk-helm-sample-chart_osdk-helm-tutorial","osdk-helm-modify-cr_osdk-helm-tutorial","osdk-run-operator_osdk-helm-tutorial","osdk-run-locally_osdk-helm-tutorial","osdk-run-deployment_osdk-helm-tutorial","osdk-bundle-deploy-olm_osdk-helm-tutorial","osdk-bundle-operator_osdk-helm-tutorial","osdk-deploy-olm_osdk-helm-tutorial","osdk-create-cr_osdk-helm-tutorial","osdk-helm-tutorial-addtl-resources","osdk-helm-project-layout","osdk-helm-project-layout_osdk-helm-project-layout","osdk-helm-support","osdk-helm-charts_osdk-helm-support","osdk-generating-csvs","osdk-how-csv-gen-works_osdk-generating-csvs","osdk-csv-bundle-files_osdk-generating-csvs","osdk-csv-ver_osdk-generating-csvs","osdk-manually-defined-csv-fields_osdk-generating-csvs","osdk-csv-manual-annotations_osdk-generating-csvs","olm-enabling-operator-for-restricted-network_osdk-generating-csvs","olm-enabling-operator-for-multi-arch_osdk-generating-csvs","olm-arch-os-support_osdk-generating-csvs","osdk-suggested-namespace_osdk-generating-csvs","osdk-operatorconditions_osdk-generating-csvs","olm-defining-csv-webhook_osdk-generating-csvs","olm-webhook-considerations_osdk-generating-csvs","osdk-crds_osdk-generating-csvs","osdk-crds-owned_osdk-generating-csvs","osdk-crds-required_osdk-generating-csvs","olm-dependency-resolution-crd-upgrades_osdk-generating-csvs","olm-dependency-resolution-adding-new-crd-version_osdk-generating-csvs","olm-dependency-resolution-removing-crd-version_osdk-generating-csvs","osdk-crds-templates_osdk-generating-csvs","osdk-hiding-internal-objects_osdk-generating-csvs","osdk-init-resource_osdk-generating-csvs","osdk-apiservices_osdk-generating-csvs","osdk-apiservices-owned_osdk-generating-csvs","osdk-apiservices-resource-creation_osdk-generating-csvs","osdk-apiservices-service-certs_osdk-generating-csvs","osdk-apiservice-required_osdk-generating-csvs","osdk-working-bundle-images","osdk-bundle-operator_osdk-working-bundle-images","osdk-deploy-olm_osdk-working-bundle-images","osdk-publish-catalog_osdk-working-bundle-images","osdk-bundle-upgrade-olm_osdk-working-bundle-images","osdk-control-compat_osdk-working-bundle-images","osdk-working-bundle-images-additional-resources","osdk-scorecard","osdk-about-scorecard_osdk-scorecard","osdk-scorecard-config_osdk-scorecard","osdk-scorecard-tests_osdk-scorecard","osdk-scorecard-run_osdk-scorecard","osdk-scorecard-output_osdk-scorecard","osdk-scorecard-select-tests_osdk-scorecard","osdk-scorecard-parallel_osdk-scorecard","osdk-scorecard-custom-tests_osdk-scorecard","osdk-monitoring-prometheus","osdk-monitoring-prometheus-operator-support_osdk-monitoring-prometheus","osdk-monitoring-prometheus-metrics-helper_osdk-monitoring-prometheus","osdk-monitoring-prometheus-metrics-helper-modifying-port_osdk-monitoring-prometheus","osdk-monitoring-prometheus-servicemonitor_osdk-monitoring-prometheus","osdk-monitoring-prometheus-servicemonitor-creating_osdk-monitoring-prometheus","osdk-leader-election","osdk-leader-election-types_osdk-leader-election","osdk-leader-for-life-election_osdk-leader-election","osdk-leader-with-lease-election_osdk-leader-election","osdk-pkgman-to-bundle","osdk-about-pkg-format-migration_osdk-pkgman-to-bundle","osdk-migrating-pkgman_osdk-pkgman-to-bundle","osdk-cli-ref","osdk-cli-ref-bundle_osdk-cli-ref","osdk-cli-ref-bundle-validate_osdk-cli-ref","osdk-cli-ref-cleanup_osdk-cli-ref","osdk-cli-ref-completion_osdk-cli-ref","osdk-cli-ref-create_osdk-cli-ref","osdk-cli-ref-create-api_osdk-cli-ref","osdk-cli-ref-generate_osdk-cli-ref","osdk-cli-ref-generate-bundle_osdk-cli-ref","osdk-cli-ref-generate-kustomize_osdk-cli-ref","osdk-cli-ref-generate-kustomize-manifests_osdk-cli-ref","osdk-cli-ref-init_osdk-cli-ref","osdk-cli-ref-run_osdk-cli-ref","osdk-cli-ref-run-bundle_osdk-cli-ref","osdk-cli-ref-run-bundle-upgrade_osdk-cli-ref","osdk-cli-ref-scorecard_osdk-cli-ref","/documentation/openshift_container_platform/4.8/html/operators/developing-operators",{"title":8256,"visible":17,"weight":460,"urlFragment":8257,"anchor":23,"singlePageAnchor":8257,"subChapters":8258,"url":8289,"docTitle":7888},"Cluster Operators reference","cluster-operators-ref",[8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271,8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288],"cloud-credential-operator_cluster-operators-ref","cluster-authentication-operator_cluster-operators-ref","cluster-autoscaler-operator_cluster-operators-ref","cluster-config-operator_cluster-operators-ref","cluster-csi-snapshot-controller-operator_cluster-operators-ref","cluster-image-registry-operator_cluster-operators-ref","cluster-machine-approver-operator_cluster-operators-ref","cluster-monitoring-operator_cluster-operators-ref","cluster-network-operator_cluster-operators-ref","cluster-openshift-controller-manager-operator_cluster-operators-ref","cluster-samples-operator_cluster-operators-ref","cluster-storage-operator_cluster-operators-ref","cluster-version-operator_cluster-operators-ref","console-operator_cluster-operators-ref","dns-operator_cluster-operators-ref","etcd-cluster-operator_cluster-operators-ref","ingress-operator_cluster-operators-ref","insights-operator_cluster-operators-ref","kube-apiserver-operator_cluster-operators-ref","kube-controller-manager-operator_cluster-operators-ref","cluster-kube-scheduler-operator_cluster-operators-ref","cluster-kube-storage-version-migrator-operator_cluster-operators-ref","machine-api-operator_cluster-operators-ref","machine-config-operator_cluster-operators-ref","marketplace-operator_cluster-operators-ref","about-node-tuning-operator_cluster-operators-ref","openshift-apiserver-operator_cluster-operators-ref","cluster-operators-ref-olm","openshift-service-ca-operator_cluster-operators-ref","vsphere-problem-detector-operator_cluster-operators-ref","/documentation/openshift_container_platform/4.8/html/operators/cluster-operators-ref",{"title":8291,"visible":17,"categoryName":17,"sections":8292},"Monitor",[8293,8706,8815,9071],{"title":8294,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":8295,"url":8296,"docTitle":5022,"sections":8297},"Logging",[],"/documentation/openshift_container_platform/4.8/html/logging/index",[8298,8427,8447,8456,8500,8506,8513,8540,8548,8554,8561,8569,8602,8608,8613,8617,8621,8626,8630,8634,8638,8642,8646,8650,8655,8660,8665,8699],{"title":8299,"visible":17,"weight":30,"urlFragment":8300,"anchor":23,"singlePageAnchor":8300,"subChapters":8301,"url":8426,"docTitle":5022},"Release notes for Logging","release-notes",[8302,8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421,8422,8423,8424,8425],"cluster-logging-release-notes-5-4-9_cluster-logging-release-notes-v5x","openshift-logging-5-4-9-bug-fixes","openshift-logging-5-4-9-CVEs","cluster-logging-release-notes-5-4-8_cluster-logging-release-notes-v5x","openshift-logging-5-4-8-bug-fixes","openshift-logging-5-4-8-CVEs","cluster-logging-release-notes-5-4-6_cluster-logging-release-notes-v5x","openshift-logging-5-4-6-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-4-6-cves_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-4-5_cluster-logging-release-notes-v5x","openshift-logging-5-4-5-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-4-5-cves_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-4-4","openshift-logging-5-4-4-bug-fixes","openshift-logging-5-4-4-cves","cluster-logging-release-notes-5-4-3","openshift-logging-elasticsearch-dep","openshift-logging-5-4-3-bug-fixes","openshift-logging-5-4-3-CVEs","cluster-logging-release-notes-5-4-2","openshift-logging-5-4-2-bug-fixes","openshift-logging-5-4-2-CVEs","cluster-logging-release-notes-5-4-1_cluster-logging-release-notes-v5x","openshift-logging-5-4-1-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-4-1-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-4-0_cluster-logging-release-notes-v5x","openshift-logging-5-4-0-tech-prev_cluster-logging-release-notes-v5x","cluster-logging-about-vector","cluster-logging-enabling-vector","cluster-logging-about-loki","deploying-the-lokistack","openshift-logging-5-4-0-bug-fixes_cluster-logging-release-notes-v5x","cves","cluster-logging-release-notes-5-3-13_cluster-logging-release-notes-v5x","openshift-logging-5-3-13-bug-fixes","openshift-logging-5-3-13-CVEs","cluster-logging-release-notes-5-3-12_cluster-logging-release-notes-v5x","openshift-logging-5-3-12-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-3-12-cves_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-3-11_cluster-logging-release-notes-v5x","openshift-logging-5-3-11-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-3-11-cves_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-3-10","openshift-logging-5-3-10-bug-fixes","openshift-logging-5-3-10-cves","cluster-logging-release-notes-5-3-9","openshift-logging-5-3-9-bug-fixes","openshift-logging-5-3-9-CVEs","cluster-logging-release-notes-5-3-8","openshift-logging-5-3-8-bug-fixes","openshift-logging-5-3-8-CVEs","cluster-logging-release-notes-5-3-7_cluster-logging-release-notes-v5x","openshift-logging-5-3-7-bug-fixes_cluster-logging-release-notes-v5x","cves-2","cluster-logging-release-notes-5-3-6_cluster-logging-release-notes-v5x","openshift-logging-5-3-6-bug-fixes_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-3-5_cluster-logging-release-notes-v5x","openshift-logging-5-3-5-bug-fixes_cluster-logging-release-notes-v5x","cves-3","cluster-logging-release-notes-5-3-4_cluster-logging-release-notes-v5x","openshift-logging-5-3-4-bug-fixes_cluster-logging-release-notes-v5x","cves-4","cluster-logging-release-notes-5-3-3_cluster-logging-release-notes-v5x","openshift-logging-5-3-3-bug-fixes","cves-5","cluster-logging-release-notes-5-3-2_cluster-logging-release-notes-v5x","openshift-logging-5-3-2-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-3-2-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-3-1_cluster-logging-release-notes-v5x","openshift-logging-5-3-1-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-3-1-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-3-0_cluster-logging-release-notes-v5x","openshift-logging-5-3-0-new-features-and-enhancements_cluster-logging-release-notes-v5x","openshift-logging-5-3-0-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-3-0-known-issues_cluster-logging-release-notes-v5x","openshift-logging-5-3-0-deprecated-removed-features_cluster-logging-release-notes-v5x","openshift-logging-5-3-0-legacy-forwarding_cluster-logging-release-notes-v5x","openshift-logging-5-3-0-legacy-forwarding-config_cluster-logging-release-notes-v5x","openshift-logging-5-3-0-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-13","openshift-logging-5-2-13-bug-fixes","openshift-logging-5-2-13-cves","cluster-logging-release-notes-5-2-12","openshift-logging-5-2-12-bug-fixes","openshift-logging-5-2-12-CVEs","cluster-logging-release-notes-5-2-11","openshift-logging-5-2-11-bug-fixes","openshift-logging-5-2-11-CVEs","cluster-logging-release-notes-5-2-10_cluster-logging-release-notes-v5x","openshift-logging-5-2-10-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-10-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-9_cluster-logging-release-notes-v5x","openshift-logging-5-2-9-bug-fixes_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-8_cluster-logging-release-notes-v5x","openshift-logging-5-2-8-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-8-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-7_cluster-logging-release-notes-v5x","openshift-logging-5-2-7-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-7-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-6_cluster-logging-release-notes-v5x","openshift-logging-5-2-6-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-6-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-5_cluster-logging-release-notes-v5x","openshift-logging-5-2-5-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-5-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-4_cluster-logging-release-notes-v5x","openshift-logging-5-2-4-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-4-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-3_cluster-logging-release-notes-v5x","openshift-logging-5-2-3-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-3-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-2_cluster-logging-release-notes-v5x","openshift-logging-5-2-2-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-2-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-1_cluster-logging-release-notes-v5x","openshift-logging-5-2-1-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-1-CVEs_cluster-logging-release-notes-v5x","cluster-logging-release-notes-5-2-0_cluster-logging-release-notes-v5x","openshift-logging-5-2-0-new-features-and-enhancements_cluster-logging-release-notes-v5x","openshift-logging-5-2-0-bug-fixes_cluster-logging-release-notes-v5x","openshift-logging-5-2-0-known-issues_cluster-logging-release-notes-v5x","openshift-logging-5-2-0-deprecated-removed-features_cluster-logging-release-notes-v5x","openshift-logging-5-2-0-legacy-forwarding_cluster-logging-release-notes-v5x","openshift-logging-5-2-0-CVEs_cluster-logging-release-notes-v5x","/documentation/openshift_container_platform/4.8/html/logging/release-notes",{"title":8428,"visible":17,"weight":42,"urlFragment":8429,"anchor":23,"singlePageAnchor":8429,"subChapters":8430,"url":8446,"docTitle":5022},"Understanding Red Hat OpenShift Logging","cluster-logging",[8431,8432,8433,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445],"openshift-logging-common-terms_cluster-logging","cluster-logging-about_cluster-logging","cluster-logging-json-logging-about_cluster-logging","cluster-logging-collecting-storing-kubernetes-events-about_cluster-logging","cluster-logging-update-logging-about_cluster-logging","cluster-logging-view-cluster-dashboards-about_cluster-logging","cluster-logging-troubleshoot-logging-about_cluster-logging","cluster-logging-uninstall-logging-about_cluster-logging","cluster-logging-export-fields-about_cluster-logging","cluster-logging-about-components_cluster-logging","cluster-logging-about-collector_cluster-logging","cluster-logging-about-logstore_cluster-logging","cluster-logging-about-visualizer_cluster-logging","cluster-logging-eventrouter-about_cluster-logging","cluster-logging-forwarding-about_cluster-logging","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging",{"title":8448,"visible":17,"weight":53,"urlFragment":8449,"anchor":23,"singlePageAnchor":8449,"subChapters":8450,"url":8455,"docTitle":5022},"Installing OpenShift Logging","cluster-logging-deploying",[8451,2710,8452,2737,8453,8454],"cluster-logging-deploy-console_cluster-logging-deploying","cluster-logging-deploy-cli_cluster-logging-deploying","cluster-logging-visualizer-indices_cluster-logging-deploying","cluster-logging-deploy-multitenant_cluster-logging-deploying","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-deploying",{"title":8457,"visible":17,"weight":75,"urlFragment":8458,"anchor":23,"singlePageAnchor":8458,"subChapters":8459,"url":8499,"docTitle":5022},"Configuring your Logging deployment","configuring-your-logging-deployment",[8460,8461,8462,8463,8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495,8496,8497,8498],"cluster-logging-configuring-cr","cluster-logging-configuring-crd_cluster-logging-configuring-cr","cluster-logging-collector","cluster-logging-maintenance-support-about_cluster-logging-collector","cluster-logging-collector-pod-location_cluster-logging-collector","cluster-logging-collector-limits_cluster-logging-collector","cluster-logging-collector-tuning_cluster-logging-collector","cluster-logging-removing-unused-components-if-no-elasticsearch_cluster-logging-collector","cluster-logging-store","cluster-logging-elasticsearch-audit_cluster-logging-store","cluster-logging-elasticsearch-retention_cluster-logging-store","cluster-logging-logstore-limits_cluster-logging-store","cluster-logging-elasticsearch-ha_cluster-logging-store","cluster-logging-elasticsearch-scaledown_cluster-logging-store","cluster-logging-elasticsearch-storage_cluster-logging-store","cluster-logging-elasticsearch-persistent-storage-empty_cluster-logging-store","cluster-logging-manual-rollout-rolling_cluster-logging-store","cluster-logging-elasticsearch-exposing_cluster-logging-store","cluster-logging-visualizer","cluster-logging-memory-limits_cluster-logging-visualizer","cluster-logging-kibana-scaling_cluster-logging-visualizer","cluster-logging-storage","cluster-logging-deploy-storage-considerations_cluster-logging-storage","cluster-logging-storage-considerations-addtl-resources","cluster-logging-memory","cluster-logging-memory-limits_cluster-logging-memory","cluster-logging-tolerations","cluster-logging-elasticsearch-tolerations_cluster-logging-tolerations","cluster-logging-kibana-tolerations_cluster-logging-tolerations","cluster-logging-collector-tolerations_cluster-logging-tolerations","cluster-logging-tolerations-addtl-resources","cluster-logging-moving","infrastructure-moving-logging_cluster-logging-moving","cluster-logging-systemd","cluster-logging-systemd-scaling_cluster-logging-systemd","cluster-logging-maintenance-and-support","cluster-logging-maintenance-support-about_cluster-logging-unsupported","cluster-logging-maintenance-support-list_cluster-logging-unsupported","unmanaged-operators_cluster-logging-unsupported","/documentation/openshift_container_platform/4.8/html/logging/configuring-your-logging-deployment",{"title":8501,"visible":17,"weight":442,"urlFragment":8502,"anchor":23,"singlePageAnchor":8502,"subChapters":8503,"url":8505,"docTitle":5022},"Viewing logs for a resource","vewing-resource-logs",[8504],"viewing-resource-logs-cli-console_viewing-resource-logs","/documentation/openshift_container_platform/4.8/html/logging/vewing-resource-logs",{"title":8507,"visible":17,"weight":460,"urlFragment":8508,"anchor":23,"singlePageAnchor":8508,"subChapters":8509,"url":8512,"docTitle":5022},"Viewing cluster logs by using Kibana","cluster-logging-visualizer-using",[8510,8511],"cluster-logging-visualizer-indices_cluster-logging-visualizer","cluster-logging-visualizer-kibana_cluster-logging-visualizer","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-visualizer-using",{"title":8514,"visible":17,"weight":475,"urlFragment":8515,"anchor":23,"singlePageAnchor":8515,"subChapters":8516,"url":8539,"docTitle":5022},"Forwarding logs to external third-party logging systems","cluster-logging-external",[8517,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538],"cluster-logging-collector-log-forwarding-about_cluster-logging-external","creating-a-secret","cluster-logging-collector-log-forwarding-supported-plugins-5-1_cluster-logging-external","cluster-logging-collector-log-forwarding-supported-plugins-5-2_cluster-logging-external","cluster-logging-collector-log-forwarding-supported-plugins-5-3_cluster-logging-external","cluster-logging-collector-log-forwarding-supported-plugins-5-4_cluster-logging-external","cluster-logging-collector-log-forwarding-supported-plugins-5-5_cluster-logging-external","cluster-logging-collector-log-forwarding-supported-plugins-5-6_cluster-logging-external","cluster-logging-collector-log-forward-es_cluster-logging-external","cluster-logging-collector-log-forward-fluentd_cluster-logging-external","cluster-logging-collector-log-forward-nano-precision","cluster-logging-collector-log-forward-syslog_cluster-logging-external","cluster-logging-collector-log-forward-examples-syslog-log-source","cluster-logging-collector-log-forward-examples-syslog-parms","cluster-logging-collector-log-forward-examples-syslog-5424","cluster-logging-collector-log-forward-cloudwatch_cluster-logging-external","cluster-logging-collector-log-forward-loki_cluster-logging-external","cluser-logging-troubleshooting-loki-entry-out-of-order-messages_cluster-logging-external","cluster-logging-collector-log-forward-project_cluster-logging-external","cluster-logging-collector-log-forward-logs-from-application-pods_cluster-logging-external","cluster-logging-collecting-ovn-audit-logs_cluster-logging-external","cluster-logging-troubleshooting-log-forwarding_cluster-logging-external","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-external",{"title":8541,"visible":17,"weight":876,"urlFragment":8542,"anchor":23,"singlePageAnchor":8542,"subChapters":8543,"url":8547,"docTitle":5022},"Enabling JSON logging","cluster-logging-enabling-json-logging",[8544,8545,8546],"cluster-logging-json-log-forwarding_cluster-logging-enabling-json-logging","cluster-logging-configuration-of-json-log-data-for-default-elasticsearch_cluster-logging-enabling-json-logging","cluster-logging-forwarding-json-logs-to-the-default-elasticsearch_cluster-logging-enabling-json-logging","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-enabling-json-logging",{"title":8549,"visible":17,"weight":884,"urlFragment":8550,"anchor":23,"singlePageAnchor":8550,"subChapters":8551,"url":8553,"docTitle":5022},"Collecting and storing Kubernetes events","cluster-logging-eventrouter",[8552],"cluster-logging-eventrouter-deploy_cluster-logging-eventrouter","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-eventrouter",{"title":8555,"visible":17,"weight":895,"urlFragment":8556,"anchor":23,"singlePageAnchor":8556,"subChapters":8557,"url":8560,"docTitle":5022},"Updating OpenShift Logging","cluster-logging-upgrading",[8558,8559],"cluster-logging-updating-logging-to-5-0_cluster-logging-upgrading","cluster-logging-updating-logging-to-5-1_cluster-logging-upgrading","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-upgrading",{"title":8562,"visible":17,"weight":906,"urlFragment":8563,"anchor":23,"singlePageAnchor":8563,"subChapters":8564,"url":8568,"docTitle":5022},"Viewing cluster dashboards","cluster-logging-dashboards",[8565,8566,8567],"cluster-logging-dashboards-access_cluster-logging-dashboards","cluster-logging-dashboards-logging_cluster-logging-dashboards","cluster-logging-dashboards-es_cluster-logging-dashboards","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-dashboards",{"title":8570,"visible":17,"weight":913,"urlFragment":8571,"anchor":23,"singlePageAnchor":8571,"subChapters":8572,"url":8601,"docTitle":5022},"Troubleshooting Logging","troubleshooting-logging",[8573,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,8600],"cluster-logging-cluster-status","cluster-logging-clo-status_cluster-logging-cluster-status","cluster-logging-clo-status-message_cluster-logging-cluster-status","cluster-logging-clo-status-example_cluster-logging-cluster-status","cluster-logging-log-store-status","cluster-logging-log-store-comp-viewing_cluster-logging-elasticsearch","cluster-logging-elasticsearch-status-message_cluster-logging-elasticsearch","cluster-logging-elasticsearch-status-comp_cluster-logging-elasticsearch","ref_cluster-logging-elasticsearch-cluster-status_cluster-logging-elasticsearch","cluster-logging-alerts","cluster-logging-collector-alerts-viewing_cluster-logging-alerts","cluster-logging-collector-alerts_cluster-logging-alerts","cluster-logging-elasticsearch-rules_cluster-logging-alerts","cluster-logging-must-gather","about-must-gather_cluster-logging-must-gather","cluster-logging-must-gather-prereqs","cluster-logging-must-gather-collecting_cluster-logging-must-gather","cluster-logging-troubleshooting-for-critical-alerts","elasticsearch-cluster-health-is-red","elasticsearch-cluster-health-is-yellow","elasticsearch-node-disk-low-watermark-reached","elasticsearch-node-disk-high-watermark-reached","elasticsearch-node-disk-flood-watermark-reached","elasticsearch-jvm-heap-use-is-high","aggregated-logging-system-cpu-is-high","elasticsearch-process-cpu-is-high","elasticsearch-disk-space-is-running-low","elasticsearch-filedescriptor-usage-is-high","/documentation/openshift_container_platform/4.8/html/logging/troubleshooting-logging",{"title":8603,"visible":17,"weight":922,"urlFragment":8604,"anchor":23,"singlePageAnchor":8604,"subChapters":8605,"url":8607,"docTitle":5022},"Uninstalling OpenShift Logging","cluster-logging-uninstall",[8606],"cluster-logging-uninstall_cluster-logging-uninstall","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-uninstall",{"title":8609,"visible":17,"weight":2806,"urlFragment":8610,"anchor":23,"singlePageAnchor":8610,"subChapters":8611,"url":8612,"docTitle":5022},"Log Record Fields","cluster-logging-exported-fields",[],"/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-exported-fields",{"title":8614,"visible":17,"weight":3071,"urlFragment":8614,"anchor":23,"singlePageAnchor":8614,"subChapters":8615,"url":8616,"docTitle":5022},"message",[],"/documentation/openshift_container_platform/4.8/html/logging/message",{"title":8618,"visible":17,"weight":3339,"urlFragment":8618,"anchor":23,"singlePageAnchor":8618,"subChapters":8619,"url":8620,"docTitle":5022},"structured",[],"/documentation/openshift_container_platform/4.8/html/logging/structured",{"title":8622,"visible":17,"weight":3395,"urlFragment":8623,"anchor":23,"singlePageAnchor":8623,"subChapters":8624,"url":8625,"docTitle":5022},"@timestamp","timestamp",[],"/documentation/openshift_container_platform/4.8/html/logging/timestamp",{"title":8627,"visible":17,"weight":3421,"urlFragment":8627,"anchor":23,"singlePageAnchor":8627,"subChapters":8628,"url":8629,"docTitle":5022},"hostname",[],"/documentation/openshift_container_platform/4.8/html/logging/hostname",{"title":8631,"visible":17,"weight":3436,"urlFragment":8631,"anchor":23,"singlePageAnchor":8631,"subChapters":8632,"url":8633,"docTitle":5022},"ipaddr4",[],"/documentation/openshift_container_platform/4.8/html/logging/ipaddr4",{"title":8635,"visible":17,"weight":3448,"urlFragment":8635,"anchor":23,"singlePageAnchor":8635,"subChapters":8636,"url":8637,"docTitle":5022},"ipaddr6",[],"/documentation/openshift_container_platform/4.8/html/logging/ipaddr6",{"title":8639,"visible":17,"weight":4660,"urlFragment":8639,"anchor":23,"singlePageAnchor":8639,"subChapters":8640,"url":8641,"docTitle":5022},"level",[],"/documentation/openshift_container_platform/4.8/html/logging/level",{"title":8643,"visible":17,"weight":4669,"urlFragment":8643,"anchor":23,"singlePageAnchor":8643,"subChapters":8644,"url":8645,"docTitle":5022},"pid",[],"/documentation/openshift_container_platform/4.8/html/logging/pid",{"title":8647,"visible":17,"weight":4681,"urlFragment":8647,"anchor":23,"singlePageAnchor":8647,"subChapters":8648,"url":8649,"docTitle":5022},"service",[],"/documentation/openshift_container_platform/4.8/html/logging/service",{"title":8651,"visible":17,"weight":8652,"urlFragment":8651,"anchor":23,"singlePageAnchor":8651,"subChapters":8653,"url":8654,"docTitle":5022},"tags",25,[],"/documentation/openshift_container_platform/4.8/html/logging/tags",{"title":8656,"visible":17,"weight":8657,"urlFragment":8656,"anchor":23,"singlePageAnchor":8656,"subChapters":8658,"url":8659,"docTitle":5022},"file",26,[],"/documentation/openshift_container_platform/4.8/html/logging/file",{"title":8661,"visible":17,"weight":8662,"urlFragment":8661,"anchor":23,"singlePageAnchor":8661,"subChapters":8663,"url":8664,"docTitle":5022},"offset",27,[],"/documentation/openshift_container_platform/4.8/html/logging/offset",{"title":8666,"visible":17,"weight":8667,"urlFragment":8668,"anchor":23,"singlePageAnchor":8668,"subChapters":8669,"url":8698,"docTitle":5022},"kubernetes",28,"cluster-logging-exported-fields-kubernetes_cluster-logging-exported-fields",[8670,8671,8672,8673,8674,8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,8693,8694,8695,8696,8697],"kubernetes-pod_name","kubernetes-pod_id","kubernetes-namespace_name","kubernetes-namespace_id","kubernetes-host","kubernetes-container_name","kubernetes-annotations","kubernetes-labels","kubernetes-event","kubernetes-event-verb","kubernetes-event-metadata","kubernetes-event-metadata-name","kubernetes-event-metadata-namespace","kubernetes-event-metadata-selflink","kubernetes-event-metadata-uid","kubernetes-event-metadata-resourceversion","kubernetes-event-involvedobject","kubernetes-event-involvedobject-kind","kubernetes-event-involvedobject-namespace","kubernetes-event-involvedobject-name","kubernetes-event-involvedobject-uid","kubernetes-event-involvedobject-apiversion","kubernetes-event-involvedobject-resourceversion","kubernetes-event-reason","kubernetes-event-source_component","kubernetes-event-firsttimestamp","kubernetes-event-count","kubernetes-event-type","/documentation/openshift_container_platform/4.8/html/logging/cluster-logging-exported-fields-kubernetes_cluster-logging-exported-fields",{"title":8700,"visible":17,"weight":8701,"urlFragment":8702,"anchor":23,"singlePageAnchor":8702,"subChapters":8703,"url":8705,"docTitle":5022},"OpenShift",29,"openshift",[8704],"openshift-labels","/documentation/openshift_container_platform/4.8/html/logging/openshift",{"title":8707,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":8708,"url":8709,"docTitle":8710,"sections":8711},"Monitoring",[],"/documentation/openshift_container_platform/4.8/html/monitoring/index","monitoring",[8712,8724,8747,8759,8772,8794,8801,8808],{"title":8713,"visible":17,"weight":30,"urlFragment":8714,"anchor":23,"singlePageAnchor":8714,"subChapters":8715,"url":8723,"docTitle":8710},"Monitoring overview","monitoring-overview",[8716,8717,8718,8719,8720,8721,8722,1553,978],"about-openshift-monitoring","understanding-the-monitoring-stack_monitoring-overview","default-monitoring-components_monitoring-overview","default-monitoring-targets_monitoring-overview","components-for-monitoring-user-defined-projects_monitoring-overview","monitoring-targets-for-user-defined-projects_monitoring-overview","openshift-monitoring-common-terms_monitoring-overview","/documentation/openshift_container_platform/4.8/html/monitoring/monitoring-overview",{"title":8725,"visible":17,"weight":42,"urlFragment":8726,"anchor":23,"singlePageAnchor":8726,"subChapters":8727,"url":8746,"docTitle":8710},"Configuring the monitoring stack","configuring-the-monitoring-stack",[1013,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,3642,8738,8739,8740,8741,8742,8743,8744,8745,1004],"maintenance-and-support_configuring-the-monitoring-stack","support-considerations_configuring-the-monitoring-stack","unmanaged-monitoring-operators_configuring-the-monitoring-stack","preparing-to-configure-the-monitoring-stack","creating-cluster-monitoring-configmap_configuring-the-monitoring-stack","creating-user-defined-workload-monitoring-configmap_configuring-the-monitoring-stack","configuring-the-monitoring-stack_configuring-the-monitoring-stack","configurable-monitoring-components_configuring-the-monitoring-stack","moving-monitoring-components-to-different-nodes_configuring-the-monitoring-stack","assigning-tolerations-to-monitoring-components_configuring-the-monitoring-stack","persistent-storage-prerequisites","configuring-a-local-persistent-volume-claim_configuring-the-monitoring-stack","modifying-retention-time-for-prometheus-metrics-data_configuring-the-monitoring-stack","controlling-the-impact-of-unbound-attributes-in-user-defined-projects_configuring-the-monitoring-stack","setting-a-scrape-sample-limit-for-user-defined-projects_configuring-the-monitoring-stack","creating-scrape-sample-alerts_configuring-the-monitoring-stack","attaching-additional-labels-to-your-time-series-and-alerts_configuring-the-monitoring-stack","setting-log-levels-for-monitoring-components_configuring-the-monitoring-stack","/documentation/openshift_container_platform/4.8/html/monitoring/configuring-the-monitoring-stack",{"title":8748,"visible":17,"weight":53,"urlFragment":8749,"anchor":23,"singlePageAnchor":8749,"subChapters":8750,"url":8758,"docTitle":8710},"Enabling monitoring for user-defined projects","enabling-monitoring-for-user-defined-projects",[8751,8752,8753,8754,8755,8756,8757,1022],"enabling-monitoring-for-user-defined-projects_enabling-monitoring-for-user-defined-projects","granting-users-permission-to-monitor-user-defined-projects_enabling-monitoring-for-user-defined-projects","granting-user-permissions-using-the-web-console_enabling-monitoring-for-user-defined-projects","granting-user-permissions-using-the-cli_enabling-monitoring-for-user-defined-projects","granting-users-permission-to-configure-monitoring-for-user-defined-projects_enabling-monitoring-for-user-defined-projects","accessing-metrics-from-outside-cluster_enabling-monitoring-for-user-defined-projects","disabling-monitoring-for-user-defined-projects_enabling-monitoring-for-user-defined-projects","/documentation/openshift_container_platform/4.8/html/monitoring/enabling-monitoring-for-user-defined-projects",{"title":8760,"visible":17,"weight":75,"urlFragment":8761,"anchor":23,"singlePageAnchor":8761,"subChapters":8762,"url":8771,"docTitle":8710},"Managing metrics","managing-metrics",[8763,8764,8765,8766,8767,8768,8769,8770,1043],"understanding-metrics_managing-metrics","setting-up-metrics-collection-for-user-defined-projects_managing-metrics","deploying-a-sample-service_managing-metrics","specifying-how-a-service-is-monitored_managing-metrics","querying-metrics_managing-metrics","querying-metrics-for-all-projects-as-an-administrator_managing-metrics","querying-metrics-for-user-defined-projects-as-a-developer_managing-metrics","exploring-the-visualized-metrics_managing-metrics","/documentation/openshift_container_platform/4.8/html/monitoring/managing-metrics",{"title":8773,"visible":17,"weight":442,"urlFragment":8774,"anchor":23,"singlePageAnchor":8774,"subChapters":8775,"url":8793,"docTitle":8710},"Managing alerts","managing-alerts",[8776,8777,8778,8779,8780,8781,8782,8783,8784,8785,8786,8787,8788,8789,8790,8791,8792,1069],"accessing_the_alerting_ui_managing-alerts","searching-alerts-silences-and-alerting-rules_managing-alerts","getting-information-about-alerts-silences-and-alerting-rules_managing-alerts","managing-alerting-rules_managing-alerts","Optimizing-alerting-for-user-defined-projects_managing-alerts","creating-alerting-rules-for-user-defined-projects_managing-alerts","reducing-latency-for-alerting-rules-that-do-not-query-platform-metrics_managing-alerts","accessing-alerting-rules-for-your-project_managing-alerts","listing-alerting-rules-for-all-projects-in-a-single-view_managing-alerts","removing-alerting-rules-for-user-defined-projects_managing-alerts","managing-silences_managing-alerts","silencing-alerts_managing-alerts","editing-silences_managing-alerts","expiring-silences_managing-alerts","sending-notifications-to-external-systems_managing-alerts","configuring-alert-receivers_managing-alerts","applying-custom-alertmanager-configuration_managing-alerts","/documentation/openshift_container_platform/4.8/html/monitoring/managing-alerts",{"title":8795,"visible":17,"weight":460,"urlFragment":8796,"anchor":23,"singlePageAnchor":8796,"subChapters":8797,"url":8800,"docTitle":8710},"Reviewing monitoring dashboards","reviewing-monitoring-dashboards",[8798,8799,1119],"reviewing-monitoring-dashboards-admin_reviewing-monitoring-dashboards","reviewing-monitoring-dashboards-developer_reviewing-monitoring-dashboards","/documentation/openshift_container_platform/4.8/html/monitoring/reviewing-monitoring-dashboards",{"title":8802,"visible":17,"weight":475,"urlFragment":8803,"anchor":23,"singlePageAnchor":8803,"subChapters":8804,"url":8807,"docTitle":8710},"Accessing third-party UIs","accessing-third-party-uis",[8805,8806],"accessing-third-party-uis-using-the-web-console_accessing-third-party-uis","accessing-third-party-uis-using-the-cli_accessing-third-party-uis","/documentation/openshift_container_platform/4.8/html/monitoring/accessing-third-party-uis",{"title":8809,"visible":17,"weight":876,"urlFragment":8810,"anchor":23,"singlePageAnchor":8810,"subChapters":8811,"url":8814,"docTitle":8710},"Troubleshooting monitoring issues","troubleshooting-monitoring-issues",[8812,8813],"investigating-why-user-defined-metrics-are-unavailable_troubleshooting-monitoring-issues","determining-why-prometheus-is-consuming-disk-space_troubleshooting-monitoring-issues","/documentation/openshift_container_platform/4.8/html/monitoring/troubleshooting-monitoring-issues",{"title":8816,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":8817,"url":8818,"docTitle":8819,"sections":8820},"Scalability and performance",[],"/documentation/openshift_container_platform/4.8/html/scalability_and_performance/index","scalability_and_performance",[8821,8838,8859,8871,8883,8894,8900,8908,8915,8930,8941,8951,8959,8966,8974,8985,8995,9045,9059],{"title":8822,"visible":17,"weight":30,"urlFragment":8823,"anchor":23,"singlePageAnchor":8823,"subChapters":8824,"url":8837,"docTitle":8819},"Recommended host practices","recommended-host-practices",[8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,1553],"recommended-node-host-practices_recommended-host-practices","create-a-kubeletconfig-crd-to-edit-kubelet-parameters_recommended-host-practices","modify-unavailable-workers_recommended-host-practices","master-node-sizing_recommended-host-practices","increasing-aws-flavor-size_recommended-host-practices","recommended-etcd-practices_recommended-host-practices","etcd-defrag_recommended-host-practices","infrastructure-components_recommended-host-practices","infrastructure-moving-monitoring_recommended-host-practices","infrastructure-moving-registry_recommended-host-practices","infrastructure-moving-router_recommended-host-practices","infrastructure-node-sizing_recommended-host-practices","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/recommended-host-practices",{"title":8839,"visible":17,"weight":42,"urlFragment":8840,"anchor":23,"singlePageAnchor":8840,"subChapters":8841,"url":8858,"docTitle":8819},"Recommended host practices for IBM Z & LinuxONE environments","ibm-z-recommended-host-practices",[8842,8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,8855,8856,8857],"ibm-z-managing-cpu-overcommitment_ibm-z-recommended-host-practices","ibm-z-disable-thp_ibm-z-recommended-host-practices","ibm-z-boost-networking-performance-with-rfs_ibm-z-recommended-host-practices","use-the-mco-to-activate-rfs_ibm-z-recommended-host-practices","ibm-z-choose-networking-setup_ibm-z-recommended-host-practices","ibm-z-ensure-high-disk-performance-hyperpav_ibm-z-recommended-host-practices","use-the-mco-to-activate-hyperpav-aliases-in-nodes-using-zvm-full-pack-minidisks_ibm-z-recommended-host-practices","ibm-z-rhel-kvm-host-recommendations_ibm-z-recommended-host-practices","use-multiple-queues-for-your-virtio-network-interfaces_ibm-z-recommended-host-practices","use-io-threads-for-your-virtual-block-devices_ibm-z-recommended-host-practices","avoid-virtual-scsi-devices_ibm-z-recommended-host-practices","configure-guest-caching-for-disk_ibm-z-recommended-host-practices","exclude-the-memory-ballon-device_ibm-z-recommended-host-practices","tune-the-cpu-migration-algorithm-of-the-host-scheduler_ibm-z-recommended-host-practices","disable-the-cpuset-cgroup-controller_ibm-z-recommended-host-practices","tune-the-polling-period-for-idle-virtual-cpus_ibm-z-recommended-host-practices","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/ibm-z-recommended-host-practices",{"title":8860,"visible":17,"weight":53,"urlFragment":8861,"anchor":23,"singlePageAnchor":8861,"subChapters":8862,"url":8870,"docTitle":8819},"Recommended cluster scaling practices","recommended-cluster-scaling-practices",[8863,8864,8865,8866,8867,8868,4897,4898,8869],"recommended-scale-practices_cluster-scaling","machineset-modifying_cluster-scaling","machine-health-checks-about_cluster-scaling","machine-health-checks-limitations_cluster-scaling","machine-health-checks-resource_cluster-scaling","machine-health-checks-short-circuiting_cluster-scaling","machine-health-checks-creating_cluster-scaling","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/recommended-cluster-scaling-practices",{"title":8872,"visible":17,"weight":75,"urlFragment":8873,"anchor":23,"singlePageAnchor":8873,"subChapters":8874,"url":8882,"docTitle":8819},"Using the Node Tuning Operator","using-node-tuning-operator",[8875,8876,8877,8878,8879,8880,8881],"about-node-tuning-operator_node-tuning-operator","accessing-an-example-node-tuning-operator-specification_node-tuning-operator","custom-tuning-default-profiles-set_node-tuning-operator","verifying-tuned-profiles-are-applied_node-tuning-operator","custom-tuning-specification_node-tuning-operator","custom-tuning-example_node-tuning-operator","supported-tuned-daemon-plug-ins_node-tuning-operator","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using-node-tuning-operator",{"title":8884,"visible":17,"weight":442,"urlFragment":8885,"anchor":23,"singlePageAnchor":8885,"subChapters":8886,"url":8893,"docTitle":8819},"Using Cluster Loader","using_cluster_loader_node-tuning-operator",[8887,8888,8889,8890,8891,8892],"installing-cluster-loader_using_cluster_loader","running_cluster_loader_using_cluster_loader","configuring_cluster_loader_using_cluster_loader","example-cluster-loader-configuration-file","configuration-fields","known-issues","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using_cluster_loader_node-tuning-operator",{"title":8895,"visible":17,"weight":460,"urlFragment":8896,"anchor":23,"singlePageAnchor":8896,"subChapters":8897,"url":8899,"docTitle":8819},"Using CPU Manager","using-cpu-manager",[8898],"seting_up_cpu_manager_using-cpu-manager","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using-cpu-manager",{"title":8901,"visible":17,"weight":475,"urlFragment":8902,"anchor":23,"singlePageAnchor":8902,"subChapters":8903,"url":8907,"docTitle":8819},"Using Topology Manager","using-topology-manager",[8904,8905,8906],"topology_manager_policies_using-topology-manager","seting_up_topology_manager_using-topology-manager","pod-interactions-with-topology-manager_using-topology-manager","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/using-topology-manager",{"title":8909,"visible":17,"weight":876,"urlFragment":8910,"anchor":23,"singlePageAnchor":8910,"subChapters":8911,"url":8914,"docTitle":8819},"Scaling the Cluster Monitoring Operator","scaling-cluster-monitoring-operator",[8912,8913],"prometheus-database-storage-requirements_cluster-monitoring-operator","configuring-cluster-monitoring_cluster-monitoring-operator","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/scaling-cluster-monitoring-operator",{"title":8916,"visible":17,"weight":884,"urlFragment":8917,"anchor":23,"singlePageAnchor":8917,"subChapters":8918,"url":8929,"docTitle":8819},"The Node Feature Discovery Operator","node-feature-discovery-operator",[8919,8920,8921,8922,8923,8924,8925,8926,8927,8928],"about-node-feature-discovery-operator_node-feature-discovery-operator","installing-the-node-feature-discovery-operator_node-feature-discovery-operator","install-operator-cli_node-feature-discovery-operator","install-operator-web-console_node-feature-discovery-operator","using-the-node-feature-discovery-operator_node-feature-discovery-operator","create-cd-cli_node-feature-discovery-operator","create-nfd-cr-web-console_node-feature-discovery-operator","configuring-the-node-feature-discovery_node-feature-discovery-operator","configuring-node-feature-discovery-operator-core_node-feature-discovery-operator","configuring-node-feature-discovery-operator-sources_node-feature-discovery-operator","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/node-feature-discovery-operator",{"title":8931,"visible":17,"weight":895,"urlFragment":8932,"anchor":23,"singlePageAnchor":8932,"subChapters":8933,"url":8940,"docTitle":8819},"The Driver Toolkit","driver-toolkit",[8934,8935,8936,8937,8938,8939],"about-driver-toolkit","pulling-the-driver-toolkit","pulling-the-driver-toolkit-from-registry","pulling-the-driver-toolkit-from-payload","using-the-driver-toolkit","create-simple-kmod-image","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/driver-toolkit",{"title":8942,"visible":17,"weight":906,"urlFragment":8943,"anchor":23,"singlePageAnchor":8943,"subChapters":8944,"url":8950,"docTitle":8819},"Planning your environment according to object maximums","planning-your-environment-according-to-object-maximums",[8945,8946,8947,8948,8949],"cluster-maximums-major-releases_object-limits","cluster-maximums-environment_object-limits","ibm-z-platform","how-to-plan-according-to-cluster-maximums_object-limits","how-to-plan-according-to-application-requirements_object-limits","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/planning-your-environment-according-to-object-maximums",{"title":8952,"visible":17,"weight":913,"urlFragment":8953,"anchor":23,"singlePageAnchor":8953,"subChapters":8954,"url":8958,"docTitle":8819},"Optimizing storage","optimizing-storage",[8955,8956,5019,4692,5020,5021,5022,5023,5024,8957],"available-persistent-storage-options_persistent-storage","recommended-configurable-storage-technology_persistent-storage","data-storage-management_persistent-storage","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/optimizing-storage",{"title":8960,"visible":17,"weight":922,"urlFragment":8961,"anchor":23,"singlePageAnchor":8961,"subChapters":8962,"url":8965,"docTitle":8819},"Optimizing routing","routing-optimization",[8963,8964],"baseline-router-performance_routing-optimization","router-performance-optimizations_routing-optimization","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/routing-optimization",{"title":8967,"visible":17,"weight":2806,"urlFragment":8968,"anchor":23,"singlePageAnchor":8968,"subChapters":8969,"url":8973,"docTitle":8819},"Optimizing networking","optimizing-networking",[8970,8971,8972],"optimizing-mtu_optimizing-networking","recommended-install-practices_optimizing-networking","ipsec-impact_optimizing-networking","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/optimizing-networking",{"title":8975,"visible":17,"weight":3071,"urlFragment":8976,"anchor":23,"singlePageAnchor":8976,"subChapters":8977,"url":8984,"docTitle":8819},"Managing bare metal hosts","managing-bare-metal-hosts",[8978,8979,8980,8981,8982,8983],"about-bare-metal-hosts-and-nodes_managing-bare-metal-hosts","maintaining-bare-metal-hosts_managing-bare-metal-hosts","adding-bare-metal-host-to-cluster-using-web-console_managing-bare-metal-hosts","adding-bare-metal-host-to-cluster-using-yaml_managing-bare-metal-hosts","automatically-scaling-machines-to-available-bare-metal-hosts_managing-bare-metal-hosts","removing-bare-metal-hosts-from-provisioner_managing-bare-metal-hosts","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/managing-bare-metal-hosts",{"title":8986,"visible":17,"weight":3339,"urlFragment":8987,"anchor":23,"singlePageAnchor":8987,"subChapters":8988,"url":8994,"docTitle":8819},"What huge pages do and how they are consumed by applications","what-huge-pages-do-and-how-they-are-consumed",[8989,8990,8991,8992,4911,8993],"what-huge-pages-do_huge-pages","how-huge-pages-are-consumed-by-apps_huge-pages","consuming-huge-pages-resource-using-the-downward-api_huge-pages","configuring-huge-pages_huge-pages","disable-thp_huge-pages","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/what-huge-pages-do-and-how-they-are-consumed",{"title":8996,"visible":17,"weight":3395,"urlFragment":8997,"anchor":23,"singlePageAnchor":8997,"subChapters":8998,"url":9044,"docTitle":8819},"Performance Addon Operator for low latency nodes","cnf-performance-addon-operator-for-low-latency-nodes",[8999,9000,9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043],"cnf-understanding-low-latency_cnf-master","about_hyperthreading_for_low_latency_and_real_time_applications_cnf-master","installing-the-performance-addon-operator_cnf-master","install-operator-cli_cnf-master","install-operator-web-console_cnf-master","upgrading-performance-addon-operator_cnf-master","about-upgrading-performance-addon-operator_cnf-master","how-performance-addon-operator-upgrades-affect-your-cluster_cnf-master","upgrading-performance-addon-operator-to-minor-version_cnf-master","upgrading-performance-addon-operator-configured-for-a-specific-namespace_cnf-master","performance-addon-operator-monitoring-upgrade-status_cnf-master","cnf-provisioning-real-time-and-low-latency-workloads_cnf-master","performance-addon-operator-known-limitations-for-real-time_cnf-master","performance-addon-operator-provisioning-worker-with-real-time-capabilities_cnf-master","performance-addon-operator-verifying-real-time-kernel-installation_cnf-master","performance-addon-operator-creating-workload-that-works-in-real-time_cnf-master","performance-addon-operator-creating-pod-with-guaranteed-qos-class_cnf-master","performance-addon-operator-disabling-cpu-load-balancing-for-dpdk_cnf-master","performance-addon-operator-assigning-proper-node-selector_cnf-master","performance-addon-operator-scheduling-workload-onto-worker-with-real-time-capabilities_cnf-master","managing-device-interrupt-processing-for-guaranteed-pod-isolated-cpus_cnf-master","disabling-cpu-cfs-quota_cnf-master","configuring-global-device-interrupts-handling-for-isolated-cpus_cnf-master","disabling_interrupt_processing_for_individual_pods_cnf-master","use-device-interrupt-processing-for-isolated-cpus_cnf-master","pao_supported_api_versions_cnf-master","upgrading_pao_api_from_v1alpha1_to_v1_cnf-master","upgrading_pao_api_from_v1alpha1_to_v1_or_v2_cnf-master","configuring_for_irq_dynamic_load_balancing_cnf-master","configuring_hyperthreading_for_a_cluster_cnf-master","disabling_hyperthreading_for_low_latency_applications_cnf-master","cnf-tuning-nodes-for-low-latency-via-performanceprofile_cnf-master","cnf-configuring-huge-pages_cnf-master","cnf-allocating-multiple-huge-page-sizes_cnf-master","cnf-cpu-infra-container_cnf-master","reducing-nic-queues-using-the-performance-addon-operator_cnf-master","adjusting-nic-queues-with-the-performance-profile_cnf-master","verifying-queue-status_cnf-master","logging-associated-with-adjusting-nic-queues_cnf-master","cnf-debugging-low-latency-cnf-tuning-status_cnf-master","cnf-debugging-low-latency-cnf-tuning-status-machineconfigpools_cnf-master","cnf-collecting-low-latency-tuning-debugging-data-for-red-hat-support_cnf-master","cnf-about-must-gather_cnf-master","cnf-about-collecting-low-latency-data_cnf-master","cnf-about-gathering-data_cnf-master","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/cnf-performance-addon-operator-for-low-latency-nodes",{"title":9046,"visible":17,"weight":3421,"urlFragment":9047,"anchor":23,"singlePageAnchor":9047,"subChapters":9048,"url":9058,"docTitle":8819},"Performing latency tests for platform verification","cnf-performing-platform-verification-latency-tests",[9049,9050,9051,9052,9053,9054,9055,9056,9057],"cnf-latency-tests-prerequisites_cnf-latency-tests","discovery-mode_cnf-latency-tests","cnf-measuring-latency_cnf-latency-tests","cnf-performing-end-to-end-tests-running-the-tests_cnf-latency-tests","cnf-performing-end-to-end-tests-running-oslat_cnf-latency-tests","cnf-performing-end-to-end-tests-test-failure-report_cnf-latency-tests","cnf-performing-end-to-end-tests-junit-test-output_cnf-latency-tests","cnf-performing-end-to-end-tests-disconnected-mode_cnf-latency-tests","cnf-performing-end-to-end-tests-troubleshooting_cnf-latency-tests","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/cnf-performing-platform-verification-latency-tests",{"title":9060,"visible":17,"weight":3436,"urlFragment":9061,"anchor":23,"singlePageAnchor":9061,"subChapters":9062,"url":9070,"docTitle":8819},"Creating a performance profile","cnf-create-performance-profiles",[9063,9064,9065,9066,9067,9068,9069],"cnf-about-the-profile-creator-tool_cnf-create-performance-profiles","gathering-data-about-your-cluster-using-must-gather_cnf-create-performance-profiles","running-the-performance-profile-profile-cluster-using-podman_cnf-create-performance-profiles","how-to-run-podman-to-create-a-profile_cnf-create-performance-profiles","running-the-performance-profile-creator-wrapper-script_cnf-create-performance-profiles","performance-profile-creator-arguments_cnf-create-performance-profiles","cnf-create-performance-profiles-additional-resources","/documentation/openshift_container_platform/4.8/html/scalability_and_performance/cnf-create-performance-profiles",{"title":9072,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":9073,"url":9074,"docTitle":9075,"sections":9076},"Support",[],"/documentation/openshift_container_platform/4.8/html/support/index","support",[9077,9086,9092,9102,9136,9153,9159],{"title":9078,"visible":17,"weight":30,"urlFragment":9079,"anchor":23,"singlePageAnchor":9079,"subChapters":9080,"url":9085,"docTitle":9075},"Support overview","support-overview",[9081,9082,9083,9084],"support-overview-get-support","support-overview-remote-health-monitoring","support-overview-gather-data-cluster","support-overview-troubleshooting-issues","/documentation/openshift_container_platform/4.8/html/support/support-overview",{"title":9087,"visible":17,"weight":42,"urlFragment":9088,"anchor":23,"singlePageAnchor":9088,"subChapters":9089,"url":9091,"docTitle":9075},"Managing your cluster resources","managing-cluster-resources",[9090],"support-cluster-resources_managing-cluster-resources","/documentation/openshift_container_platform/4.8/html/support/managing-cluster-resources",{"title":9093,"visible":17,"weight":53,"urlFragment":9094,"anchor":23,"singlePageAnchor":9094,"subChapters":9095,"url":9101,"docTitle":9075},"Getting support","getting-support",[9096,9097,9098,9099,9100],"support_getting-support","support-knowledgebase-about_getting-support","support-knowledgebase-search_getting-support","support-submitting-a-case_getting-support","getting-support-additional-resources","/documentation/openshift_container_platform/4.8/html/support/getting-support",{"title":9103,"visible":17,"weight":75,"urlFragment":9104,"anchor":23,"singlePageAnchor":9104,"subChapters":9105,"url":9135,"docTitle":9075},"Remote health monitoring with connected clusters","remote-health-monitoring-with-connected-clusters",[9106,9107,9108,9109,9110,9111,9112,9113,9114,9115,9116,9117,9118,9119,9120,9121,9122,9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133,9134],"about-remote-health-monitoring","telemetry-about-telemetry_about-remote-health-monitoring","what-information-is-collected_about-remote-health-monitoring","insights-operator-about_about-remote-health-monitoring","insights-operator-what-information-is-collected_about-remote-health-monitoring","understanding-telemetry-and-insights-operator-data-flow_about-remote-health-monitoring","additional-details-about-how-remote-health-monitoring-data-is-used","showing-data-collected-by-remote-health-monitoring","showing-data-collected-from-the-cluster_showing-data-collected-by-remote-health-monitoring","insights-operator-showing-data-collected-from-the-cluster_showing-data-collected-by-remote-health-monitoring","opting-out-remote-health-reporting","telemetry-consequences-of-disabling-telemetry_opting-out-remote-health-reporting","insights-operator-new-pull-secret_opting-out-remote-health-reporting","images-update-global-pull-secret_opting-out-remote-health-reporting","using-insights-to-identify-issues-with-your-cluster","insights-operator-advisor-overview_using-insights-to-identify-issues-with-your-cluster","insights-operator-advisor-recommendations_using-insights-to-identify-issues-with-your-cluster","displaying-potential-issues-with-your-cluster_using-insights-to-identify-issues-with-your-cluster","displaying-all-insights-advisor-recommendations_using-insights-to-identify-issues-with-your-cluster","disabling-insights-advisor-recommendations_using-insights-to-identify-issues-with-your-cluster","enabling-insights-advisor-recommendations_using-insights-to-identify-issues-with-your-cluster","displaying-the-insights-status-in-the-web-console_using-insights-to-identify-issues-with-your-cluster","using-insights-operator","insights-operator-downloading-archive_using-insights-operator","insights-operator-gather-duration_using-insights-operator","remote-health-reporting-from-restricted-network","insights-operator-one-time-gather_remote-health-reporting-from-restricted-network","insights-operator-manual-upload_remote-health-reporting-from-restricted-network","insights-operator-enable-obfuscation_remote-health-reporting-from-restricted-network","/documentation/openshift_container_platform/4.8/html/support/remote-health-monitoring-with-connected-clusters",{"title":9137,"visible":17,"weight":442,"urlFragment":9138,"anchor":23,"singlePageAnchor":9138,"subChapters":9139,"url":9152,"docTitle":9075},"Gathering data about your cluster","gathering-cluster-data",[9140,9141,9142,9143,9144,9145,9146,9147,9148,9149,9150,9151],"about-must-gather_gathering-cluster-data","support_gathering_data_gathering-cluster-data","gathering-data-specific-features_gathering-cluster-data","gathering-data-audit-logs_gathering-cluster-data","support-get-cluster-id_gathering-cluster-data","about-sosreport_gathering-cluster-data","support-generating-a-sosreport-archive_gathering-cluster-data","querying-bootstrap-node-journal-logs_gathering-cluster-data","querying-cluster-node-journal-logs_gathering-cluster-data","support-collecting-network-trace_gathering-cluster-data","support-providing-diagnostic-data-to-red-hat_gathering-cluster-data","about-toolbox_gathering-cluster-data","/documentation/openshift_container_platform/4.8/html/support/gathering-cluster-data",{"title":9154,"visible":17,"weight":460,"urlFragment":9155,"anchor":23,"singlePageAnchor":9155,"subChapters":9156,"url":9158,"docTitle":9075},"Summarizing cluster specifications","summarizing-cluster-specifications",[9157],"summarizing-cluster-specifications-through-clusterversion_summarizing-cluster-specifications","/documentation/openshift_container_platform/4.8/html/support/summarizing-cluster-specifications",{"title":5270,"visible":17,"weight":475,"urlFragment":5620,"anchor":23,"singlePageAnchor":5620,"subChapters":9160,"url":9235,"docTitle":9075},[9161,9162,9163,9164,9165,9166,9167,9168,9169,9170,9171,9172,9173,9174,1553,9175,9176,9177,9178,9179,9180,9181,9182,9183,9184,9185,9186,9187,9188,9189,9190,9191,9192,9193,9194,9195,9196,9197,9198,9199,9200,9201,9202,9203,9204,9205,9206,9207,9208,9209,9210,9211,9212,9213,9214,9215,9216,9217,1605,9218,9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,1633,9229,9230,9231,9232,9233,9234],"troubleshooting-installations","determining-where-installation-issues-occur_troubleshooting-installations","upi-installation-considerations_troubleshooting-installations","checking-load-balancer-configuration_troubleshooting-installations","specifying-openshift-installer-log-levels_troubleshooting-installations","troubleshooting-openshift-install-command-issues_troubleshooting-installations","monitoring-installation-progress_troubleshooting-installations","gathering-bootstrap-diagnostic-data_troubleshooting-installations","investigating-master-node-installation-issues_troubleshooting-installations","investigating-etcd-installation-issues_troubleshooting-installations","investigating-kubelet-api-installation-issues_troubleshooting-installations","investigating-worker-node-installation-issues_troubleshooting-installations","querying-operator-status-after-installation_troubleshooting-installations","installation-bootstrap-gather_troubleshooting-installations","verifying-node-health","reviewing-node-status-use-and-configuration_verifying-node-health","querying-kubelet-status-on-a-node_verifying-node-health","querying-cluster-node-journal-logs_verifying-node-health","troubleshooting-crio-issues","about-crio_troubleshooting-crio-issues","verifying-crio-status_troubleshooting-crio-issues","gathering-crio-logs_troubleshooting-crio-issues","cleaning-crio-storage_troubleshooting-crio-issues","troubleshooting-operating-system-issues","investigating-kernel-crashes","enabling-kdump_troubleshooting-operating-system-issues","enabling-kdump-day-one_troubleshooting-operating-system-issues","testing-kdump-configuration","analyzing-core-dumps","debugging-ignition_troubleshooting-operating-system-issues","troubleshooting-network-issues","nw-how-nw-iface-selected_troubleshooting-network-issues","nw-troubleshoot-ovs_troubleshooting-network-issues","configuring-ovs-log-level-temp_troubleshooting-network-issues","configuring-ovs-log-level-permanently_troubleshooting-network-issues","displaying-ovs-logs_troubleshooting-network-issues","troubleshooting-operator-issues","olm-status-conditions_troubleshooting-operator-issues","olm-status-viewing-cli_troubleshooting-operator-issues","olm-cs-status-cli_troubleshooting-operator-issues","querying-operator-pod-status_troubleshooting-operator-issues","gathering-operator-logs_troubleshooting-operator-issues","troubleshooting-disabling-autoreboot-mco_troubleshooting-operator-issues","troubleshooting-disabling-autoreboot-mco-console_troubleshooting-operator-issues","troubleshooting-disabling-autoreboot-mco-cli_troubleshooting-operator-issues","olm-refresh-subs_troubleshooting-operator-issues","investigating-pod-issues","understanding-pod-error-states_investigating-pod-issues","reviewing-pod-status_investigating-pod-issues","inspecting-pod-and-container-logs_investigating-pod-issues","accessing-running-pods_investigating-pod-issues","starting-debug-pods-with-root-access_investigating-pod-issues","copying-files-pods-and-containers_investigating-pod-issues","troubleshooting-s2i","strategies-for-s2i-troubleshooting_troubleshooting-s2i","gathering-s2i-diagnostic-data_troubleshooting-s2i","gathering-application-diagnostic-data_troubleshooting-s2i","troubleshooting-storage-issues","storage-multi-attach-error_troubleshooting-storage-issues","troubleshooting-windows-container-workload-issues","wmco-does-not-install_troubleshooting-windows-container-workload-issues","investigating-why-windows-machine-compute-node_troubleshooting-windows-container-workload-issues","accessing-windows-node","accessing-windows-node-using-ssh_troubleshooting-windows-container-workload-issues","accessing-windows-node-using-rdp_troubleshooting-windows-container-workload-issues","collecting-kube-node-logs-windows_troubleshooting-windows-container-workload-issues","collecting-windows-application-event-logs_troubleshooting-windows-container-workload-issues","collecting-docker-logs-windows_troubleshooting-windows-container-workload-issues","investigating-monitoring-issues","investigating-why-user-defined-metrics-are-unavailable_investigating-monitoring-issues","determining-why-prometheus-is-consuming-disk-space_investigating-monitoring-issues","diagnosing-oc-issues","understanding-oc-log-levels_diagnosing-oc-issues","specifying-oc-log-levels_diagnosing-oc-issues","/documentation/openshift_container_platform/4.8/html/support/troubleshooting",{"title":9237,"visible":17,"categoryName":17,"sections":9238},"Integration",[9239,9876,9964,10510,11115],{"title":9240,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":9241,"url":9242,"docTitle":9243,"sections":9244},"Service Mesh",[],"/documentation/openshift_container_platform/4.8/html/service_mesh/index","service_mesh",[9245,9678],{"title":9246,"visible":17,"weight":30,"urlFragment":9247,"anchor":23,"singlePageAnchor":9247,"subChapters":9248,"url":9677,"docTitle":9243},"Service Mesh 2.x","service-mesh-2-x",[9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,978,9346,9347,9348,9349,9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9372,9373,9374,9375,9376,9377,1013,9378,9379,9380,9381,9382,9383,9384,9385,1004,9386,9387,9388,1022,9389,9390,9391,9392,9393,9394,9395,9396,9397,1553,1043,9398,9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,9410,9411,1069,9412,1024,9413,9414,9415,9416,1119,9417,9418,9419,9420,9421,9422,9423,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448,9449,9450,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469,9470,9471,9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603,9604,9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9616,9617,9618,9619,9620,9621,9622,9623,9624,9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660,9661,9662,9663,9664,9665,9666,9667,9668,9669,9670,9671,9672,9673,9674,9675,9676],"ossm-about","ossm-servicemesh-overview_ossm-about","ossm-core-features_ossm-about","service-mesh-release-notes","making-open-source-more-inclusive_ossm-release-notes","ossm-rn-new-features_ossm-release-notes","new-features-red-hat-openshift-service-mesh-version-2-2-3","component-versions-included-in-red-hat-openshift-service-mesh-version-2-2-3","new-features-red-hat-openshift-service-mesh-version-2-2-2","component-versions-included-in-red-hat-openshift-service-mesh-version-2-2-2","copy-route-labels","new-features-red-hat-openshift-service-mesh-version-2-2-1","component-versions-included-in-red-hat-openshift-service-mesh-version-2-2-1","new-features-red-hat-openshift-service-mesh-2-2","component-versions-included-in-red-hat-openshift-service-mesh-version-2-2","literal-wasmplugin-literal-api","rosa-support","literal-istio-node-literal-daemonset-renamed","envoy-sidecar-networking-changes","service-mesh-control-plane-1-1","istio-1-12-support","kubernetes-gateway-api","new-features-red-hat-openshift-service-mesh-2-1-5-1","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1-5-1","new-features-red-hat-openshift-service-mesh-2-1-5","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1-5","new-features-red-hat-openshift-service-mesh-2-1-4","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1-4","new-features-red-hat-openshift-service-mesh-2-1-3","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1-3","new-features-red-hat-openshift-service-mesh-2-1-2-1","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1-2-1","new-features-red-hat-openshift-service-mesh-2-1-2","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1-2","new-features-red-hat-openshift-service-mesh-2-1-1","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1-1","ossm-config-disable-networkpolicy_ossm-release-notes","new-features-and-enhancements-red-hat-openshift-service-mesh-2-1","component-versions-included-in-red-hat-openshift-service-mesh-version-2-1","service-mesh-federation","ovn-kubernetes-container-network-interface-cni-generally-available","service-mesh-webassembly-wasm-extensions","threescale-webassembly-adapter-wasm","istio-1-9-support","improved-service-mesh-operator-performance","kiali-updates","new-features-red-hat-openshift-service-mesh-2-0-11-1","component-versions-included-in-red-hat-openshift-service-mesh-version-2-0-11-1","new-features-red-hat-openshift-service-mesh-2-0-11","component-versions-included-in-red-hat-openshift-service-mesh-version-2-0-11","new-features-red-hat-openshift-service-mesh-2-0-10","component-versions-included-in-red-hat-openshift-service-mesh-version-2-0-10","new-features-red-hat-openshift-service-mesh-2-0-9","component-versions-included-in-red-hat-openshift-service-mesh-version-2-0-9","new-features-red-hat-openshift-service-mesh-2-0-8","new-features-red-hat-openshift-service-mesh-2-0-7-1","change-in-how-red-hat-openshift-service-mesh-handles-uri-fragments","required-update-for-authorization-policies","new-features-red-hat-openshift-service-mesh-2-0-7","red-hat-openshift-service-mesh-on-red-hat-openshift-dedicated-and-microsoft-azure-red-hat-openshift","new-features-red-hat-openshift-service-mesh-2-0-6","new-features-red-hat-openshift-service-mesh-2-0-5","new-features-red-hat-openshift-service-mesh-2-0-4","manual-updates-cve-2021-29492_ossm-release-notes","updating-the-path-normalization-configuration","path-normalization-configuration-examples","configuring-your-smcp-for-path-normalization","configuring-for-case-normalization","new-features-red-hat-openshift-service-mesh-2-0-3","new-features-red-hat-openshift-service-mesh-2-0-2","new-features-red-hat-openshift-service-mesh-2-0-1","new-features-red-hat-openshift-service-mesh-2-0","ossm-rn-tech-preview_ossm-release-notes","istio-compatibility-support-matrix_ossm-release-notes","ossm-deprecated-features_ossm-release-notes","deprecated-features-red-hat-openshift-service-mesh-2-2","removed-features-red-hat-openshift-service-mesh-2-2","removed-features-red-hat-openshift-service-mesh-2-1","deprecated-features-red-hat-openshift-service-mesh-2-0","ossm-rn-known-issues_ossm-release-notes","ossm-rn-known-issues-ossm_ossm-release-notes","ossm-rn-known-issues-kiali_ossm-release-notes","distr-tracing-rn-known-issues_ossm-release-notes","ossm-rn-fixed-issues_ossm-release-notes","ossm-rn-fixed-issues-ossm_ossm-release-notes","distr-tracing-rn-fixed-issues_ossm-release-notes","ossm-architecture","ossm-understanding-service-mesh_ossm-architecture","ossm-architecture_ossm-architecture","understanding-kiali","ossm-kiali-overview_ossm-architecture","ossm-kiali-architecture_ossm-architecture","ossm-kiali-features_ossm-architecture","understanding-distributed-tracing","distr-tracing-product-overview_ossm-architecture","distr-tracing-architecture_ossm-architecture","distr-tracing-features_ossm-architecture","ossm-deployment-models","ossm-deploy-single-mesh_ossm-deployment-models","ossm-deploy-single-tenant_ossm-deployment-models","ossm-deploy-multitenant_ossm-deployment-models","ossm-deploy-multi-mesh_ossm-deployment-models","ossm-vs-community","ossm-vs-istio_ossm-vs-istio","ossm-cli-tool_ossm-vs-istio","ossm-installation-upgrade_ossm-vs-istio","ossm-automatic-injection_ossm-vs-istio","ossm-rbac_ossm-vs-istio","ossm-openssl_ossm-vs-istio","ossm-external-workloads_ossm-vs-istio","ossm-virtual-machine-support_ossm-vs-istio","ossm-component-modifications_ossm-vs-istio","ossm-envoy-filters_ossm-vs-istio","ossm-envoy-services_ossm-vs-istio","ossm-cni_ossm-vs-istio","ossm-global-mtls_ossm-vs-istio","ossm-gateways_ossm-vs-istio","ossm-multicluster-configuration_ossm-vs-istio","ossm-certificate-signing-request_ossm-vs-istio","ossm-routes-gateways_ossm-vs-istio","ossm-catch-all-domains_ossm-vs-istio","ossm-subdomains_ossm-vs-istio","ossm-tls_ossm-vs-istio","ossm-multitenant-install_ossm-vs-istio","ossm-mt-vs-clusterwide_ossm-vs-istio","ossm-cluster-scoped-resources_ossm-vs-istio","ossm-kiali-service-mesh_ossm-vs-istio","ossm-jaeger-service-mesh_ossm-vs-istio","preparing-ossm-installation","ossm-supported-configurations_preparing-ossm-installation","ossm-supported-platforms_preparing-ossm-installation","ossm-unsupported-configurations_preparing-ossm-installation","ossm-supported-configurations-networks_preparing-ossm-installation","ossm-supported-configurations-sm_preparing-ossm-installation","ossm-supported-configurations-kiali_preparing-ossm-installation","ossm-supported-configurations-jaeger_preparing-ossm-installation","ossm-supported-configurations-webassembly_preparing-ossm-installation","installing-ossm","ossm-installation-activities_installing-ossm","ossm-install-ossm-operator_installing-ossm","ossm-create-smcp","ossm-control-plane-deploy-operatorhub_ossm-create-smcp","ossm-control-plane-deploy-cli_ossm-create-smcp","ossm-validate-control-plane-cli_ossm-create-smcp","ossm-validate-control-plane-kiali_ossm-create-smcp","ossm-install-rosa_ossm-create-smcp","ossm-install-rosa-location_ossm-create-smcp","ossm-install-rosa-smcp_ossm-create-smcp","ossm-install-rosa-kiali-config_ossm-create-smcp","ossm-create-mesh","ossm-member-roll-create_ossm-create-mesh","ossm-member-roll-create-console_ossm-create-mesh","ossm-member-roll-create-cli_ossm-create-mesh","ossm-member-roll-modify_ossm-create-mesh","ossm-member-roll-modify-console_ossm-create-mesh","ossm-member-roll-modify-cli_ossm-create-mesh","ossm-tutorial-bookinfo-overview_ossm-create-mesh","ossm-tutorial-bookinfo-install_ossm-create-mesh","ossm-tutorial-bookinfo-adding-destination-rules_ossm-create-mesh","ossm-tutorial-bookinfo-verify-install_ossm-create-mesh","ossm-tutorial-bookinfo-removing_ossm-create-mesh","ossm-delete-bookinfo-project_ossm-create-mesh","ossm-remove-bookinfo-smmr_ossm-create-mesh","deploying-applications-ossm","ossm-automatic-sidecar-injection_deploying-applications-ossm","ossm-validating-sidecar_deploying-applications-ossm","ossm-sidecar-injection-env-var_deploying-applications-ossm","ossm-update-app-sidecar_deploying-applications-ossm","upgrading-ossm","ossm-versioning_ossm-upgrade","how-versioning-affects-service-mesh-upgrades","ossm-versions_ossm-upgrade","ossm-upgrade-considerations_ossm-upgrade","ossm-upgrade-known-issues_ossm-upgrade","ossm-upgrading-operator_ossm-upgrade","upgrading-control-plane","ossm-upgrade-21-22-changes_ossm-upgrade","ossm-upgrade-20-21-changes_ossm-upgrade","ossm-upgrading-smcp_ossm-upgrade","ossm-migrating-to-20_ossm-upgrade","ossm-migrating_ossm-upgrade","ossm-migrating-smcp_ossm-upgrade","ossm-migrating-differences-arch_ossm-upgrade","ossm-migrating-differences-annotation_ossm-upgrade","ossm-migrating-differences-behavior_ossm-upgrade","ossm-migrating-unsupported-resources_ossm-upgrade","ossm-migrating-mixer_ossm-upgrade","ossm-migrating-mtls_ossm-upgrade","other-mtls-examples","ossm-migrating-config-recipes_ossm-upgrade","ossm-migrating-config-mtls_ossm-upgrade","ossm-migrating-config-sign-key_ossm-upgrade","ossm-migrating-config-tracing_ossm-upgrade","ossm-migrating-config-vis_ossm-upgrade","resource-utilization-and-scheduling","ossm-migrrating-apps_ossm-upgrade","upgrading-data-plane","ossm-upgrading-apps-workloads_ossm-upgrade","ossm-profiles-users","ossm-members_ossm-profiles-users","ossm-control-plane-profiles_ossm-profiles-users","ossm-create-configmap_ossm-profiles-users","ossm-config-network-policy_ossm-profiles-users","ossm-security","ossm-security-mtls_ossm-security","ossm-security-enabling-strict-mtls_ossm-security","ossm-security-mtls-sidecars-incoming-services_ossm-security","ossm-security-mtls-sidecars-outgoing_ossm-security","ossm-security-min-max-tls_ossm-security","ossm-validating-sidecar_ossm-security","ossm-vs-istio_ossm-security","configure-intra-project-communication","restrict-access-to-services-outside-a-namespace","creating-allow-all-and-default-deny-all-authorization-policies","allow-or-deny-access-to-the-ingress-gateway","restrict-access-with-json-web-token","ossm-security-cipher_ossm-security","ossm-cert-manage_ossm-security","ossm-cert-manage-add-cert-key_ossm-security","ossm-cert-manage-verify-cert_ossm-security","ossm-cert-cleanup_ossm-security","ossm-routing-traffic","ossm-gateways_traffic-management","ossm-routing-ingress_traffic-management","ossm-routing-determine-ingress_traffic-management","ossm-routing-config-ig-lb_traffic-management","ossm-routing-config-ig-no-lb_traffic-management","ossm-routing-ingress-gateway_traffic-management","ossm-auto-route_traffic-management","ossm-auto-route-subdomains_traffic-management","ossm-auto-route-create-subdomains_traffic-management","ossm-auto-route-annotations_traffic-management","ossm-auto-route-enable_traffic-management","disabling-automatic-route-creation-specific-cases_traffic-management","disabling-automatic-route-creation-all-cases_traffic-management","ossm-routing-service-entries_traffic-management","ossm-routing-virtual-services_traffic-management","ossm-routing-vs_traffic-management","virtualservice-configuration-reference","ossm-routing-destination-rules_traffic-management","ossm-understanding-networkpolicy_traffic-management","ossm-config-disable-networkpolicy_traffic-management","ossm-routing-sidecar_traffic-management","routing-tutorial","ossm-routing-bookinfo_traffic-management","ossm-routing-bookinfo-applying_traffic-management","ossm-routing-bookinfo-test_traffic-management","ossm-routing-bookinfo-route_traffic-management","ossm-observability","ossm-observability-addresses_observability","ossm-accessing-kiali-console_observability","ossm-observability-visual_observability","ossm-observability-topology_observability","ossm-viewing-logs_observability","ossm-viewing-metrics_observability","ossm-overview-distr-tracing_observability","ossm-config-external-jaeger_observability","ossm-config-sampling_observability","ossm-accessing-jaeger-console_observability","ossm-access-grafana_observability","ossm-access-prometheus_observability","ossm-performance-scalability","ossm-recommended-resources_performance-scalability","ossm-load-test-results_performance-scalability","service-mesh-control-plane-performance","data-plane-performance","cpu-and-memory-consumption","additional-latency","ossm-production","ossm-smcp-prod_ossm-architecture","additional-resources_ossm-production","ossm-federation","ossm-federation-overview_federation","ossm-federation-features_federation","ossm-federation-security_federation","ossm-federation-limitations_federation","ossm-federation-prerequisites_federation","ossm-federation-planning_federation","ossm-federation-across-clusters_federation","exposing-the-federation-ingress-on-clusters-running-on-bare-metal","exposing-the-federation-ingress-on-clusters-running-on-ibm-power-and-ibm-z","exposing-the-federation-ingress-on-amazon-web-services-aws","exposing-the-federation-ingress-on-azure","exposing-the-federation-ingress-on-google-cloud-platform-gcp","con-my-concept-module-a_federation","ossm-federation-config-smcp_federation","understanding-federation-gateways","understanding-federation-trust-domain-parameters","ossm-federation-joining_federation","ossm-federation-create-peer_federation","ossm-federation-config-export_federation","ossm-federation-create-export_federation","ossm-federation-config-import_federation","ossm-federation-create-import_federation","ossm-federation-config-failover-overview_federation","ossm-federation-config-importedserviceset-failover_federation","ossm-federation-config-destinationrule-failover_federation","ossm-federation-remove-service_federation","to-remove-a-service-from-a-single-mesh","to-remove-a-service-from-the-entire-federated-mesh","ossm-federation-remove-mesh_federation","ossm-extensions","ossm-extensions-overview_ossm-extensions","ossm-extensions-wasmplugin-format_ossm-extensions","ossm-wasm-ref-wasmplugin_ossm-extensions","ossm-wasmplugin-deploy_ossm-extensions","ossm-extensions-smextension-format_ossm-extensions","ossm-wasm-ref-smextension_ossm-extensions","ossm-smextensions-deploy_ossm-extensions","ossm-extensions-migration-overview_ossm-extensions","ossm-extensions-migration-api-changes_ossm-extensions","ossm-extensions-migration-format-changes_ossm-extensions","ossm-extensions-migrating-to-wasmplugin_ossm-extensions","ossm-threescale-webassembly-module","compatibility_ossm-threescale-webassembly-module","usage-as-a-stand-alone-module_ossm-threescale-webassembly-module","prerequisites_ossm-threescale-webassembly-module","ossm-configuring-the-threescale-wasm-auth-module_ossm-threescale-webassembly-module","the-service-mesh-extension_ossm-threescale-webassembly-module","ossm-threescale-applying-external-service-entry-objects_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-configuration_ossm-threescale-webassembly-module","threescale-configuring-the-threescale-webassembly-module_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-api-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-system-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-upstream-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-backend-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-services-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-credentials-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-lookup-queries_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-source-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-operations-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-mapping-rules-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-mapping-rule-object_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-examples-for-credentials-use-cases_ossm-threescale-webassembly-module","api-key-in-query-string-parameters_ossm-threescale-webassembly-module","application-id-and-key_ossm-threescale-webassembly-module","authorization-header_ossm-threescale-webassembly-module","openid-connect-use-case_ossm-threescale-webassembly-module","picking-up-the-jwt-token-from-a-header_ossm-threescale-webassembly-module","ossm-threescale-webassembly-module-minimal-working-configuration_ossm-threescale-webassembly-module","threescale-adapter","ossm-threescale-integrate_threescale-adapter","ossm-threescale-cr_threescale-adapter","ossm-threescale-templates_threescale-adapter","ossm-threescale-manifests_threescale-adapter","ossm-threescale-routing_threescale-adapter","ossm-threescale-integration-settings_threescale-adapter","ossm-threescale-caching_threescale-adapter","ossm-threescale-authentication_threescale-adapter","ossm-threescale-authentication-patterns_threescale-adapter","ossm-threescale-apikey-authentication_threescale-adapter","ossm-threescale-appidapikey-authentication_threescale-adapter","ossm-threescale-openid-authentication_threescale-adapter","ossm-threescale-hybrid-authentication_threescale-adapter","ossm-threescale-metrics_threescale-adapter","threescale-backend-cache_threescale-adapter","advantages-of-enabling-backend-cache","trade-offs-for-having-lower-latencies","backend-cache-configuration-settings","threescale-istio-adapter-apicast_threescale-adapter","ossm-threescale-istio-adapter-verification_threescale-adapter","ossm-threescale-istio-adapter-troubleshooting-checklist_threescale-adapter","ossm-troubleshooting","ossm-versions_troubleshooting-ossm","troubleshooting-operator-installation","ossm-validating-operators_troubleshooting-ossm","ossm-troubleshooting-operators_troubleshooting-ossm","viewing-operator-pod-logs","troubleshooting-the-control-plane","ossm-validating-smcp_troubleshooting-ossm","ossm-accessing-kiali-console_troubleshooting-ossm","ossm-accessing-jaeger-console_troubleshooting-ossm","ossm-troubleshooting-smcp_troubleshooting-ossm","troubleshooting-the-data-plane","ossm-troubleshooting-injection_troubleshooting-ossm","troubleshooting-istio-sidecar-injection","troubleshooting-jaeger-agent-sidecar-injection","ossm-troubleshooting-proxy_troubleshooting-ossm","enabling-envoy-access-logs","support_troubleshooting-ossm","support-knowledgebase-about_troubleshooting-ossm","support-knowledgebase-search_troubleshooting-ossm","about-must-gather_troubleshooting-ossm","ossm-about-collecting-ossm-data_troubleshooting-ossm","support-submitting-a-case_troubleshooting-ossm","ossm-reference","ossm-cr-example_ossm-reference","spec-parameters","ossm-cr-general_ossm-reference","ossm-cr-profiles_ossm-reference","ossm-cr-techPreview_ossm-reference","ossm-cr-tracing_ossm-reference","ossm-cr-version_ossm-reference","ossm-cr-threescale_ossm-reference","ossm-cr-status_ossm-reference","additional-resources_ossm-reference","kiali-config-ref","ossm-smcp-kiali_kiali-config-ref","ossm-specifying-external-kiali_kiali-config-ref","jaeger-config-ref","ossm-enabling-tracing_jaeger-config-reference","ossm-specifying-jaeger-configuration_jaeger-config-reference","ossm-deploying-jaeger_jaeger-config-reference","ossm-deploying-jaeger-default_jaeger-config-reference","ossm-deploying-jaeger-production-min_jaeger-config-reference","ossm-deploying-jaeger-production_jaeger-config-reference","ossm-deploying-jaeger-streaming_jaeger-config-reference","ossm-specifying-external-jaeger_jaeger-config-reference","distr-tracing-deployment-best-practices_jaeger-config-reference","distr-tracing-config-security-ossm_jaeger-config-reference","distr-tracing-config-security-ossm-web_jaeger-config-reference","distr-tracing-config-security-ossm-cli_jaeger-config-reference","distr-tracing-config-default_jaeger-config-reference","distr-tracing-config-jaeger-collector_jaeger-config-reference","distr-tracing-config-sampling_jaeger-config-reference","distr-tracing-config-storage_jaeger-config-reference","distributed-tracing-config-auto-provisioning-es_jaeger-config-reference","distributed-tracing-config-external-es_jaeger-config-reference","distr-tracing-manage-es-certificates_jaeger-config-reference","distr-tracing-config-query_jaeger-config-reference","distr-tracing-config-ingester_jaeger-config-reference","removing-ossm","ossm-control-plane-remove_removing-ossm","ossm-control-plane-remove-operatorhub_removing-ossm","ossm-control-plane-remove-cli_removing-ossm","ossm-operatorhub-remove-operators_removing-ossm","ossm-remove-operator-servicemesh_removing-ossm","ossm-remove-cleanup_removing-ossm","/documentation/openshift_container_platform/4.8/html/service_mesh/service-mesh-2-x",{"title":9679,"visible":17,"weight":42,"urlFragment":9680,"anchor":23,"singlePageAnchor":9680,"subChapters":9681,"url":9875,"docTitle":9243},"Service Mesh 1.x","service-mesh-1-x",[9682,9683,9684,9685,9686,1045,9687,9688,9689,9690,9691,9692,9693,9694,9695,9696,9697,9698,9699,9700,9701,9702,9703,9704,9705,9706,9707,9708,9709,9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9736,9737,9738,9739,9740,9741,9742,9743,9744,9745,9746,1147,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,9759,9760,9761,9762,9763,9764,9765,1096,9766,9767,9768,9769,1179,9770,1121,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,9785,1299,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,9815,1605,9816,1149,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,1181,9836,9837,9838,9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874],"service-mesh-release-notes-v1x","making-open-source-more-inclusive","ossm-servicemesh-overview_ossm-release-notes-v1x","support_ossm-release-notes-v1x","about-must-gather_ossm-release-notes-v1x","ossm-about-collecting-ossm-data_ossm-release-notes-v1x","ossm-supported-configurations-v1x_ossm-release-notes-v1x","ossm-supported-configurations-kiali_ossm-release-notes-v1x","ossm-supported-configurations-adapters_ossm-release-notes-v1x","ossm-rn-new-features-1x_ossm-release-notes-v1x","new-features-red-hat-openshift-service-mesh-1-1-18-2","component-versions-included-in-red-hat-openshift-service-mesh-version-1-1-18-2","new-features-red-hat-openshift-service-mesh-1-1-18-1","component-versions-included-in-red-hat-openshift-service-mesh-version-1-1-18-1","new-features-red-hat-openshift-service-mesh-1-1-18","component-versions-included-in-red-hat-openshift-service-mesh-version-1-1-18","new-features-red-hat-openshift-service-mesh-1-1-17-1","change-in-how-red-hat-openshift-service-mesh-handles-uri-fragments-2","required-update-for-authorization-policies-2","new-features-red-hat-openshift-service-mesh-1-1-17","new-features-red-hat-openshift-service-mesh-1-1-16","new-features-red-hat-openshift-service-mesh-1-1-15","new-features-red-hat-openshift-service-mesh-1-1-14","manual-updates-cve-2021-29492_ossm-release-notes-v1x","updating-the-path-normalization-configuration-2","path-normalization-configuration-examples-2","configuring-your-smcp-for-path-normalization-2","new-features-red-hat-openshift-service-mesh-1-1-13","new-features-red-hat-openshift-service-mesh-1-1-12","new-features-red-hat-openshift-service-mesh-1-1-11","new-features-red-hat-openshift-service-mesh-1-1-10","new-features-red-hat-openshift-service-mesh-1-1-9","new-features-red-hat-openshift-service-mesh-1-1-8","new-features-red-hat-openshift-service-mesh-1-1-7","new-features-red-hat-openshift-service-mesh-1-1-6","new-features-red-hat-openshift-service-mesh-1-1-5","new-features-red-hat-openshift-service-mesh-1-1-4","manual-updates-cve-2020-8663_ossm-release-notes-v1x","upgrading_es5_es6_ossm-release-notes-v1x","new-features-red-hat-openshift-service-mesh-1-1-3","new-features-red-hat-openshift-service-mesh-1-1-2","new-features-red-hat-openshift-service-mesh-1-1-1","new-features-red-hat-openshift-service-mesh-1-1-0","ossm-manual-updates-1.0-1.1_ossm-release-notes-v1x","ossm-deprecated-features-1x_ossm-release-notes-v1x","deprecated-features-red-hat-openshift-service-mesh-1-1-5","ossm-rn-known-issues-1x_ossm-release-notes-v1x","ossm-rn-known-issues-ossm_ossm-release-notes-v1x","ossm-rn-known-issues-kiali_ossm-release-notes-v1x","distr-tracing-rn-known-issues_ossm-release-notes-v1x","ossm-rn-fixed-issues-1x_ossm-release-notes-v1x","ossm-rn-fixed-issues-ossm_ossm-release-notes-v1x","ossm-rn-fixed-issues-kiali_ossm-release-notes-v1x","distr-tracing-rn-fixed-issues_ossm-release-notes-v1x","ossm-architecture-v1x","ossm-understanding-service-mesh_ossm-architecture-v1x","ossm-architecture-1x_ossm-architecture-v1x","understanding-kiali-2","ossm-kiali-overview_ossm-architecture-v1x","ossm-kiali-architecture_ossm-architecture-v1x","ossm-kiali-features_ossm-architecture-v1x","understanding-jaeger","distr-tracing-product-overview_ossm-architecture-v1x","jaeger-architecture_ossm-architecture-v1x","distr-tracing-features_ossm-architecture-v1x","ossm-vs-community-v1x","ossm-multitenant-install_ossm-vs-istio-v1x","ossm-mt-vs-clusterwide_ossm-vs-istio-v1x","ossm-cluster-scoped-resources_ossm-vs-istio-v1x","ossm-vs-istio_ossm-vs-istio-v1x","ossm-cli-tool_ossm-vs-istio-v1x","ossm-automatic-injection_ossm-vs-istio-v1x","ossm-rbac_ossm-vs-istio-v1x","ossm-openssl_ossm-vs-istio-v1x","ossm-component-modifications_ossm-vs-istio-v1x","ossm-envoy-sds-ca_ossm-vs-istio-v1x","ossm-cni_ossm-vs-istio-v1x","ossm-routes-gateways_ossm-vs-istio-v1x","ossm-catch-all-domains_ossm-vs-istio-v1x","ossm-subdomains_ossm-vs-istio-v1x","ossm-tls_ossm-vs-istio-v1x","ossm-kiali-service-mesh_ossm-vs-istio-v1x","ossm-jaeger-service-mesh_ossm-vs-istio-v1x","preparing-ossm-installation-v1x","ossm-supported-configurations-v1x_preparing-ossm-installation-v1x","ossm-supported-configurations-kiali_preparing-ossm-installation-v1x","ossm-supported-configurations-adapters_preparing-ossm-installation-v1x","ossm-installation-activities_preparing-ossm-installation-v1x","installing-ossm-v1x","distr-tracing-operator-install-elasticsearch_installing-ossm-v1x","distr-tracing-jaeger-operator-install_installing-ossm-v1x","ossm-install-kiali_installing-ossm-v1x","ossm-install-ossm-operator_installing-ossm-v1x","ossm-control-plane-deploy-1x_installing-ossm-v1x","ossm-control-plane-deploy-operatorhub_installing-ossm-v1x","ossm-control-plane-deploy-cli_installing-ossm-v1x","ossm-member-roll-create_installing-ossm-v1x","ossm-member-roll-create-console_installing-ossm-v1x","ossm-member-roll-create-cli_installing-ossm-v1x","ossm-member-roll-modify_installing-ossm-v1x","ossm-member-roll-modify-console_installing-ossm-v1x","ossm-member-roll-modify-cli_installing-ossm-v1x","manual-updates","ossm-update-app-sidecar_installing-ossm-v1x","ossm-security-v1x","ossm-security-mtls_ossm-security-v1x","ossm-security-enabling-strict-mtls_ossm-security-v1x","ossm-security-mtls-sidecars-incoming-services_ossm-security-v1x","ossm-security-mtls-sidecars-outgoing_ossm-security-v1x","ossm-security-min-max-tls_ossm-security-v1x","ossm-security-cipher-1x_ossm-security-v1x","ossm-cert-manage-1x_ossm-security-v1x","ossm-cert-manage-add-cert-key-1x_ossm-security-v1x","ossm-cert-manage-verify-cert-1x_ossm-security-v1x","ossm-cert-cleanup-1x_ossm-security-v1x","ossm-routing-traffic-v1x","ossm-gateways_routing-traffic-v1x","ossm-routing-ingress-gateway_routing-traffic-v1x","ossm-routing-ingress_routing-traffic-v1x","ossm-routing-determine-ingress_routing-traffic-v1x","ossm-routing-config-ig-lb_routing-traffic-v1x","ossm-routing-config-ig-no-lb_routing-traffic-v1x","ossm-auto-route-1x_routing-traffic-v1x","ossm-auto-route-enable_routing-traffic-v1x","ossm-auto-route-subdomains_routing-traffic-v1x","ossm-routing-service-entries_routing-traffic-v1x","ossm-routing-virtual-services_routing-traffic-v1x","ossm-routing-vs_routing-traffic-v1x","virtualservice-configuration-reference-2","ossm-routing-destination-rules_routing-traffic-v1x","ossm-routing-bookinfo_routing-traffic-v1x","ossm-routing-bookinfo-applying_routing-traffic-v1x","ossm-routing-bookinfo-test_routing-traffic-v1x","ossm-routing-bookinfo-route_routing-traffic-v1x","deploying-applications-ossm-v1x","ossm-control-plane-templates-1x_deploying-applications-ossm-v1x","ossm-create-configmap_deploying-applications-ossm-v1x","ossm-automatic-sidecar-injection_deploying-applications-ossm-v1x","ossm-sidecar-injection-env-var_deploying-applications-ossm-v1x","ossm-mixer-policy-1x_deploying-applications-ossm-v1x","ossm-config-network-policy_deploying-applications-ossm-v1x","ossm-tutorial-bookinfo-overview_deploying-applications-ossm-v1x","ossm-tutorial-bookinfo-install_deploying-applications-ossm-v1x","ossm-tutorial-bookinfo-adding-destination-rules_deploying-applications-ossm-v1x","ossm-tutorial-bookinfo-verify-install_deploying-applications-ossm-v1x","ossm-tutorial-bookinfo-removing_deploying-applications-ossm-v1x","ossm-delete-bookinfo-project_deploying-applications-ossm-v1x","ossm-remove-bookinfo-smmr_deploying-applications-ossm-v1x","generating-sample-traces-analyzing-trace-data_deploying-applications-ossm-v1x","ossm-observability-v1x","ossm-observability-access-console_observability-v1x","ossm-observability-visual_observability-v1x","ossm-observability-topology_observability-v1x","ossm-custom-resources-v1x","ossm-cr-example-1x_ossm-controler-items-v1x","ossm-cr-parameters_ossm-controler-items-v1x","ossm-cr-istio-global_ossm-controler-items-v1x","ossm-cr-gateway_ossm-controler-items-v1x","ossm-cr-mixer_ossm-controler-items-v1x","ossm-cr-pilot_ossm-controler-items-v1x","configuring-kiali_ossm-controler-items-v1x","configuring-kiali-grafana_ossm-controler-items-v1x","configuring-kiali-jaeger_ossm-controler-items-v1x","ossm-configuring-jaeger_ossm-controler-items-v1x","ossm-configuring-jaeger-elasticsearch_ossm-controler-items-v1x","ossm-configuring-jaeger-existing-v1x_ossm-controler-items-v1x","ossm-jaeger-config-elasticsearch-v1x_ossm-controler-items-v1x","ossm-jaeger-config-es-cleaner-v1x_ossm-controler-items-v1x","ossm-cr-threescale_ossm-controler-items-v1x","threescale-adapter-v1x","ossm-threescale-integrate-1x_threescale-adapter-v1x","ossm-threescale-cr_threescale-adapter-v1x","ossm-threescale-templates_threescale-adapter-v1x","ossm-threescale-manifests_threescale-adapter-v1x","ossm-threescale-routing_threescale-adapter-v1x","ossm-threescale-integration-settings_threescale-adapter-v1x","ossm-threescale-caching_threescale-adapter-v1x","ossm-threescale-authentication_threescale-adapter-v1x","ossm-threescale-authentication-patterns_threescale-adapter-v1x","ossm-threescale-apikey-authentication_threescale-adapter-v1x","ossm-threescale-appidapikey-authentication_threescale-adapter-v1x","ossm-threescale-openid-authentication_threescale-adapter-v1x","ossm-threescale-hybrid-authentication_threescale-adapter-v1x","ossm-threescale-metrics-1x_threescale-adapter-v1x","ossm-threescale-istio-adapter-verification_threescale-adapter-v1x","ossm-threescale-istio-adapter-troubleshooting-checklist_threescale-adapter-v1x","removing-ossm-v1x","ossm-control-plane-remove_removing-ossm-v1x","ossm-control-plane-remove-operatorhub_removing-ossm-v1x","ossm-control-plane-remove-cli_removing-ossm-v1x","ossm-operatorhub-remove-operators_removing-ossm-v1x","ossm-remove-operator-servicemesh_removing-ossm-v1x","ossm-remove-cleanup-1x_removing-ossm-v1x","/documentation/openshift_container_platform/4.8/html/service_mesh/service-mesh-1-x",{"title":9877,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":9878,"url":9879,"docTitle":9880,"sections":9881},"Distributed tracing",[],"/documentation/openshift_container_platform/4.8/html/distributed_tracing/index","distributed_tracing",[9882,9912,9921],{"title":9883,"visible":17,"weight":30,"urlFragment":9884,"anchor":23,"singlePageAnchor":9884,"subChapters":9885,"url":9911,"docTitle":9880},"Distributed tracing release notes","distr-tracing-release-notes",[9886,9887,9888,9889,9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910],"distr-tracing-product-overview_distributed-tracing-release-notes","making-open-source-more-inclusive_distributed-tracing-release-notes","support_distributed-tracing-release-notes","distr-tracing-rn-new-features_distributed-tracing-release-notes","new-features-and-enhancements-red-hat-openshift-distributed-tracing-2-5","component-versions-supported-in-red-hat-openshift-distributed-tracing-version-2-5","new-features-and-enhancements-red-hat-openshift-distributed-tracing-2-4","component-versions-supported-in-red-hat-openshift-distributed-tracing-version-2-4","new-features-and-enhancements-red-hat-openshift-distributed-tracing-2-3-1","component-versions-supported-in-red-hat-openshift-distributed-tracing-version-2-3-1","new-features-and-enhancements-red-hat-openshift-distributed-tracing-2-3-0","component-versions-supported-in-red-hat-openshift-distributed-tracing-version-2-3-0","new-features-and-enhancements-red-hat-openshift-distributed-tracing-2-2-0","component-versions-supported-in-red-hat-openshift-distributed-tracing-version-2-2-0","new-features-and-enhancements-red-hat-openshift-distributed-tracing-2-1-0","component-versions-supported-in-red-hat-openshift-distributed-tracing-version-2-1-0","new-features-and-enhancements-red-hat-openshift-distributed-tracing-2-0-0","component-versions-supported-in-red-hat-openshift-distributed-tracing-version-2-0-0","distr-tracing-rn-technology-preview_distributed-tracing-release-notes","red-hat-openshift-distributed-tracing-2-4-0-technology-preview","red-hat-openshift-distributed-tracing-2-2-0-technology-preview","red-hat-openshift-distributed-tracing-2-1-0-technology-preview","red-hat-openshift-distributed-tracing-2-0-0-technology-preview","distr-tracing-rn-known-issues_distributed-tracing-release-notes","distr-tracing-rn-fixed-issues_distributed-tracing-release-notes","/documentation/openshift_container_platform/4.8/html/distributed_tracing/distr-tracing-release-notes",{"title":9913,"visible":17,"weight":42,"urlFragment":9914,"anchor":23,"singlePageAnchor":9914,"subChapters":9915,"url":9920,"docTitle":9880},"Distributed tracing architecture","distributed-tracing-architecture",[9916,9917,9918,9919],"distr-tracing-architecture","distr-tracing-product-overview_distributed-tracing-architecture","distr-tracing-features_distributed-tracing-architecture","distr-tracing-architecture_distributed-tracing-architecture","/documentation/openshift_container_platform/4.8/html/distributed_tracing/distributed-tracing-architecture",{"title":9922,"visible":17,"weight":53,"urlFragment":9923,"anchor":23,"singlePageAnchor":9923,"subChapters":9924,"url":9963,"docTitle":9880},"Distributed tracing installation","distributed-tracing-installation",[9925,1013,9926,9927,9928,9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962],"installing-distributed-tracing","distr-tracing-install-overview_install-distributed-tracing","distr-tracing-operator-install-elasticsearch_install-distributed-tracing","distr-tracing-jaeger-operator-install_install-distributed-tracing","distr-tracing-install-otel-operator_install-distributed-tracing","distr-tracing-deploying","distr-tracing-deploy-default_deploying-distr-tracing-platform","distr-tracing-deploy-default-cli_deploying-distr-tracing-platform","distr-tracing-deploy-production_deploying-distr-tracing-platform","distr-tracing-deploy-production-cli_deploying-distr-tracing-platform","distr-tracing-deploy-streaming_deploying-distr-tracing-platform","distr-tracing-deploy-streaming-cli_deploying-distr-tracing-platform","validating-your-jaeger-deployment","distr-tracing-accessing-jaeger-console_deploying-distr-tracing-platform","customizing-your-deployment","distr-tracing-deployment-best-practices_deploying-distr-tracing-platform","distr-tracing-config-default_deploying-distr-tracing-platform","distr-tracing-config-jaeger-collector_deploying-distr-tracing-platform","distr-tracing-config-sampling_deploying-distr-tracing-platform","distr-tracing-config-storage_deploying-distr-tracing-platform","distributed-tracing-config-auto-provisioning-es_deploying-distr-tracing-platform","distributed-tracing-config-external-es_deploying-distr-tracing-platform","distr-tracing-manage-es-certificates_deploying-distr-tracing-platform","distr-tracing-config-query_deploying-distr-tracing-platform","distr-tracing-config-ingester_deploying-distr-tracing-platform","injecting-sidecars","dist-tracing-sidecar-automatic_deploying-distr-tracing-platform","distr-tracing-sidecar-manual_deploying-distr-tracing-platform","distr-tracing-deploying-otel","distr-tracing-config-otel-collector_deploying-distr-tracing-data-collection","validating-your-otel-deployment","distr-tracing-accessing-jaeger-console_deploying-distr-tracing-data-collection","upgrading-distributed-tracing","distr-tracing-changing-operator-channel_upgrading-distributed-tracing","removing-distributed-tracing","distr-tracing-removing-instance_removing-distributed-tracing","distr-tracing-removing-instance-cli_removing-distributed-tracing","removing-the-red-hat-openshift-distributed-tracing-operators","/documentation/openshift_container_platform/4.8/html/distributed_tracing/distributed-tracing-installation",{"title":9965,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":9966,"url":9967,"docTitle":9968,"sections":9969},"Serverless",[],"/documentation/openshift_container_platform/4.8/html/serverless/index","serverless",[9970,10023,10047,10075,10130,10258,10336,10355,10364,10375,10393,10498],{"title":83,"visible":17,"weight":30,"urlFragment":9971,"anchor":23,"singlePageAnchor":9971,"subChapters":9972,"url":10022,"docTitle":9968},"serverless-release-notes",[9973,9974,9975,9976,9977,9978,9979,9980,9981,9982,9983,9984,9985,9986,9987,9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001,10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019,10020,10021],"serverless-api-versions_serverless-release-notes","serverless-tech-preview-features_serverless-release-notes","serverless-deprecated-removed-features_serverless-release-notes","serverless-rn-1-28-0_serverless-release-notes","new-features-1-28-0_serverless-release-notes","known-issues-1-28-0_serverless-release-notes","serverless-rn-1-27_serverless-release-notes","new-features-1-27_serverless-release-notes","fixed-issues-1-27_serverless-release-notes","known-issues-1-27_serverless-release-notes","serverless-rn-1-26_serverless-release-notes","new-features-1.26_serverless-release-notes","fixed-issues-1.26_serverless-release-notes","known-issues-1.26_serverless-release-notes","serverless-rn-1-25-0_serverless-release-notes","new-features-1.25.0_serverless-release-notes","fixed-issues-1.25.0_serverless-release-notes","known-issues-1.25.0_serverless-release-notes","serverless-rn-1-24-0_serverless-release-notes","new-features-1.24.0_serverless-release-notes","fixed-issues-1.24.0_serverless-release-notes","known-issues-1-24-0_serverless-release-notes","serverless-rn-1-23-0_serverless-release-notes","new-features-1-23-0_serverless-release-notes","known-issues-1-23-0_serverless-release-notes","serverless-rn-1-22-0_serverless-release-notes","new-features-1-22-0_serverless-release-notes","known-issues-1-22-0_serverless-release-notes","serverless-rn-1-21-0_serverless-release-notes","new-features-1-21-0_serverless-release-notes","fixed-issues-1-21-0_serverless-release-notes","known-issues-1-21-0_serverless-release-notes","serverless-rn-1-20-0_serverless-release-notes","new-features-1-20-0_serverless-release-notes","known-issues-1-20-0_serverless-release-notes","serverless-rn-1-19-0_serverless-release-notes","new-features-1-19-0_serverless-release-notes","fixed-issues-1-19-0_serverless-release-notes","known-issues-1-19-0_serverless-release-notes","serverless-rn-1-18-0_serverless-release-notes","new-features-1-18-0_serverless-release-notes","fixed-issues-1-18-0_serverless-release-notes","known-issues-1-18-0_serverless-release-notes","serverless-rn-1-17-0_serverless-release-notes","new-features-1-17-0_serverless-release-notes","known-issues-1-17-0_serverless-release-notes","serverless-rn-1-16-0_serverless-release-notes","new-features-1-16-0_serverless-release-notes","known-issues-1-16-0_serverless-release-notes","/documentation/openshift_container_platform/4.8/html/serverless/serverless-release-notes",{"title":10024,"visible":17,"weight":42,"urlFragment":10025,"anchor":23,"singlePageAnchor":10025,"subChapters":10026,"url":10046,"docTitle":9968},"Discover","discover",[10027,10028,10029,10030,10031,10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,10044,10045],"about-serverless","about-knative-serving_about-serverless","about-knative-serving-resources_about-serverless","about-knative-eventing_about-serverless","about-serverless-supported-configs","about-serverless-scalability-performance","additional-resources_about-serverless","serverless-functions-about","serverless-functions-about-runtimes","next-steps_serverless-functions-about","knative-event-sources","serverless-brokers","serverless-broker-types_serverless-brokers","serverless-broker-types-default_serverless-brokers","serverless-broker-types-production_serverless-brokers","next-steps_serverless-brokers","serverless-channels","serverless-channels-implementations","next-steps_serverless-channels","/documentation/openshift_container_platform/4.8/html/serverless/discover",{"title":929,"visible":17,"weight":53,"urlFragment":10048,"anchor":23,"singlePageAnchor":10048,"subChapters":10049,"url":10074,"docTitle":9968},"install",[10050,10051,10052,10053,10054,10055,10056,10057,10058,10059,10060,10061,10062,10063,10064,10065,10066,10067,10068,10069,10070,10071,10072,10073],"install-serverless-operator","install-serverless-operator-before-you-begin","serverless-cluster-sizing-req_install-serverless-operator","install-serverless-operator-scaling-with-machinesets","serverless-install-web-console_install-serverless-operator","serverless-install-cli_install-serverless-operator","additional-resources_install-serverless-operator","next-steps_install-serverless-operator","installing-knative-serving","serverless-install-serving-web-console_installing-knative-serving","serverless-install-serving-yaml_installing-knative-serving","next-steps_installing-knative-serving","installing-knative-eventing","serverless-install-eventing-web-console_installing-knative-eventing","serverless-install-eventing-yaml_installing-knative-eventing","next-steps_installing-knative-eventing","removing-openshift-serverless","serverless-uninstalling-knative-serving_removing-openshift-serverless","serverless-uninstalling-knative-eventing_removing-openshift-serverless","removing-openshift-serverless-removing-the-operator","olm-deleting-operators-from-a-cluster-using-web-console_removing-openshift-serverless","olm-deleting-operator-from-a-cluster-using-cli_removing-openshift-serverless","olm-refresh-subs_removing-openshift-serverless","serverless-deleting-crds_removing-openshift-serverless","/documentation/openshift_container_platform/4.8/html/serverless/install",{"title":10076,"visible":17,"weight":75,"urlFragment":10077,"anchor":23,"singlePageAnchor":10077,"subChapters":10078,"url":10129,"docTitle":9968},"Knative CLI","knative-cli",[10079,10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110,10111,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,10128],"installing-kn","installing-cli-web-console_installing-kn","serverless-installing-cli-linux-rpm-package-manager_installing-kn","installing-cli-linux_installing-kn","serverless-installing-cli-macos_installing-kn","installing-cli-windows_installing-kn","advanced-kn-config","kn-plugins","serverless-build-events-kn_kn-plugins","serverless-send-events-kn_kn-plugins","kn-serving-ref","kn-serving-ref-kn-service","creating-serverless-apps-kn_kn-serving-ref","kn-service-update_kn-serving-ref","kn-service-apply_kn-serving-ref","kn-service-describe_kn-serving-ref","kn-service-offline-about_kn-serving-ref","creating-an-offline-service_kn-serving-ref","kn-serving-ref-kn-container","serverless-kn-container_kn-serving-ref","kn-serving-ref-domain-mapping","serverless-create-domain-mapping-kn_kn-serving-ref","serverless-manage-domain-mapping-kn_kn-serving-ref","kn-eventing-ref","kn-eventing-ref-kn-sources","serverless-list-source-types-kn_kn-eventing-ref","specifying-sink-flag-kn_kn-eventing-ref","serverless-kn-containersource_kn-eventing-ref","apiserversource-kn_kn-eventing-ref","serverless-pingsource-kn_kn-eventing-ref","serverless-kafka-source-kn_kn-eventing-ref","kn-func-ref","serverless-create-func-kn_kn-func-ref","serverless-kn-func-run_kn-func-ref","serverless-build-func-kn_kn-func-ref","serverless-build-func-kn-image-containers_kn-func-ref","serverless-build-func-kn-image-registries_kn-func-ref","serverless-build-func-kn-push_kn-func-ref","serverless-build-func-kn-help_kn-func-ref","serverless-deploy-func-kn_kn-func-ref","functions-list-kn_kn-func-ref","describe-function-kn_kn-func-ref","serverless-kn-func-invoke_kn-func-ref","serverless-kn-func-invoke-reference_kn-func-ref","serverless-kn-func-invoke-main-parameters_kn-func-ref","serverless-kn-func-invoke-example-commands_kn-func-ref","serverless-kn-func-invoke-example-commands-specifying-file-with-data_kn-func-ref","serverless-kn-func-invoke-example-commands-specifying-function-project_kn-func-ref","serverless-kn-func-invoke-example-commands-specifying-where-function-is-deployed_kn-func-ref","serverless-kn-func-delete_kn-func-ref","/documentation/openshift_container_platform/4.8/html/serverless/knative-cli",{"title":6546,"visible":17,"weight":442,"urlFragment":10131,"anchor":23,"singlePageAnchor":10131,"subChapters":10132,"url":10257,"docTitle":9968},"develop",[10133,10134,10135,10136,10137,10138,10139,10140,10141,10142,10143,10144,10145,10146,10147,10148,10149,10150,10151,10152,10153,10154,10155,10156,10157,10158,10159,10160,10161,10162,10163,10164,10165,10166,10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182,10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,10193,10194,10195,10196,10197,10198,10199,10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,10236,10237,10238,10239,10240,10241,10242,10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256],"serverless-applications","creating-serverless-apps-kn_serverless-applications","creating-an-offline-service_serverless-applications","creating-serverless-apps-yaml_serverless-applications","verifying-serverless-app-deployment_serverless-applications","interacting-serverless-apps-http2-gRPC_serverless-applications","serverless-services-network-policies_serverless-applications","serverless-init-containers-apps_serverless-applications","serverless-https-redirect-service_serverless-applications","additional-resources_serverless-applications","serverless-autoscaling-developer","serverless-autoscaling-developer-scale-bounds","serverless-autoscaling-developer-minscale_serverless-autoscaling-developer","serverless-autoscaling-minscale-kn_serverless-autoscaling-developer","serverless-autoscaling-developer-maxscale_serverless-autoscaling-developer","serverless-autoscaling-maxscale-kn_serverless-autoscaling-developer","serverless-about-concurrency_serverless-autoscaling-developer","serverless-concurrency-limits-configure-soft_serverless-autoscaling-developer","serverless-concurrency-limits-configure-hard_serverless-autoscaling-developer","serverless-target-utilization_serverless-autoscaling-developer","serverless-traffic-management","serverless-traffic-management-spec-examples","serverless-traffic-splitting-flags-kn_serverless-traffic-management","serverless-traffic-splitting-flags-kn-precedence_serverless-traffic-management","serverless-custom-revision-urls_serverless-traffic-management","serverless-custom-revision-urls-assign_serverless-traffic-management","serverless-custom-revision-urls-remove_serverless-traffic-management","serverless-create-traffic-split-kn_serverless-traffic-management","odc-splitting-traffic-between-revisions-using-developer-perspective_serverless-traffic-management","serverless-blue-green-deploy_serverless-traffic-management","serverless-configuring-routes","serverless-customize-labels-annotations-routes_serverless-configuring-routes","serverless-openshift-routes_serverless-configuring-routes","knative-service-cluster-local_serverless-configuring-routes","additional-resources_serverless-configuring-routes","serverless-event-sinks","specifying-sink-flag-kn_serverless-event-sinks","serverless-connect-sink-source-odc_serverless-event-sinks","serverless-connect-trigger-sink_serverless-event-sinks","serverless-event-delivery","serverless-event-delivery-component-behaviors_serverless-event-delivery","serverless-event-delivery-component-behaviors-kafka_serverless-event-delivery","serverless-event-delivery-parameters_serverless-event-delivery","serverless-configuring-event-delivery-examples_serverless-event-delivery","trigger-event-delivery-config_serverless-event-delivery","serverless-listing-event-sources","serverless-list-source-types-kn_serverless-listing-event-sources","serverless-list-source-types-odc_serverless-listing-event-sources","serverless-list-source_serverless-listing-event-sources","serverless-apiserversource","odc-creating-apiserversource_serverless-apiserversource","apiserversource-kn_serverless-apiserversource","specifying-sink-flag-kn_serverless-apiserversource","apiserversource-yaml_context","serverless-pingsource","serverless-pingsource-odc_serverless-pingsource","serverless-pingsource-kn_serverless-pingsource","specifying-sink-flag-kn_serverless-pingsource","serverless-pingsource-yaml_serverless-pingsource","serverless-custom-event-sources","serverless-sinkbinding-intro_context","serverless-sinkbinding-yaml_serverless-custom-event-sources","serverless-sinkbinding-kn_serverless-custom-event-sources","specifying-sink-flag-kn_serverless-custom-event-sources","serverless-sinkbinding-odc_serverless-custom-event-sources","serverless-sinkbinding-reference_serverless-custom-event-sources","serverless-sinkbinding-reference-subject-parameters_serverless-custom-event-sources","serverless-sinkbinding-reference-cloudevent-overrides_serverless-custom-event-sources","serverless-sinkbinding-reference-include-label_serverless-custom-event-sources","serverless-custom-event-sources-containersource","serverless-containersource-guidelines_serverless-custom-event-sources","serverless-kn-containersource_serverless-custom-event-sources","serverless-odc-create-containersource_serverless-custom-event-sources","serverless-containersource-reference_serverless-custom-event-sources","serverless-containersource-reference-cloudevent-overrides_serverless-custom-event-sources","serverless-creating-channels","serverless-create-channel-odc_serverless-creating-channels","serverless-create-channel-kn_serverless-creating-channels","serverless-create-default-channel-yaml_serverless-creating-channels","serverless-create-kafka-channel-yaml_serverless-creating-channels","next-steps_serverless-creating-channels","serverless-subs","serverless-creating-subscriptions-odc_serverless-subs","serverless-creating-subscriptions-yaml_serverless-subs","serverless-creating-subscriptions-kn_serverless-subs","serverless-describe-subs-kn_serverless-subs","serverless-list-subs-kn_serverless-subs","serverless-update-subscriptions-kn_serverless-subs","next-steps_serverless-subs","serverless-using-brokers","serverless-create-broker-kn_serverless-using-brokers","serverless-creating-broker-annotation_serverless-using-brokers","serverless-creating-broker-labeling_serverless-using-brokers","serverless-deleting-broker-injection_serverless-using-brokers","serverless-using-brokers-kafka_serverless-using-brokers","serverless-kafka-broker_serverless-using-brokers","serverless-kafka-broker-with-kafka-topic_serverless-using-brokers","serverless-using-brokers-managing-brokers","serverless-list-broker-kn_serverless-using-brokers","serverless-describe-broker-kn_serverless-using-brokers","next-steps_serverless-using-brokers","additional-resources_serverless-using-brokers","serverless-triggers","serverless-create-trigger-odc_serverless-triggers","serverless-create-kn-trigger_serverless-triggers","kn-trigger-list_serverless-triggers","kn-trigger-describe_serverless-triggers","kn-trigger-filtering_serverless-triggers","kn-trigger-update_serverless-triggers","delete-kn-trigger_serverless-triggers","trigger-event-delivery-config_serverless-triggers","next-steps_serverless-triggers","serverless-kafka-developer","serverless-kafka-delivery-retries_serverless-kafka-developer","serverless-kafka-developer-source","serverless-kafka-source-odc_serverless-kafka-developer","serverless-kafka-source-kn_serverless-kafka-developer","specifying-sink-flag-kn_serverless-kafka-developer","serverless-kafka-source-yaml_serverless-kafka-developer","serverless-kafka-developer-broker","serverless-create-kafka-channel-yaml_serverless-kafka-developer","serverless-kafka-developer-sink","serverless-kafka-sink_serverless-kafka-developer","additional-resources_serverless-kafka-developer","/documentation/openshift_container_platform/4.8/html/serverless/develop",{"title":10259,"visible":17,"weight":460,"urlFragment":10260,"anchor":23,"singlePageAnchor":10260,"subChapters":10261,"url":10335,"docTitle":9968},"Administer","administer",[10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,10284,10285,10286,10287,10288,10289,10290,10291,10292,10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303,10304,10305,10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319,10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,10334],"serverless-configuration","serverless-channel-default_serverless-configuration","serverless-broker-backing-channel-default_serverless-configuration","serverless-global-config-broker-class-default_serverless-configuration","serverless-enable-scale-to-zero_serverless-configuration","serverless-scale-to-zero-grace-period_serverless-configuration","serverless-configuration-CR-system-deployments","knative-serving-CR-system-deployments_serverless-configuration","knative-eventing-CR-system-deployments_serverless-configuration","serverless-config-emptydir_serverless-configuration","serverless-https-redirect-global_serverless-configuration","serverless-url-scheme-external-routes_serverless-configuration","serverless-kourier-gateway-service-type_serverless-configuration","serverless-enabling-pvc-support_serverless-configuration","serverless-admin-init-containers_serverless-configuration","serverless-tag-to-digest-resolution_serverless-configuration","knative-serving-controller-custom-certs-secrets_serverless-configuration","additional-resources_knative-serving-CR-config","serverless-kafka-admin","serverless-install-kafka-odc_serverless-kafka-admin","serverless-kafka-admin-security","serverless-kafka-broker-tls-default-config_serverless-kafka-admin","serverless-kafka-broker-sasl-default-config_serverless-kafka-admin","serverless-kafka-tls-channels_serverless-kafka-admin","serverless-kafka-sasl-channels_serverless-kafka-admin","serverless-kafka-sasl-source_serverless-kafka-admin","serverless-kafka-sink-security-config_serverless-kafka-admin","serverless-kafka-broker-configmap_serverless-kafka-admin","additional-resources_serverless-kafka-admin","serverless-admin-perspective","creating-serverless-apps-admin-console_serverless-admin-perspective","serverless-creating-event-source-admin-web-console_serverless-admin-perspective","serverless-creating-broker-admin-web-console_serverless-admin-perspective","serverless-creating-trigger-admin-web-console_serverless-admin-perspective","serverless-creating-channel-admin-web-console_serverless-admin-perspective","serverless-creating-subscription-admin-web-console_serverless-admin-perspective","additional-resources_serverless-cluster-admin-eventing","serverless-ossm-setup","prerequsites_serverless-ossm-setup","serverlesss-ossm-external-certs_serverless-ossm-setup","serverless-ossm-setup_serverless-ossm-setup","serverless-ossm-enabling-serving-metrics_serverless-ossm-setup","serverless-ossm-setup-with-kourier_serverless-ossm-setup","serverless-ossm-secret-filtering_serverless-ossm-setup","serverless-admin-metrics","prerequisites_serverless-admin-metrics","serverless-controller-metrics_serverless-admin-metrics","serverless-webhook-metrics_serverless-admin-metrics","serverless-admin-metrics-eventing","serverless-broker-ingress-metrics_serverless-admin-metrics","serverless-broker-filter-metrics_serverless-admin-metrics","serverless-inmemory-dispatch-metrics_serverless-admin-metrics","serverless-event-source-metrics_serverless-admin-metrics","serverless-admin-metrics-serving","serverless-activator-metrics_serverless-admin-metrics","serverless-autoscaler-metrics_serverless-admin-metrics","serverless-go-metrics_serverless-admin-metrics","metering-serverless","installing-metering-serverless","datasources-metering-serverless_metering-serverless","knative-service-cpu-usage-ds_metering-serverless","knative-service-memory-usage-ds_metering-serverless","applying-datasources-knative_metering-serverless","queries-metering-serverless_metering-serverless","knative-service-cpu-usage-query_metering-serverless","knative-service-memory-usage-query_metering-serverless","applying-queries-knative_metering-serverless","reports-metering-serverless_metering-serverless","reports-metering-serverless-run_metering-serverless","serverless-ha","serverless-config-replicas-serving_serverless-ha","serverless-config-replicas-eventing_serverless-ha","serverless-config-replicas-kafka_serverless-ha","/documentation/openshift_container_platform/4.8/html/serverless/administer",{"title":8291,"visible":17,"weight":475,"urlFragment":10337,"anchor":23,"singlePageAnchor":10337,"subChapters":10338,"url":10354,"docTitle":9968},"monitor",[10339,10340,10341,10342,10343,10344,10345,10346,10347,10348,10349,10350,10351,10352,10353],"cluster-logging-serverless","cluster-logging-about_cluster-logging-serverless","cluster-logging-deploying-about_cluster-logging-serverless","cluster-logging-deploy-about-config_cluster-logging-serverless","cluster-logging-deploy-about-sample_cluster-logging-serverless","using-cluster-logging-to-find-logs-for-knative-serving-components_cluster-logging-serverless","using-cluster-logging-to-find-logs-for-services-deployed-with-knative-serving_cluster-logging-serverless","serverless-developer-metrics","serverless-monitoring-services-default-metrics_serverless-developer-metrics","serverless-monitoring-services-custom-metrics_serverless-developer-metrics","serverless-monitoring-services-configuration-scraping_serverless-developer-metrics","serverless-monitoring-services-examining-metrics_serverless-developer-metrics","serverless-queue-proxy-metrics_serverless-developer-metrics","serverless-monitoring-services-examining-metrics-dashboard_serverless-developer-metrics","additional-resources_serverless-service-monitoring","/documentation/openshift_container_platform/4.8/html/serverless/monitor",{"title":10356,"visible":17,"weight":876,"urlFragment":10357,"anchor":23,"singlePageAnchor":10357,"subChapters":10358,"url":10363,"docTitle":9968},"Tracing requests","serverless-tracing",[10359,10360,10361,10362],"distr-tracing-product-overview_serverless-tracing","serverless-open-telemetry_serverless-tracing","serverless-jaeger-config_serverless-tracing","additional-resources_serverless-tracing","/documentation/openshift_container_platform/4.8/html/serverless/serverless-tracing",{"title":10365,"visible":17,"weight":884,"urlFragment":10366,"anchor":23,"singlePageAnchor":10366,"subChapters":10367,"url":10374,"docTitle":9968},"OpenShift Serverless support","serverless-support",[10368,10369,10370,10371,10372,10373],"support-knowledgebase-about_serverless-support","support-knowledgebase-search_serverless-support","support-submitting-a-case_serverless-support","serverless-support-gather-info","about-must-gather_serverless-support","serverless-about-collecting-data_serverless-support","/documentation/openshift_container_platform/4.8/html/serverless/serverless-support",{"title":10376,"visible":17,"weight":895,"urlFragment":10377,"anchor":23,"singlePageAnchor":10377,"subChapters":10378,"url":10392,"docTitle":9968},"Security","security",[10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391],"serverless-config-tls","serverless-enabling-tls-internal-traffic_serverless-config-tls","serverless-enabling-tls-local-services_serverless-config-tls","serverless-domain-mapping-custom-tls-cert_serverless-config-tls","serverless-kafka-broker-tls-default-config_serverless-config-tls","serverless-kafka-tls-channels_serverless-config-tls","serverless-ossm-with-kourier-jwt","serverless-ossm-v2x-jwt_serverless-ossm-with-kourier-jwt","serverless-ossm-v1x-jwt_serverless-ossm-with-kourier-jwt","serverless-custom-domains","serverless-create-domain-mapping_serverless-custom-domains","serverless-create-domain-mapping-kn_serverless-custom-domains","serverless-domain-mapping-custom-tls-cert_serverless-custom-domains","/documentation/openshift_container_platform/4.8/html/serverless/security",{"title":10394,"visible":17,"weight":906,"urlFragment":10395,"anchor":23,"singlePageAnchor":10395,"subChapters":10396,"url":10497,"docTitle":9968},"Functions","functions",[10397,10398,10399,10400,10401,10402,10403,10404,10405,10406,10407,10408,10409,10410,10411,10412,10413,10414,10415,10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10427,10428,10429,10430,10431,10432,10433,10434,10435,10436,10437,10438,10439,10440,10441,10442,10443,10444,10445,10446,10447,10448,10449,10450,10451,10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,10464,10465,10466,10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,10478,10479,10480,10481,10482,10483,10484,10485,10486,10487,10488,10489,10490,10491,10492,10493,10494,10495,10496],"serverless-functions-setup","prerequisites_serverless-functions-setup","serverless-functions-podman_serverless-functions-setup","serverless-functions-podman-macos_serverless-functions-setup","next-steps_serverless-functions-setup","serverless-functions-getting-started","prerequisites_serverless-functions-getting-started","serverless-create-func-kn_serverless-functions-getting-started","serverless-kn-func-run_serverless-functions-getting-started","serverless-build-func-kn_serverless-functions-getting-started","serverless-build-func-kn-image-containers_serverless-functions-getting-started","serverless-build-func-kn-image-registries_serverless-functions-getting-started","serverless-build-func-kn-push_serverless-functions-getting-started","serverless-build-func-kn-help_serverless-functions-getting-started","serverless-deploy-func-kn_serverless-functions-getting-started","serverless-kn-func-invoke_serverless-functions-getting-started","serverless-kn-func-delete_serverless-functions-getting-started","additional-resources_serverless-functions-getting-started","next-steps_serverless-functions-getting-started","serverless-functions-on-cluster-builds","serverless-functions-creating-on-cluster-builds_serverless-functions-on-cluster-builds","serverless-functions-specifying-function-revision_serverless-functions-on-cluster-builds","serverless-developing-quarkus-functions","prerequisites_serverless-developing-quarkus-functions","serverless-quarkus-template_serverless-developing-quarkus-functions","serverless-invoking-quarkus-functions_serverless-developing-quarkus-functions","serverless-invoking-quarkus-functions-examples_serverless-developing-quarkus-functions","serverless-quarkus-cloudevent-attributes_serverless-developing-quarkus-functions","serverless-quarkus-function-return-values_serverless-developing-quarkus-functions","serverless-functions-quarkus-return-value-types_serverless-developing-quarkus-functions","serverless-testing-quarkus-functions_serverless-developing-quarkus-functions","next-steps_serverless-developing-quarkus-functions","serverless-developing-nodejs-functions","prerequisites_serverless-developing-nodejs-functions","serverless-nodejs-template_serverless-developing-nodejs-functions","serverless-developing-nodejs-functions-about-invoking","serverless-nodejs-functions-context-objects_serverless-developing-nodejs-functions","serverless-nodejs-functions-context-objects-methods_serverless-developing-nodejs-functions","serverless-nodejs-functions-context-objects-cloudevent-data_serverless-developing-nodejs-functions","serverless-nodejs-function-return-values_serverless-developing-nodejs-functions","serverless-nodejs-function-return-values-headers_serverless-developing-nodejs-functions","serverless-nodejs-function-return-values-status-codes_serverless-developing-nodejs-functions","serverless-testing-nodejs-functions_serverless-developing-nodejs-functions","next-steps_serverless-developing-nodejs-functions","serverless-developing-typescript-functions","prerequisites_serverless-developing-typescript-functions","serverless-typescript-template_serverless-developing-typescript-functions","serverless-developing-typescript-functions-about-invoking","serverless-typescript-functions-context-objects_serverless-developing-typescript-functions","serverless-typescript-functions-context-objects-methods_serverless-developing-typescript-functions","serverless-typescript-functions-context-types_serverless-developing-typescript-functions","serverless-typescript-functions-context-objects-cloudevent-data_serverless-developing-typescript-functions","serverless-typescript-function-return-values_serverless-developing-typescript-functions","serverless-typescript-function-return-values-headers_serverless-developing-typescript-functions","serverless-typescript-function-return-values-status-codes_serverless-developing-typescript-functions","serverless-testing-typescript-functions_serverless-developing-typescript-functions","next-steps_serverless-developing-typescript-functions","serverless-functions-eventing","serverless-connect-func-source-odc_serverless-functions-eventing","serverless-functions-project-configuration","serverless-functions-func-yaml_serverless-functions-yaml","serverless-functions-func-yaml-buildenvs_serverless-functions-yaml","serverless-functions-func-yaml-envs_serverless-functions-yaml","serverless-functions-func-yaml-builder_serverless-functions-yaml","serverless-functions-func-yaml-build_serverless-functions-yaml","serverless-functions-func-yaml-volumes_serverless-functions-yaml","serverless-functions-func-yaml-options_serverless-functions-yaml","serverless-functions-func-yaml-image_serverless-functions-yaml","serverless-functions-func-yaml-imagedigest_serverless-functions-yaml","serverless-functions-func-yaml-labels_serverless-functions-yaml","serverless-functions-func-yaml-name_serverless-functions-yaml","serverless-functions-func-yaml-namespace_serverless-functions-yaml","serverless-functions-func-yaml-runtime_serverless-functions-yaml","serverless-functions-func-yaml-environment-variables_serverless-functions-yaml","additional-resources_serverless-functions-project-configuration","serverless-functions-accessing-secrets-configmaps","serverless-functions-secrets-configmaps-interactively_serverless-functions-secrets","serverless-functions-secrets-configmaps-interactively-specialized_serverless-functions-secrets","serverless-functions-secrets-configmaps-manually_serverless-functions-secrets","serverless-functions-mounting-secret-as-volume_serverless-functions-secrets","serverless-functions-mounting-configmap-as-volume_serverless-functions-secrets","serverless-functions-key-value-in-secret-to-env-variable_serverless-functions-secrets","serverless-functions-key-value-in-configmap-to-env-variable_serverless-functions-secrets","serverless-functions-all-values-in-secret-to-env-variables_serverless-functions-secrets","serverless-functions-all-values-in-configmap-to-env-variables_serverless-functions-secrets","serverless-functions-attributes","serverless-functions-adding-annotations_serverless-functions-annotations","serverless-functions-reference-guide","serverless-nodejs-context-object-reference_serverless-functions-reference-guide","serverless-nodejs-context-object-reference-log_serverless-functions-reference-guide","serverless-nodejs-context-object-reference-query_serverless-functions-reference-guide","serverless-nodejs-context-object-reference-body_serverless-functions-reference-guide","serverless-nodejs-context-object-reference-headers_serverless-functions-reference-guide","serverless-nodejs-context-object-reference-http-requests_serverless-functions-reference-guide","serverless-typescript-context-object-reference_serverless-functions-reference-guide","serverless-typescript-context-object-reference-log_serverless-functions-reference-guide","serverless-typescript-context-object-reference-query_serverless-functions-reference-guide","serverless-typescript-context-object-reference-body_serverless-functions-reference-guide","serverless-typescript-context-object-reference-headers_serverless-functions-reference-guide","serverless-typescript-context-object-reference-http-requests_serverless-functions-reference-guide","/documentation/openshift_container_platform/4.8/html/serverless/functions",{"title":10499,"visible":17,"weight":913,"urlFragment":10500,"anchor":23,"singlePageAnchor":10500,"subChapters":10501,"url":10509,"docTitle":9968},"Integrations","integrations",[10502,10503,10504,10505,10506,10507,10508],"serverless-cost-management-integration","prerequisites_serverless-cost-management-integration","serverless-cost-management-labels_serverless-cost-management-integration","additional-resources_serverless-cost-management-integration","gpu-resources","serverless-gpu-resources-kn_gpu-resources","additional-requirements_gpu-resources","/documentation/openshift_container_platform/4.8/html/serverless/integrations",{"title":10511,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":10512,"url":10513,"docTitle":10514,"sections":10515},"OpenShift Virtualization",[],"/documentation/openshift_container_platform/4.8/html/openshift_virtualization/index","openshift_virtualization",[10516,10523,10531,10549,10601,10612,10621,10628,10954,10984,11006,11032,11058],{"title":10517,"visible":17,"weight":30,"urlFragment":10518,"anchor":23,"singlePageAnchor":10518,"subChapters":10519,"url":10522,"docTitle":10514},"About OpenShift Virtualization","about-virt",[10520,10521],"virt-what-you-can-do-with-virt_about-virt","virt-supported-cluster-version_about-virt","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/about-virt",{"title":10524,"visible":17,"weight":42,"urlFragment":10525,"anchor":23,"singlePageAnchor":10525,"subChapters":10526,"url":10530,"docTitle":10514},"Start here with OpenShift Virtualization","start-here-with-openshift-virtualization",[10527,10528,10529],"virt-learn-more-cluster-administrator","virt-learn-more-virtualization-administrator","virt-learn-more-developer","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/start-here-with-openshift-virtualization",{"title":10532,"visible":17,"weight":53,"urlFragment":10533,"anchor":23,"singlePageAnchor":10533,"subChapters":10534,"url":10548,"docTitle":10514},"OpenShift Virtualization release notes","openshift-virtualization-release-notes",[10535,10536,10537,10538,10539,10540,10541,10542,10543,10544,10545,10546,10547],"about-red-hat-openshift-virtualization","virt-supported-cluster-version_virt-4-8-release-notes","virt-guest-os","virt-4-8-inclusive-language","virt-4-8-new","virt-4-8-quick-starts","virt-4-8-networking-new","virt-4-8-storage-new","virt-4-8-deprecated-removed","virt-4-8-deprecated","virt-4-8-changes","virt-4-8-technology-preview","virt-4-8-known-issues","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/openshift-virtualization-release-notes",{"title":10550,"visible":17,"weight":75,"urlFragment":10551,"anchor":23,"singlePageAnchor":10551,"subChapters":10552,"url":10600,"docTitle":10514},"Installing OpenShift Virtualization","installing-openshift-virtualization",[10553,10554,10555,10556,10557,10558,10559,10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,10585,10586,10587,978,10588,10589,10590,10591,10592,10593,1013,10594,10595,10596,10597,10598,10599],"preparing-cluster-for-virt","virt-hardware-os-requirements_preparing-cluster-for-virt","virt-cluster-resource-requirements_preparing-cluster-for-virt","memory-overhead_preparing-cluster-for-virt","CPU-overhead_preparing-cluster-for-virt","storage-overhead_preparing-cluster-for-virt","example-scenario_preparing-cluster-for-virt","object-maximums_preparing-cluster-for-virt","restricted-networks-environments_preparing-cluster-for-virt","live-migration_preparing-cluster-for-virt","snapshots-and-cloning_preparing-cluster-for-virt","cluster-high-availability-options_preparing-cluster-for-virt","virt-specifying-nodes-for-virtualization-components","virt-about-node-placement-virtualization-components_virt-specifying-nodes-for-virtualization-components","how-to-apply-node-placement-rules-virt-components","node-placement-olm-subscription_virt-specifying-nodes-for-virtualization-components","node-placement-hco_virt-specifying-nodes-for-virtualization-components","node-placement-hpp_virt-specifying-nodes-for-virtualization-components","additional-resources_virt-specifying-nodes-for-virtualization-components","example-manifests_virt-specifying-nodes-for-virtualization-components","olm-subscription-examples_virt-specifying-nodes-for-virtualization-components","virt-example-node-placement-node-selector-olm-subscription_virt-specifying-nodes-for-virtualization-components","virt-example-node-placement-tolerations-olm-subscription_virt-specifying-nodes-for-virtualization-components","hyperconverged-cluster-cr-examples_virt-specifying-nodes-for-virtualization-components","virt-example-node-placement-node-selector-hyperconverged-cr_virt-specifying-nodes-for-virtualization-components","virt-example-node-placement-affinity-hyperconverged-cr_virt-specifying-nodes-for-virtualization-components","virt-example-node-placement-tolerations-hyperconverged-cr_virt-specifying-nodes-for-virtualization-components","hpp-object-examples_virt-specifying-nodes-for-virtualization-components","virt-example-node-placement-node-selector-hpp_virt-specifying-nodes-for-virtualization-components","installing-virt-web","virt-installing-virt-operator_installing-virt-web","installing-virt-web-next-steps","prerequisites_installing-virt-cli","virt-subscribing-cli_installing-virt-cli","virt-deploying-operator-cli_installing-virt-cli","virt-installing-virtctl","virt-installing-virtctl-client-web_virt-installing-virtctl","virt-enabling-virt-repos_virt-installing-virtctl","virt-installing-virtctl-client_virt-installing-virtctl","virt-installing-virtctl-addtl-resources","uninstalling-openshift-virtualization-using-the-web-console","virt-deleting-deployment-custom-resource_uninstalling-virt-web","virt-deleting-catalog-subscription_uninstalling-virt-web","deleting-a-namespace-using-the-web-console_uninstalling-virt-web","uninstalling-openshift-virtualization-using-the-cli","uninstalling-virt-cli-prereqs","virt-deleting-virt-cli_uninstalling-virt-cli","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/installing-openshift-virtualization",{"title":10602,"visible":17,"weight":442,"urlFragment":10603,"anchor":23,"singlePageAnchor":10603,"subChapters":10604,"url":10611,"docTitle":10514},"Updating OpenShift Virtualization","upgrading-openshift-virtualization",[10605,10606,10607,10608,10609,10610],"virt-about-upgrading-virt_upgrading-virt","how-upgrades-work_upgrading-virt","how-upgrades-affect-cluster_upgrading-virt","olm-approving-pending-upgrade_upgrading-virt","virt-monitoring-upgrade-status_upgrading-virt","additional-resources_upgrading-virt","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/upgrading-openshift-virtualization",{"title":10613,"visible":17,"weight":460,"urlFragment":10614,"anchor":23,"singlePageAnchor":10614,"subChapters":10615,"url":10620,"docTitle":10514},"Additional security privileges granted for kubevirt-controller and virt-launcher","virt-additional-security-privileges-controller-and-launcher",[10616,10617,10618,10619,1553],"virt-extended-selinux-policies-for-virt-launcher_virt-additional-security-privileges-controller-and-launcher","virt-additional-scc-for-kubevirt-controller_virt-additional-security-privileges-controller-and-launcher","additional-sccs-granted-to-the-kubevirt-controller-service-account","viewing-the-scc-and-rbac-definitions-for-the-kubevirt-controller","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virt-additional-security-privileges-controller-and-launcher",{"title":10622,"visible":17,"weight":475,"urlFragment":10623,"anchor":23,"singlePageAnchor":10623,"subChapters":10624,"url":10627,"docTitle":10514},"Using the CLI tools","virt-using-the-cli-tools",[1024,10625,10626],"virt-virtctl-commands_virt-using-the-cli-tools","virt-openshift-client-commands_virt-using-the-cli-tools","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virt-using-the-cli-tools",{"title":10629,"visible":17,"weight":876,"urlFragment":10630,"anchor":23,"singlePageAnchor":10630,"subChapters":10631,"url":10953,"docTitle":10514},"Virtual machines","virtual-machines",[10632,10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,10647,10648,10649,10650,10651,10652,10653,10654,10655,10656,10657,10658,10659,10660,10661,10662,10663,10664,10665,10666,10667,10668,10669,10670,10671,10672,10673,10674,10675,10676,10677,10678,10679,10680,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,10692,10693,10694,10695,1045,10696,10697,10698,10699,10700,1605,10701,10702,10703,10704,10705,10706,10707,1096,10708,10709,10710,10711,10712,10713,10714,10715,10716,10717,10718,10719,10720,10721,10722,10723,10724,10725,10726,10727,10728,10729,10730,10731,10732,10733,10734,10735,1121,10736,10737,10738,10739,10740,10741,1149,10742,10743,10744,10745,1181,10746,10747,10748,10749,10750,10751,10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,10762,10763,10764,10765,10766,10767,10768,10769,10770,1230,10771,10772,10773,10774,10775,1306,10776,10777,10778,10779,10780,10781,10782,10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,10798,10799,10800,10801,10802,10803,10804,1316,10805,10806,10807,1336,10808,10809,10810,10811,10812,1359,10813,10814,10815,10816,10817,1382,10818,10819,10820,10821,10822,10823,10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844,10845,1409,10846,10847,10848,1004,10849,1437,10850,1022,10851,1512,10852,10853,10854,10855,10856,10857,10858,10859,10860,10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,10872,10873,10874,10875,10876,10877,10878,10879,10880,10881,10882,10883,10884,10885,1522,10886,10887,10888,10889,1542,10890,10891,10892,10893,10894,10895,1588,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906,10907,10908,10909,10910,10911,1633,10912,10913,10914,10915,10916,10917,10918,10919,10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,10933,10934,10935,10936,10937,10938,1043,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948,10949,10950,10951,10952],"virt-create-vms","virt-creating-vm-quick-start-web_virt-create-vms","virt-creating-vm-wizard-web_virt-create-vms","virt-vm-wizard-fields-web_virt-create-vms","virt-networking-wizard-fields-web_virt-create-vms","virt-storage-wizard-fields-web_virt-create-vms","virt-cloud-init-fields-web_virt-create-vms","virt-creating-vm-yaml-web_virt-create-vms","virt-creating-vm-cli_virt-create-vms","virt-vm-storage-volume-types_virt-create-vms","virt-about-runstrategies-vms_virt-create-vms","additional-resources_virt-create-vms_virt-create-vms","virt-edit-vms","virt-editing-vm-web_virt-edit-vms","virt-editing-vm-yaml-web_virt-edit-vms","virt-editing-vm-cli_virt-edit-vms","virt-vm-add-disk_virt-edit-vms","virt-storage-wizard-fields-web_virt-edit-vms","virt-vm-add-nic_virt-edit-vms","virt-networking-wizard-fields-web_virt-edit-vms","virt-vm-edit-cdrom_virt-edit-vms","virt-edit-boot-order","virt-add-boot-order-web_virt-edit-boot-order","virt-edit-boot-order-web_virt-edit-boot-order","virt-edit-boot-order-yaml-web_virt-edit-boot-order","virt-remove-boot-order-item-web_virt-edit-boot-order","virt-delete-vms","virt-delete-vm-web_virt-delete-vms","virt-deleting-vms_virt-delete-vms","virt-manage-vmis","virt-about-vmis_virt-manage-vmis","virt-listing-vmis-cli_virt-manage-vmis","virt-listing-vmis-web_virt-manage-vmis","virt-editing-vmis-web_virt-manage-vmis","virt-deleting-vmis-cli_virt-manage-vmis","virt-deleting-vmis-web_virt-manage-vmis","virt-controlling-vm-states","virt-starting-vm-web_virt-controlling-vm-states","virt-restarting-vm-web_virt-controlling-vm-states","virt-stopping-vm-web_virt-controlling-vm-states","virt-unpausing-vm-web_virt-controlling-vm-states","virt-accessing-vm-consoles","virt-accessing-vm-consoles-web","virt-vm-serial-console-web_virt-accessing-vm-consoles","virt-connecting-vnc-console_virt-accessing-vm-consoles","virt-vm-rdp-console-web_virt-accessing-vm-consoles","virt-copying-the-ssh-command_virt-accessing-vm-consoles","virt-accessing-vm-consoles-cli","virt-accessing-vmi-ssh_virt-accessing-vm-consoles","virt-accessing-vm-yaml-ssh_virt-accessing-vm-consoles","virt-accessing-serial-console_virt-accessing-vm-consoles","virt-accessing-vnc-console_virt-accessing-vm-consoles","virt-accessing-rdp-console_virt-accessing-vm-consoles","virt-triggering-vm-failover-resolving-failed-node","prerequisites_virt-triggering-vm-failover-resolving-failed-node","nodes-nodes-working-deleting-bare-metal_virt-triggering-vm-failover-resolving-failed-node","verifying-vm-failover_virt-triggering-vm-failover-resolving-failed-node","virt-listing-vmis-cli_virt-triggering-vm-failover-resolving-failed-node","virt-installing-qemu-guest-agent","virt-installing-qemu-guest-agent-on-linux-vm_virt-installing-qemu-guest-agent","installing-qemu-guest-agent-on-a-windows-virtual-machine","virt-installing-virtio-drivers-existing-windows_virt-installing-qemu-guest-agent","virt-installing-virtio-drivers-installing-windows_virt-installing-qemu-guest-agent","virt-viewing-qemu-guest-agent-web","About-the-qemu-guest-agent-web_virt-viewing-qemu-guest-agent-web","virt-viewing-qemu-guest-agent-information-web_virt-viewing-qemu-guest-agent-web","virt-managing-configmaps-secrets-service-accounts","virt-adding-secret-configmap-service-account-to-vm_virt-managing-configmaps-secrets-service-accounts","virt-removing-secret-configmap-service-account-vm_virt-managing-configmaps-secrets-service-accounts","virt-installing-virtio-drivers-on-existing-windows-vm","virt-understanding-virtio-drivers_virt-installing-virtio-drivers-on-existing-windows-vm","virt-supported-virtio-drivers_virt-installing-virtio-drivers-on-existing-windows-vm","virt-adding-virtio-drivers-vm-yaml_virt-installing-virtio-drivers-on-existing-windows-vm","virt-installing-virtio-drivers-existing-windows_virt-installing-virtio-drivers-on-existing-windows-vm","virt-removing-virtio-disk-from-vm_virt-installing-virtio-drivers-on-existing-windows-vm","virt-installing-virtio-drivers-on-new-windows-vm","virt-understanding-virtio-drivers_virt-installing-virtio-drivers-on-new-windows-vm","virt-supported-virtio-drivers_virt-installing-virtio-drivers-on-new-windows-vm","virt-adding-virtio-drivers-vm-yaml_virt-installing-virtio-drivers-on-new-windows-vm","virt-installing-virtio-drivers-installing-windows_virt-installing-virtio-drivers-on-new-windows-vm","virt-removing-virtio-disk-from-vm_virt-installing-virtio-drivers-on-new-windows-vm","advanced-virtual-machine-management","virt-working-with-resource-quotas-for-vms","virt-setting-resource-quota-limits-for-vms_virt-working-with-resource-quotas-for-vms","additional-resources_virt-working-with-resource-quotas-for-vms","virt-specifying-nodes-for-vms","virt-about-node-placement-vms_virt-specifying-nodes-for-vms","node-placement-examples_virt-specifying-nodes-for-vms","virt-example-vm-node-placement-node-selector_virt-specifying-nodes-for-vms","virt-example-vm-node-placement-pod-affinity_virt-specifying-nodes-for-vms","virt-example-vm-node-placement-node-affinity_virt-specifying-nodes-for-vms","virt-example-vm-node-placement-tolerations_virt-specifying-nodes-for-vms","additional-resources_virt-specifying-nodes-for-vms","virt-configuring-certificate-rotation","virt-configuring-certificate-rotation_virt-configuring-certificate-rotation","virt-troubleshooting-cert-rotation-parameters_virt-configuring-certificate-rotation","virt-automating-management-tasks","virt-about-red-hat-ansible-automation_virt-automating-management-tasks","virt-automating-virtual-machine-creation-with-ansible_virt-automating-management-tasks","virt-example-ansible-playbook-creating-vms_virt-automating-management-tasks","virt-efi-mode-for-vms","virt-about-efi-mode-for-vms_virt-efi-mode-for-vms","virt-booting-vms-efi-mode_virt-efi-mode-for-vms","configuring-pxe-booting","virt-pxe-booting-with-mac-address_pxe-booting","virt-pxe-vmi-template_pxe-booting","virt-managing-guest-memory","virt-configuring-guest-memory-overcommitment_virt-managing-guest-memory","virt-disabling-guest-memory-overhead-accounting_virt-managing-guest-memory","virt-using-huge-pages-with-vms","what-huge-pages-do_virt-using-huge-pages-with-vms","virt-configuring-huge-pages-for-vms_virt-using-huge-pages-with-vms","virt-dedicated-resources-vm","virt-about-dedicated-resources_virt-dedicated-resources-vm","virt-enabling-dedicated-resources_virt-dedicated-resources-vm","virt-schedule-vms","understanding-policy-attributes_virt-schedule-vms","virt-setting-policy-attributes_virt-schedule-vms","virt-schedule-supported-cpu-model-vms_virt-schedule-vms","virt-schedule-cpu-host-model-vms_virt-schedule-vms","virt-configuring-pci-passthrough","virt-about_pci-passthrough_virt-configuring-pci-passthrough","virt-adding-kernel-arguments-enable-IOMMU_virt-configuring-pci-passthrough","virt-binding-devices-vfio-driver_virt-configuring-pci-passthrough","virt-exposing-pci-device-in-cluster-cli_virt-configuring-pci-passthrough","virt-removing-pci-device-from-cluster_virt-configuring-pci-passthrough","virt-configuring-vms-for-pci-passthrough","virt-assigning-pci-device-virtual-machine_virt-configuring-pci-passthrough","additional-resources_configuring-pci-passthrough","virt-configuring-a-watchdog","virt-configuring-a-watchdog_prerequisites","virt-defining-a-watchdog","virt-installing-a-watchdog_virt-configuring-a-watchdog","virt-configuring-a-watchdog_additional-resources","importing-virtual-machines","virt-tls-certificates-for-dv-imports","virt-adding-tls-certificates-for-authenticating-dv-imports_virt-tls-certificates-for-dv-imports","virt-example-configmap-tls-certificate_virt-tls-certificates-for-dv-imports","virt-importing-virtual-machine-images-datavolumes","virt-cdi-supported-operations-matrix_virt-importing-virtual-machine-images-datavolumes","virt-about-datavolumes_virt-importing-virtual-machine-images-datavolumes","virt-importing-vm-datavolume_virt-importing-virtual-machine-images-datavolumes","virt-importing-virtual-machine-images-datavolumes_additional-resources","virt-importing-virtual-machine-images-datavolumes-block","virt-about-datavolumes_virt-importing-virtual-machine-images-datavolumes-block","virt-about-block-pvs_virt-importing-virtual-machine-images-datavolumes-block","virt-creating-local-block-pv_virt-importing-virtual-machine-images-datavolumes-block","virt-importing-vm-to-block-pv_virt-importing-virtual-machine-images-datavolumes-block","virt-cdi-supported-operations-matrix_virt-importing-virtual-machine-images-datavolumes-block","virt-importing-virtual-machine-images-datavolumes-block_additional-resources","virt-importing-rhv-vm","virt-features-for-storage-matrix_virt-importing-rhv-vm","virt-importing-vm-prerequisites_virt-importing-rhv-vm","virt-importing-vm-wizard_virt-importing-rhv-vm","virt-importing-vm-cli_virt-importing-rhv-vm","virt-creating-configmap_virt-importing-rhv-vm","virt-troubleshooting-vm-import_virt-importing-rhv-vm","logs_virt-importing-rhv-vm","error-messages_virt-importing-rhv-vm","known-issues_virt-importing-rhv-vm","virt-importing-vmware-vm","virt-features-for-storage-matrix_virt-importing-vmware-vm","preparing-a-vddk-image_virt-importing-vmware-vm","configuring-an-internal-image-registry_virt-importing-vmware-vm","configuring-an-external-image-registry_virt-importing-vmware-vm","virt-creating-vddk-image_virt-importing-vmware-vm","virt-importing-vm-wizard_virt-importing-vmware-vm","virt-updating-imported-vmware-vm-network-name_virt-importing-vmware-vm","virt-troubleshooting-vm-import_virt-importing-vmware-vm","logs_virt-importing-vmware-vm","error-messages_virt-importing-vmware-vm","cloning-virtual-machines","virt-enabling-user-permissions-to-clone-datavolumes","virt-about-datavolumes_virt-enabling-user-permissions-to-clone-datavolumes","virt-creating-rbac-cloning-dvs_virt-enabling-user-permissions-to-clone-datavolumes","virt-cloning-vm-disk-into-new-datavolume","virt-about-datavolumes_virt-cloning-vm-disk-into-new-datavolume","virt-cloning-pvc-of-vm-disk-into-new-datavolume_virt-cloning-vm-disk-into-new-datavolume","virt-template-datavolume-clone_virt-cloning-vm-disk-into-new-datavolume","virt-cdi-supported-operations-matrix_virt-cloning-vm-disk-into-new-datavolume","virt-cloning-vm-using-datavolumetemplate","virt-about-datavolumes_virt-cloning-vm-using-datavolumetemplate","virt-creating-new-vm-from-cloned-pvc-using-datavolumetemplate_virt-cloning-vm-using-datavolumetemplate","virt-template-datavolume-vm_virt-cloning-vm-using-datavolumetemplate","virt-cdi-supported-operations-matrix_virt-cloning-vm-using-datavolumetemplate","virt-cloning-vm-disk-into-new-datavolume-block","virt-about-datavolumes_virt-cloning-vm-disk-into-new-datavolume-block","virt-about-block-pvs_virt-cloning-vm-disk-into-new-datavolume-block","virt-creating-local-block-pv_virt-cloning-vm-disk-into-new-datavolume-block","virt-cloning-pvc-of-vm-disk-into-new-datavolume_virt-cloning-vm-disk-into-new-datavolume-block","virt-cdi-supported-operations-matrix_virt-cloning-vm-disk-into-new-datavolume-block","virtual-machine-networking","virt-using-the-default-pod-network-with-virt","virt-configuring-masquerade-mode-cli_virt-using-the-default-pod-network-with-virt","virt-configuring-masquerade-mode-dual-stack_virt-using-the-default-pod-network-with-virt","virt-creating-service-vm","virt-about-services_virt-creating-service-vm","services-dual-stack-cluster_virt-creating-service-vm","virt-creating-a-service-from-a-virtual-machine_virt-creating-service-vm","additional-resources_creating-service-vm","virt-attaching-vm-multiple-networks","virt-connecting-network-through-nad","virt-creating-linux-bridge-nncp_virt-attaching-vm-multiple-networks","virt-creating-linux-bridge-network-attachment-definition","virt-attaching-vm-multiple-networks_prerequisites","virt-creating-linux-bridge-nad-web_virt-attaching-vm-multiple-networks","virt-creating-linux-bridge-nad-cli_virt-attaching-vm-multiple-networks","virt-configuring-vm-for-linux-bridge-network","virt-vm-creating-nic-web_virt-attaching-vm-multiple-networks","virt-networking-wizard-fields-web_virt-attaching-vm-multiple-networks","virt-attaching-vm-additional-network-cli_virt-attaching-vm-multiple-networks","virt-configuring-ip-for-vms","virt-configuring-ip-for-new-vm-cloud-init_virt-configuring-ip-for-vms","virt-configuring-sriov-device-for-vms","discover-sr-iov-devices_virt-configuring-sriov-device-for-vms","example-sriovnetworknodestate_virt-configuring-sriov-device-for-vms","nw-sriov-configuring-device_virt-configuring-sriov-device-for-vms","virt-defining-an-sriov-network","nw-sriov-network-attachment_virt-defining-an-sriov-network","virt-attaching-vm-to-sriov-network","virt-attaching-vm-to-sriov-network_virt-attaching-vm-to-sriov-network","virt-viewing-ip-of-vm-nic","virt-viewing-vmi-ip-cli_virt-viewing-ip-of-vm-vnic","virt-viewing-vmi-ip-web_virt-viewing-ip-of-vm-vnic","virt-using-mac-address-pool-for-vms","virt-about-kubemacpool_virt-using-mac-address-pool-for-vms","virt-disabling-mac-address-pool-for-namespace-cli_virt-using-mac-address-pool-for-vms","virt-reenabling-mac-address-pool-for-namespace-cli_virt-using-mac-address-pool-for-vms","virtual-machine-disks","virt-features-for-storage","virt-features-for-storage-matrix_virt-features-for-storage","virt-configuring-local-storage-for-vms","virt-about-hostpath-provisioner_virt-configuring-local-storage-for-vms","virt-configuring-selinux-hpp-on-rhcos8_virt-configuring-local-storage-for-vms","virt-using-hostpath-provisioner_virt-configuring-local-storage-for-vms","virt-creating-storage-class_virt-configuring-local-storage-for-vms","virt-creating-data-volumes","virt-creating-data-volumes-using-storage-api_virt-creating-data-volumes","virt-creating-data-volumes-using-pvc-api_virt-creating-data-volumes","virt-customizing-storage-profile_virt-creating-data-volumes","additional-resources_creating-data-volumes-using-profiles","virt-reserving-pvc-space-fs-overhead","virt-how-fs-overhead-affects-space-vm-disks_virt-reserving-pvc-space-fs-overhead","virt-overriding-default-fs-overhead-value_virt-reserving-pvc-space-fs-overhead","virt-configuring-cdi-for-namespace-resourcequota","virt-about-cpu-and-memory-quota-namespace_virt-configuring-cdi-for-namespace-resourcequota","virt-overriding-cpu-and-memory-defaults_virt-configuring-cdi-for-namespace-resourcequota","virt-configuring-cdi-for-namespace-resourcequota_additional-resources","virt-virt-managing-data-volume-annotations","virt-dv-annotations_virt-managing-data-volume-annotations","virt-using-preallocation-for-datavolumes","virt-about-preallocation_virt-using-preallocation-for-datavolumes","virt-enabling-preallocation-for-dv_virt-using-preallocation-for-datavolumes","virt-uploading-local-disk-images-web","virt-cdi-supported-operations-matrix_virt-uploading-local-disk-images-web","virt-uploading-image-web_virt-uploading-local-disk-images-web","virt-uploading-local-disk-images-web_additional-resources","virt-uploading-local-disk-images-virtctl","virt-about-datavolumes_virt-uploading-local-disk-images-virtctl","virt-creating-an-upload-dv_virt-uploading-local-disk-images-virtctl","virt-uploading-local-disk-image-dv_virt-uploading-local-disk-images-virtctl","virt-cdi-supported-operations-matrix_virt-uploading-local-disk-images-virtctl","virt-uploading-local-disk-images-virtctl_additional-resources","virt-uploading-local-disk-images-block","virt-about-datavolumes_virt-uploading-local-disk-images-block","virt-about-block-pvs_virt-uploading-local-disk-images-block","virt-creating-local-block-pv_virt-uploading-local-disk-images-block","virt-creating-an-upload-dv_virt-uploading-local-disk-images-block","virt-uploading-local-disk-image-dv_virt-uploading-local-disk-images-block","virt-cdi-supported-operations-matrix_virt-uploading-local-disk-images-block","virt-uploading-local-disk-images-block_additional-resources","virt-managing-offline-vm-snapshots","virt-about-vm-snapshots_virt-managing-offline-vm-snapshots","virtual-machine-snapshot-controller-and-custom-resource-definitions-crds","virt-creating-offline-vm-snapshot-web_virt-managing-offline-vm-snapshots","virt-creating-offline-vm-snapshot-cli_virt-managing-offline-vm-snapshots","virt-restoring-vm-from-snapshot-web_virt-managing-offline-vm-snapshots","virt-restoring-vm-from-snapshot-cli_virt-managing-offline-vm-snapshots","virt-deleting-vm-snapshot-web_virt-managing-offline-vm-snapshots","virt-deleting-vm-snapshot-cli_virt-managing-offline-vm-snapshots","virt-moving-local-vm-disk-to-different-node","virt-cloning-local-volume-to-another-node_virt-moving-local-vm-disk-to-different-node","virt-expanding-virtual-storage-with-blank-disk-images","virt-about-datavolumes_virt-expanding-virtual-storage-with-blank-disk-images","virt-creating-blank-disk-datavolumes_virt-expanding-virtual-storage-with-blank-disk-images","virt-template-blank-disk-datavolume_virt-expanding-virtual-storage-with-blank-disk-images","virt-expanding-virtual-storage-with-blank-disk-images_additional-resources","virt-cloning-a-datavolume-using-smart-cloning","virt-understanding-smart-cloning_virt-cloning-a-datavolume-using-smart-cloning","virt-cloning-a-datavolume_virt-cloning-a-datavolume-using-smart-cloning","virt-cloning-a-datavolume-using-smart-cloning_additional-resources","virt-creating-and-using-boot-sources","virt-about-vms-and-boot-sources_virt-creating-and-using-boot-sources","virt-importing-rhel-image-boot-source-web_virt-creating-and-using-boot-sources","virt-adding-a-boot-source-web_virt-creating-and-using-boot-sources","virt-creating-a-vm-from-a-template-with-an-attached-boot-source_virt-creating-and-using-boot-sources","virt-creating-a-custom-disk-image-boot-source-web_virt-creating-and-using-boot-sources","additional-resources_creating-and-using-boot-sources","virt-hot-plugging-virtual-disks","virt-hot-plugging-a-virtual-disk-using-the-cli_virt-hot-plugging-virtual-disks","virt-hot-unplugging-a-virtual-disk-using-the-cli_virt-hot-plugging-virtual-disks","virt-using-container-disks-with-vms","virt-about-container-disks_virt-using-container-disks-with-vms","importing-a-container-disk-into-a-pvc-by-using-a-data-volume","attaching-a-container-disk-to-a-virtual-machine-as-a-literal-containerdisk-literal-volume","virt-preparing-container-disk-for-vms_virt-using-container-disks-with-vms","virt-disabling-tls-for-registry_virt-using-container-disks-with-vms","virt-preparing-cdi-scratch-space","virt-about-datavolumes_virt-preparing-cdi-scratch-space","virt-understanding-scratch-space_virt-preparing-cdi-scratch-space","virt-operations-requiring-scratch-space_virt-preparing-cdi-scratch-space","virt-defining-storageclass_virt-preparing-cdi-scratch-space","virt-cdi-supported-operations-matrix_virt-preparing-cdi-scratch-space","virt-preparing-cdi-scratch-space-additional-resources","virt-reusing-persistent-volumes","virt-about-reclaiming-statically-provisioned-persistent-volumes_virt-reusing-statically-provisioned-persistent-volumes","virt-reclaiming-statically-provisioned-persistent-volumes_virt-reusing-statically-provisioned-persistent-volumes","virt-deleting-datavolumes","virt-about-datavolumes_virt-deleting-datavolumes","virt-listing-dvs_virt-deleting-datavolumes","virt-deleting-dvs_virt-deleting-datavolumes","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virtual-machines",{"title":10955,"visible":17,"weight":884,"urlFragment":10956,"anchor":23,"singlePageAnchor":10956,"subChapters":10957,"url":10983,"docTitle":10514},"Virtual machine templates","virtual-machine-templates",[10958,10959,10960,10961,10962,10963,10964,10965,10966,10967,10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,1614,10980,10981,10982],"virt-creating-vm-template","virt-understanding-vm-templates-web_virt-creating-vm-template","virt-about-vms-and-boot-sources_virt-creating-vm-template","virt-adding-a-boot-source-web_virt-creating-vm-template","virt-template-fields-for-boot-source_virt-creating-vm-template","virt-marking-vm-templates-favorites_virt-creating-vm-template","virt-filtering-vm-templates_virt-creating-vm-template","virt-creating-template-wizard-web_virt-creating-vm-template","virt-template-wizard-fields","virt-vm-wizard-fields-web_virt-creating-vm-template","virt-networking-wizard-fields-web_virt-creating-vm-template","virt-storage-wizard-fields-web_virt-creating-vm-template","virt-cloud-init-fields-web_virt-creating-vm-template","additional-resources_creating-vm-template","virt-editing-vm-template","virt-editing-vm-web_virt-editing-vm-template","virt-editing-template-yaml-web_virt-editing-vm-template","virt-vm-add-disk_virt-editing-vm-template","virt-vm-add-nic_virt-editing-vm-template","virt-vm-edit-cdrom_virt-editing-vm-template","virt-dedicated-resources-vm-template","virt-about-dedicated-resources_virt-dedicated-resources-vm-template","virt-enabling-dedicated-resources_virt-dedicated-resources-vm-template","virt-deleting-vm-template","virt-deleting-template-wizard-web_virt-deleting-vm-template","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/virtual-machine-templates",{"title":10985,"visible":17,"weight":895,"urlFragment":10986,"anchor":23,"singlePageAnchor":10986,"subChapters":10987,"url":11005,"docTitle":10514},"Live migration","live-migration",[10988,10989,10990,10991,10992,10993,10994,10995,10996,10997,10998,10999,11000,11001,11002,11003,11004],"virt-live-migration","virt-understanding-live-migration_virt-live-migration","virt-updating-access-mode-for-live-migration_virt-live-migration","virt-live-migration-limits","virt-configuring-live-migration-limits_virt-live-migration-limits","virt-live-migration-limits-ref_virt-live-migration-limits","virt-migrate-vmi","virt-initiating-vm-migration-web_virt-migrate-vmi","virt-initiating-vm-migration-cli_virt-migrate-vmi","virt-monitor-vmi-migration","virt-monitoring-vm-migration-web_virt-monitor-vmi-migration","virt-monitoring-vm-migration-cli_virt-monitor-vmi-migration","virt-cancel-vmi-migration","virt-cancelling-vm-migration-web_virt-cancel-vmi-migration","virt-cancelling-vm-migration-cli_virt-cancel-vmi-migration","virt-configuring-vmi-eviction-strategy","virt-configuring-vm-live-migration-cli_virt-configuring-vmi-eviction-strategy","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/live-migration",{"title":11007,"visible":17,"weight":906,"urlFragment":11008,"anchor":23,"singlePageAnchor":11008,"subChapters":11009,"url":11031,"docTitle":10514},"Node maintenance","node-maintenance",[11010,11011,11012,11013,11014,11015,11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,11028,11029,11030],"virt-about-node-maintenance","virt-understanding-node-maintenance_virt-node-maintenance","virt-maintaining-bare-metal-nodes_virt-node-maintenance","virt-setting-node-maintenance","virt-setting-node-maintenance-web_virt-setting-node-maintenance","virt-setting-node-maintenance-cli_virt-setting-node-maintenance","virt-setting-node-to-maintenance-mode-with-cr_virt-setting-node-maintenance","virt-checking_status_of_node_maintenance_cr_tasks_virt-setting-node-maintenance","virt-resuming-node","virt-resuming-node-maintenance-web_virt-resuming-node","virt-resuming-node-maintenance-cli_virt-resuming-node","virt-resuming-node-from-maintenance-mode-with-cr_virt-resuming-node","virt-automatic-certificates","virt-automatic-certificates-renewal_virt-automatic-certificates","virt-managing-node-labeling-obsolete-cpu-models","virt-about-node-labeling-obsolete-cpu-models_virt-managing-node-labeling-obsolete-cpu-models","virt-about-node-labeling-cpu-features_virt-managing-node-labeling-obsolete-cpu-models","virt-configuring-obsolete-cpu-models_virt-managing-node-labeling-obsolete-cpu-models","virt-using-skip-node","virt-using-skip-node_virt-preventing-node-reconciliation","additional-resources_virt-preventing-node-reconciliation","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/node-maintenance",{"title":11033,"visible":17,"weight":913,"urlFragment":11034,"anchor":23,"singlePageAnchor":11034,"subChapters":11035,"url":11057,"docTitle":10514},"Node networking","node-networking",[11036,11037,11038,11039,11040,11041,11042,11043,4636,11044,11045,11046,11047,11048,11049,11050,11051,11052,11053,11054,11055,11056],"virt-observing-node-network-state","virt-about-nmstate_virt-observing-node-network-state","virt-viewing-network-state-of-node_virt-observing-node-network-state","virt-updating-node-network-config","virt-about-nmstate_virt-updating-node-network-config","virt-creating-interface-on-nodes_virt-updating-node-network-config","virt-confirming-policy-updates-on-nodes_virt-updating-node-network-config","virt-removing-interface-from-nodes_virt-updating-node-network-config","virt-example-bridge-nncp_virt-updating-node-network-config","virt-example-vlan-nncp_virt-updating-node-network-config","virt-example-bond-nncp_virt-updating-node-network-config","virt-example-ethernet-nncp_virt-updating-node-network-config","virt-example-nmstate-multiple-interfaces_virt-updating-node-network-config","virt-example-nmstate-IP-management_virt-updating-node-network-config","virt-example-nmstate-IP-management-static_virt-updating-node-network-config","virt-example-nmstate-IP-management-no-ip_virt-updating-node-network-config","virt-example-nmstate-IP-management-dhcp_virt-updating-node-network-config","virt-example-nmstate-IP-management-dns_virt-updating-node-network-config","virt-example-nmstate-IP-management-static-routing_virt-updating-node-network-config","virt-troubleshooting-node-network","virt-troubleshooting-incorrect-policy-config_virt-troubleshooting-node-network","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/node-networking",{"title":11059,"visible":17,"weight":922,"urlFragment":11060,"anchor":23,"singlePageAnchor":11060,"subChapters":11061,"url":11114,"docTitle":10514},"Logging, events, and monitoring","logging-events-and-monitoring",[11062,11063,11064,11065,11066,11067,11068,11069,11070,11071,11072,11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,11088,11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,11100,11101,11102,11103,11104,11105,11106,11107,11108,11109,11110,11111,11112,11113],"virt-logs","virt-understanding-logs_virt-logs","virt-viewing-virtual-machine-logs-cli_virt-logs","virt-viewing-virtual-machine-logs-web_virt-logs","virt-events","virt-understanding-events_virt-events","virt-viewing-vm-events-web_virt-events","virt-viewing-namespace-events-cli_virt-events","virt-viewing-resource-events-cli_virt-events","virt-diagnosing-datavolumes-using-events-and-conditions","virt-about-conditions-and-events.adoc_virt-diagnosing-datavolumes-using-events-and-conditions","virt-analyzing-datavolume-conditions-and-events_virt-diagnosing-datavolumes-using-events-and-conditions","virt-viewing-information-about-vm-workloads","virt-about-the-vm-dashboard_virt-viewing-information-about-vm-workloads","virt-monitoring-vm-health","virt-about-readiness-liveness-probes_virt-monitoring-vm-health","virt-define-http-readiness-probe_virt-monitoring-vm-health","virt-define-tcp-readiness-probe_virt-monitoring-vm-health","virt-define-http-liveness-probe_virt-monitoring-vm-health","virt-template-vmi-probe-config_virt-monitoring-vm-health","additional-resources_monitoring-vm-health","virt-using-dashboard-to-get-cluster-info","virt-about-the-overview-dashboard_virt-using-dashboard-to-get-cluster-info","virt-openshift-cluster-monitoring","about-openshift-monitoring_virt-openshift-cluster-monitoring","cluster-logging-about-components_virt-openshift-cluster-monitoring","telemetry-about-telemetry_virt-openshift-cluster-monitoring","what-information-is-collected_virt-openshift-cluster-monitoring","cli-troubleshooting-and-debugging-commands","virt-prometheus-queries","prerequisites_virt-prometheus-queries","querying-metrics_virt-prometheus-queries","querying-metrics-for-all-projects-as-an-administrator_virt-prometheus-queries","querying-metrics-for-user-defined-projects-as-a-developer_virt-prometheus-queries","virt-querying-metrics_virt-prometheus-queries","virt-promql-vcpu-metrics_virt-prometheus-queries","virt-promql-network-metrics_virt-prometheus-queries","virt-promql-storage-metrics_virt-prometheus-queries","virt-storage-traffic_virt-prometheus-queries","virt-iops_virt-prometheus-queries","virt-promql-guest-memory-metrics_virt-prometheus-queries","additional-resources_virt-prometheus-queries","virt-collecting-virt-data","virt-collecting-data-about-your-environment_virt-collecting-virt-data","additional-resources_collecting-data-about-your-environment","virt-collecting-data-about-vms_virt-collecting-virt-data","additional-resources_collecting-data-about-vms","virt-using-virt-must-gather_virt-collecting-virt-data","virt-must-gather-options_virt-collecting-virt-data","parameters","usage-and-examples_virt-collecting-virt-data","additional-resources_must-gather-virt","/documentation/openshift_container_platform/4.8/html/openshift_virtualization/logging-events-and-monitoring",{"title":11116,"visible":17,"weight":21,"urlFragment":22,"anchor":23,"singlePageAnchor":23,"subChapters":11117,"url":11118,"docTitle":11119,"sections":11120},"Windows Container Support for OpenShift",[],"/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/index","windows_container_support_for_openshift",[11121,11126,11153,11166,11175,11196,11205,11211,11218,11224],{"title":11122,"visible":17,"weight":30,"urlFragment":11123,"anchor":23,"singlePageAnchor":11123,"subChapters":11124,"url":11125,"docTitle":11119},"Red Hat OpenShift support for Windows Containers overview","windows-container-overview",[],"/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/windows-container-overview",{"title":11127,"visible":17,"weight":42,"urlFragment":11128,"anchor":23,"singlePageAnchor":11128,"subChapters":11129,"url":11152,"docTitle":11119},"Windows Container Support for Red Hat OpenShift release notes","windows-containers-release-notes-3-x",[11130,9094,11131,11132,11133,11134,11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150,11151],"about-windows-containers","wmco-3-1-2","wmco-3-1-2-bug-fixes","wmco-3-1-1","wmco-3-1-1-bug-fixes","wmco-3-1-0","wmco-3-1-0-new-features","wmco-3-1-0-byoh","wmco-3-1-0-bug-fixes","wmco-3-1-0-known-issues","wmco-3-0-0","wmco-prerequisites_windows-containers-release-notes","wmco-prerequisites_platforms_windows-containers-release-notes","wmco-prerequisites_platforms_byoh_windows-containers-release-notes","wmco-prerequisites_versions_windows-containers-release-notes","wmco-prerequisites_networking_windows-containers-release-notes","wmco-3-0-0-improvements","clarified-limits-on-custom-vxlan-port-selection","wmco-3-0-0-bug-fixes","rhsa-2021-3001-windows-container-support-for-openshift-container-platform-security-update","wmco-3-0-0-known-issues","windows-containers-release-notes-limitations_windows-containers-release-notes","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/windows-containers-release-notes-3-x",{"title":11154,"visible":17,"weight":53,"urlFragment":11155,"anchor":23,"singlePageAnchor":11155,"subChapters":11156,"url":11165,"docTitle":11119},"Understanding Windows container workloads","understanding-windows-container-workloads",[11157,11158,11159,11160,11161,11162,11163,11164],"wmco-prerequisites_understanding-windows-container-workloads","wmco-prerequisites_platforms_understanding-windows-container-workloads","wmco-prerequisites_platforms_byoh_understanding-windows-container-workloads","wmco-prerequisites_versions_understanding-windows-container-workloads","wmco-prerequisites_networking_understanding-windows-container-workloads","windows-workload-management_understanding-windows-container-workloads","windows-node-services_understanding-windows-container-workloads","windows-containers-release-notes-limitations_understanding-windows-container-workloads","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/understanding-windows-container-workloads",{"title":11167,"visible":17,"weight":75,"urlFragment":11168,"anchor":23,"singlePageAnchor":11168,"subChapters":11169,"url":11174,"docTitle":11119},"Enabling Windows container workloads","enabling-windows-container-workloads",[11170,11171,11172,11173,1553],"installing-the-wmco","installing-wmco-using-web-console_enabling-windows-container-workloads","installing-wmco-using-cli_enabling-windows-container-workloads","configuring-secret-for-wmco_enabling-windows-container-workloads","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/enabling-windows-container-workloads",{"title":11176,"visible":17,"weight":442,"urlFragment":11177,"anchor":23,"singlePageAnchor":11177,"subChapters":11178,"url":11195,"docTitle":11119},"Creating Windows MachineSet objects","creating-windows-machineset-objects",[11179,11180,11181,11182,1605,11183,11184,11185,11186,1633,11187,11188,11189,11190,11191,11192,11193,11194,2643],"creating-windows-machineset-aws","machine-api-overview_creating-windows-machineset-aws","windows-machineset-aws_creating-windows-machineset-aws","machineset-creating_creating-windows-machineset-aws","creating-windows-machineset-azure","machine-api-overview_creating-windows-machineset-azure","windows-machineset-azure_creating-windows-machineset-azure","machineset-creating_creating-windows-machineset-azure","creating-windows-machineset-vsphere","machine-api-overview_creating-windows-machineset-vsphere","preparing-vsphere-for-windows-containers","creating-the-vsphere-windows-vm-golden-image_creating-windows-machineset-vsphere","additional-resources_creating-windows-machineset-vsphere","enabling-internal-api-server-vsphere_creating-windows-machineset-vsphere","windows-machineset-vsphere_creating-windows-machineset-vsphere","machineset-creating_creating-windows-machineset-vsphere","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/creating-windows-machineset-objects",{"title":11197,"visible":17,"weight":460,"urlFragment":11198,"anchor":23,"singlePageAnchor":11198,"subChapters":11199,"url":11204,"docTitle":11119},"Scheduling Windows container workloads","scheduling-windows-workloads",[11200,11201,11202,11203],"windows-pod-placement_scheduling-windows-workloads","creating-runtimeclass_scheduling-windows-workloads","sample-windows-workload-deployment_scheduling-windows-workloads","machineset-manually-scaling_scheduling-windows-workloads","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/scheduling-windows-workloads",{"title":11206,"visible":17,"weight":475,"urlFragment":11207,"anchor":23,"singlePageAnchor":11207,"subChapters":11208,"url":11210,"docTitle":11119},"Windows node upgrades","windows-node-upgrades",[11209],"wmco-upgrades_windows-node-upgrades","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/windows-node-upgrades",{"title":11212,"visible":17,"weight":876,"urlFragment":11213,"anchor":23,"singlePageAnchor":11213,"subChapters":11214,"url":11217,"docTitle":11119},"Using Bring-Your-Own-Host (BYOH) Windows instances as nodes","byoh-windows-instance",[11215,11216],"configuring-byoh-windows-instance","removing-byoh-windows-instance","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/byoh-windows-instance",{"title":11219,"visible":17,"weight":884,"urlFragment":11220,"anchor":23,"singlePageAnchor":11220,"subChapters":11221,"url":11223,"docTitle":11119},"Removing Windows nodes","removing-windows-nodes",[11222],"machine-delete_removing-windows-nodes","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/removing-windows-nodes",{"title":11225,"visible":17,"weight":895,"urlFragment":11226,"anchor":23,"singlePageAnchor":11226,"subChapters":11227,"url":11230,"docTitle":11119},"Disabling Windows container workloads","disabling-windows-container-workloads",[11228,11229],"uninstalling-wmco_disabling-windows-container-workloads","deleting-wmco-namespace_disabling-windows-container-workloads","/documentation/openshift_container_platform/4.8/html/windows_container_support_for_openshift/disabling-windows-container-workloads",{"title":11232,"urlFragment":11233,"singlePageAnchor":23,"anchor":11233,"docTitle":7888,"url":11234},"Legal Notice","legal-notice","/documentation/openshift_container_platform/4.8/html/operators/legal-notice",[11236,11239,11242,11244],{"text":11237,"link":11238},"OpenShift Container Platform","/documentation/openshift_container_platform/",{"text":11240,"link":11241},"4.8","/documentation/openshift_container_platform/4.8/",{"text":7885,"link":11243},"/documentation/openshift_container_platform/4.8/html/operators/",{"text":12,"link":11245},"../operators/",{"name":7885,"translations":11247,"productVersion":11248,"multiPages":11249,"pdf":11279,"publishingStatus":11281},[5,6,7,8],{"name":11240},[11250,11253,11257,11261,11265,11269,11272,11276],{"name":7885,"contentUrl":11251,"new":11252,"url":22},"https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/421bbb87c3b613cef2a70c16f3ddbf67.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/index",{"name":11254,"contentUrl":11255,"new":11256,"url":7892},"Chapter 1. Operators overview","https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/e4f41c4c7201ead8fdfdb6444a5e12da.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/operators-overview",{"name":11258,"contentUrl":11259,"new":11260,"url":7900},"Chapter 2. Understanding Operators","https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/1c58df25c1b815ee8403252eca7b1fb8.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/understanding-operators",{"name":11262,"contentUrl":11263,"new":11264,"url":8006},"Chapter 3. User tasks","https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/17016b64ae455672004b5eb456982e81.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/user-tasks",{"name":11266,"contentUrl":11267,"new":11268,"url":8019},"Chapter 4. Administrator tasks","https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/7152b4e46fb4eead116ddb4febf3daeb.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/administrator-tasks",{"name":12,"contentUrl":11270,"new":11271,"url":8074},"https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/d6c8bd4135b5f8a4b4ae177ebe502475.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/developing-operators",{"name":11273,"contentUrl":11274,"new":11275,"url":8257},"Chapter 6. Cluster Operators reference","https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/3e965b548b388a58f6942bb1059fdedb.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/cluster-operators-ref",{"name":11232,"contentUrl":11277,"new":11278,"url":11233},"https://d2bhdhkti9t3uj.cloudfront.net/html/2dc1a32d-2aa9-4799-a273-f36db5cdd558/6d5361d7bb0c607b794d22cc02d0aa24.html","https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/operators/legal-notice",{"url":11280},"https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/pdf/operators/OpenShift_Container_Platform-4.8-Operators-en-US.pdf","PUBLISHED",[11283,11286,11289,11292,11295,11298,11301,11304,11307,11310,11312,11315,11318,11321,11324,11327,11330,11333,11336,11339,11342,11345,11348,11351,11354,11357,11360,11363,11366],{"name":11284,"url":11284,"urlAliases":11285},"4.17",[],{"name":11287,"url":11287,"urlAliases":11288},"4.16",[],{"name":11290,"url":11290,"urlAliases":11291},"4.15",[],{"name":11293,"url":11293,"urlAliases":11294},"4.14",[],{"name":11296,"url":11296,"urlAliases":11297},"4.13",[],{"name":11299,"url":11299,"urlAliases":11300},"4.12",[],{"name":11302,"url":11302,"urlAliases":11303},"4.11",[],{"name":11305,"url":11305,"urlAliases":11306},"4.10",[],{"name":11308,"url":11308,"urlAliases":11309},"4.9",[],{"name":11240,"url":11240,"urlAliases":11311},[],{"name":11313,"url":11313,"urlAliases":11314},"4.7",[],{"name":11316,"url":11316,"urlAliases":11317},"4.6",[],{"name":11319,"url":11319,"urlAliases":11320},"4.5",[],{"name":11322,"url":11322,"urlAliases":11323},"4.4",[],{"name":11325,"url":11325,"urlAliases":11326},"4.3",[],{"name":11328,"url":11328,"urlAliases":11329},"4.2",[],{"name":11331,"url":11331,"urlAliases":11332},"4.1",[],{"name":11334,"url":11334,"urlAliases":11335},"3.11",[],{"name":11337,"url":11337,"urlAliases":11338},"3.10",[],{"name":11340,"url":11340,"urlAliases":11341},"3.9",[],{"name":11343,"url":11343,"urlAliases":11344},"3.7",[],{"name":11346,"url":11346,"urlAliases":11347},"3.6",[],{"name":11349,"url":11349,"urlAliases":11350},"3.5",[],{"name":11352,"url":11352,"urlAliases":11353},"3.4",[],{"name":11355,"url":11355,"urlAliases":11356},"3.3",[],{"name":11358,"url":11358,"urlAliases":11359},"3.2",[],{"name":11361,"url":11361,"urlAliases":11362},"3.1",[],{"name":11364,"url":11364,"urlAliases":11365},"3.0",[],{"name":11367,"url":11367,"urlAliases":11368},"2",[],{"about/index":11370,"about/welcome-index":11371,"about/learn_more_about_openshift":11372,"about/oke-about":11373,"about/kubernetes-overview":11374,"release_notes/index":11375,"release_notes/ocp-4-8-release-notes":11376,"architecture/index":11377,"architecture/architecture-overview":11378,"architecture/architecture":11379,"architecture/architecture-installation":11380,"architecture/control-plane":11381,"architecture/understanding-development":11382,"architecture/architecture-rhcos":11383,"architecture/admission-plug-ins":11384,"security_and_compliance/index":11385,"security_and_compliance/security-compliance-overview":11386,"security_and_compliance/container-security-1":11387,"security_and_compliance/configuring-certificates":11388,"security_and_compliance/certificate-types-and-descriptions":11389,"security_and_compliance/compliance-operator":11390,"security_and_compliance/file-integrity-operator":11391,"security_and_compliance/audit-log-view":11392,"security_and_compliance/audit-log-policy-config":11393,"security_and_compliance/tls-security-profiles":11394,"security_and_compliance/seccomp-profiles":11395,"security_and_compliance/allowing-javascript-based-access-api-server":11396,"security_and_compliance/encrypting-etcd":11397,"security_and_compliance/pod-vulnerability-scan":11398,"installing/index":11399,"installing/ocp-installation-overview":11400,"installing/installing-preparing":11401,"installing/installing-mirroring-installation-images":11402,"installing/installing-on-aws":11403,"installing/installing-on-azure":11404,"installing/installing-on-gcp":11405,"installing/installing-on-bare-metal":11406,"installing/deploying-installer-provisioned-clusters-on-bare-metal":11407,"installing/installing-with-z-vm-on-ibm-z-and-linuxone":11408,"installing/installing-with-rhel-kvm-on-ibm-z-and-linuxone":11409,"installing/installing-on-ibm-power-systems":11410,"installing/installing-on-openstack":11411,"installing/installing-on-rhv":11412,"installing/installing-on-vsphere":11413,"installing/installing-on-vmc":11414,"installing/installing-on-any-platform":11415,"installing/installation-configuration":11416,"installing/validating-an-installation":11417,"installing/installing-troubleshooting":11418,"installing/installing-fips":11419,"updating_clusters/index":11420,"updating_clusters/understanding-openshift-updates":11421,"updating_clusters/updating-clusters-overview":11422,"updating_clusters/understanding-upgrade-channels-releases":11423,"updating_clusters/preparing-eus-eus-upgrade":11424,"updating_clusters/updating-cluster-within-minor":11425,"updating_clusters/updating-cluster-cli":11426,"updating_clusters/update-using-custom-machine-config-pools":11427,"updating_clusters/updating-cluster-rhel-compute":11428,"updating_clusters/updating-a-cluster-in-a-disconnected-environment":11429,"storage/index":11430,"storage/storage-overview":11431,"storage/understanding-ephemeral-storage":11432,"storage/understanding-persistent-storage":11433,"storage/configuring-persistent-storage":11434,"storage/using-container-storage-interface-csi":11435,"storage/expanding-persistent-volumes":11436,"storage/dynamic-provisioning":11437,"authentication_and_authorization/index":11438,"authentication_and_authorization/overview-of-authentication-authorization":11439,"authentication_and_authorization/understanding-authentication":11440,"authentication_and_authorization/configuring-internal-oauth":11441,"authentication_and_authorization/configuring-oauth-clients":11442,"authentication_and_authorization/managing-oauth-access-tokens":11443,"authentication_and_authorization/understanding-identity-provider":11444,"authentication_and_authorization/configuring-identity-providers":11445,"authentication_and_authorization/using-rbac":11446,"authentication_and_authorization/removing-kubeadmin":11447,"authentication_and_authorization/understanding-and-creating-service-accounts":11448,"authentication_and_authorization/using-service-accounts":11449,"authentication_and_authorization/using-service-accounts-as-oauth-client":11450,"authentication_and_authorization/tokens-scoping":11451,"authentication_and_authorization/bound-service-account-tokens":11452,"authentication_and_authorization/managing-pod-security-policies":11453,"authentication_and_authorization/impersonating-system-admin":11454,"authentication_and_authorization/ldap-syncing":11455,"authentication_and_authorization/managing-cloud-provider-credentials":11456,"networking/index":11457,"networking/understanding-networking":11458,"networking/accessing-hosts":11459,"networking/networking-operators-overview":11460,"networking/cluster-network-operator":11461,"networking/dns-operator":11462,"networking/configuring-ingress":11463,"networking/verifying-connectivity-endpoint":11464,"networking/configuring-node-port-service-range":11465,"networking/configuring-ipfailover":11466,"networking/using-sctp":11467,"networking/configuring-ptp":11468,"networking/network-policy":11469,"networking/multiple-networks":11470,"networking/hardware-networks":11471,"networking/openshift-sdn-default-cni-network-provider":11472,"networking/ovn-kubernetes-default-cni-network-provider":11473,"networking/configuring-routes":11474,"networking/configuring-ingress-cluster-traffic":11475,"networking/kubernetes-nmstate":11476,"networking/enable-cluster-wide-proxy":11477,"networking/configuring-a-custom-pki":11478,"networking/load-balancing-openstack":11479,"networking/associating-secondary-interfaces-metrics-to-network-attachments":11480,"registry/index":11481,"registry/registry-overview":11482,"registry/configuring-registry-operator":11483,"registry/setting-up-and-configuring-the-registry":11484,"registry/accessing-the-registry":11485,"registry/securing-exposing-registry":11486,"post-installation_configuration/index":11487,"post-installation_configuration/post-install-configuration-overview":11488,"post-installation_configuration/configuring-private-cluster":11489,"post-installation_configuration/post-install-machine-configuration-tasks":11490,"post-installation_configuration/post-install-cluster-tasks":11491,"post-installation_configuration/post-install-node-tasks":11492,"post-installation_configuration/post-install-network-configuration":11493,"post-installation_configuration/post-install-storage-configuration":11494,"post-installation_configuration/post-install-preparing-for-users":11495,"post-installation_configuration/configuring-alert-notifications":11496,"post-installation_configuration/post-install-configure-additional-devices-ibmz":11497,"migrating_from_version_3_to_4/index":11498,"migrating_from_version_3_to_4/migration-from-version-3-to-4-overview":11499,"migrating_from_version_3_to_4/about-migrating-from-3-to-4":11500,"migrating_from_version_3_to_4/planning-migration-3-4":11501,"migrating_from_version_3_to_4/planning-considerations-3-4":11502,"migrating_from_version_3_to_4/about-mtc-3-4":11503,"migrating_from_version_3_to_4/installing-3-4":11504,"migrating_from_version_3_to_4/installing-restricted-3-4":11505,"migrating_from_version_3_to_4/upgrading-3-4":11506,"migrating_from_version_3_to_4/premigration-checklists-3-4":11507,"migrating_from_version_3_to_4/migrating-applications-3-4":11508,"migrating_from_version_3_to_4/advanced-migration-options-3-4":11509,"migrating_from_version_3_to_4/troubleshooting-3-4":11510,"migration_toolkit_for_containers/index":11511,"migration_toolkit_for_containers/about-mtc":11512,"migration_toolkit_for_containers/mtc-release-notes":11513,"migration_toolkit_for_containers/installing-mtc":11514,"migration_toolkit_for_containers/installing-mtc-restricted":11515,"migration_toolkit_for_containers/upgrading-mtc":11516,"migration_toolkit_for_containers/premigration-checklists-mtc":11517,"migration_toolkit_for_containers/network-considerations-mtc":11518,"migration_toolkit_for_containers/migrating-applications-with-mtc":11519,"migration_toolkit_for_containers/advanced-migration-options-mtc":11520,"migration_toolkit_for_containers/troubleshooting-mtc":11521,"backup_and_restore/index":11522,"backup_and_restore/backup-restore-overview":11523,"backup_and_restore/graceful-shutdown-cluster":11524,"backup_and_restore/graceful-restart-cluster":11525,"backup_and_restore/application-backup-and-restore":11526,"backup_and_restore/control-plane-backup-and-restore":11527,"machine_management/index":11528,"machine_management/overview-of-machine-management":11529,"machine_management/creating-machine-sets":11530,"machine_management/manually-scaling-machineset":11531,"machine_management/modifying-machineset":11532,"machine_management/deleting-machine":11533,"machine_management/applying-autoscaling":11534,"machine_management/creating-infrastructure-machinesets":11535,"machine_management/adding-rhel-compute":11536,"machine_management/more-rhel-compute":11537,"machine_management/user-provisioned-infrastructure-2":11538,"machine_management/deploying-machine-health-checks":11539,"metering/index":11540,"metering/about-metering":11541,"metering/installing-metering":11542,"metering/upgrading-metering":11543,"metering/configuring-metering":11544,"metering/reports":11545,"metering/using-metering":11546,"metering/metering-usage-examples":11547,"metering/metering-troubleshooting-debugging":11548,"metering/metering-uninstall":11549,"web_console/index":11550,"web_console/web-console-overview":11551,"web_console/web-console":11552,"web_console/using-dashboard-to-get-cluster-info":11553,"web_console/configuring-web-console":11554,"web_console/customizing-web-console":11555,"web_console/odc-about-web-terminal":11556,"web_console/disabling-web-console":11557,"web_console/creating-quick-start-tutorials":11558,"cli_tools/index":11559,"cli_tools/cli-tools-overview":11560,"cli_tools/openshift-cli-oc":11561,"cli_tools/developer-cli-odo":11562,"cli_tools/kn-cli-tools":11563,"cli_tools/pipelines-cli-tkn":11564,"cli_tools/opm-cli":11565,"cli_tools/operator-sdk":11566,"building_applications/index":11567,"building_applications/building-applications-overview":11568,"building_applications/projects":11569,"building_applications/creating-applications":11570,"building_applications/odc-viewing-application-composition-using-topology-view":11571,"building_applications/working-with-helm-charts":11572,"building_applications/deployments":11573,"building_applications/quotas":11574,"building_applications/config-maps":11575,"building_applications/odc-monitoring-project-and-application-metrics-using-developer-perspective":11576,"building_applications/application-health":11577,"building_applications/odc-editing-applications":11578,"building_applications/pruning-objects":11579,"building_applications/idling-applications":11580,"building_applications/odc-deleting-applications":11581,"building_applications/red-hat-marketplace":11582,"cicd/index":11583,"cicd/ci-cd-overview":11584,"cicd/builds":11585,"cicd/migrating-from-jenkins-to-tekton":11586,"cicd/pipelines":11587,"cicd/gitops":11588,"images/index":11589,"images/overview-of-images":11590,"images/configuring-samples-operator":11591,"images/samples-operator-alt-registry":11592,"images/creating-images":11593,"images/managing-images":11594,"images/managing-image-streams":11595,"images/using-imagestreams-with-kube-resources":11596,"images/triggering-updates-on-imagestream-changes":11597,"images/image-configuration":11598,"images/using-templates":11599,"images/templates-using-ruby-on-rails":11600,"images/using-images":11601,"nodes/index":11602,"nodes/overview-of-nodes":11603,"nodes/working-with-pods":11604,"nodes/controlling-pod-placement-onto-nodes-scheduling":11605,"nodes/using-jobs-and-daemonsets":11606,"nodes/working-with-nodes":11607,"nodes/working-with-containers":11608,"nodes/working-with-clusters":11609,"nodes/remote-worker-nodes-on-the-network-edge":11610,"sandboxed_containers_support_for_openshift/index":11611,"sandboxed_containers_support_for_openshift/sandboxed-containers-4-8-release-notes":11612,"sandboxed_containers_support_for_openshift/understanding-sandboxed-containers":11613,"sandboxed_containers_support_for_openshift/deploying-sandboxed-containers-workloads":11614,"sandboxed_containers_support_for_openshift/uninstalling-sandboxed-containers":11615,"sandboxed_containers_support_for_openshift/upgrade-sandboxed-containers":11616,"operators/index":11617,"operators/operators-overview":11618,"operators/understanding-operators":11619,"operators/user-tasks":11620,"operators/administrator-tasks":11621,"operators/developing-operators":11622,"operators/cluster-operators-ref":11623,"logging/index":11624,"logging/release-notes":11625,"logging/cluster-logging":11626,"logging/cluster-logging-deploying":11627,"logging/configuring-your-logging-deployment":11628,"logging/vewing-resource-logs":11629,"logging/cluster-logging-visualizer-using":11630,"logging/cluster-logging-external":11631,"logging/cluster-logging-enabling-json-logging":11632,"logging/cluster-logging-eventrouter":11633,"logging/cluster-logging-upgrading":11634,"logging/cluster-logging-dashboards":11635,"logging/troubleshooting-logging":11636,"logging/cluster-logging-uninstall":11637,"logging/cluster-logging-exported-fields":11638,"logging/message":11639,"logging/structured":11640,"logging/timestamp":11641,"logging/hostname":11642,"logging/ipaddr4":11643,"logging/ipaddr6":11644,"logging/level":11645,"logging/pid":11646,"logging/service":11647,"logging/tags":11648,"logging/file":11649,"logging/offset":11650,"logging/cluster-logging-exported-fields-kubernetes_cluster-logging-exported-fields":11651,"logging/openshift":11652,"monitoring/index":11653,"monitoring/monitoring-overview":11654,"monitoring/configuring-the-monitoring-stack":11655,"monitoring/enabling-monitoring-for-user-defined-projects":11656,"monitoring/managing-metrics":11657,"monitoring/managing-alerts":11658,"monitoring/reviewing-monitoring-dashboards":11659,"monitoring/accessing-third-party-uis":11660,"monitoring/troubleshooting-monitoring-issues":11661,"scalability_and_performance/index":11662,"scalability_and_performance/recommended-host-practices":11663,"scalability_and_performance/ibm-z-recommended-host-practices":11664,"scalability_and_performance/recommended-cluster-scaling-practices":11665,"scalability_and_performance/using-node-tuning-operator":11666,"scalability_and_performance/using_cluster_loader_node-tuning-operator":11667,"scalability_and_performance/using-cpu-manager":11668,"scalability_and_performance/using-topology-manager":11669,"scalability_and_performance/scaling-cluster-monitoring-operator":11670,"scalability_and_performance/node-feature-discovery-operator":11671,"scalability_and_performance/driver-toolkit":11672,"scalability_and_performance/planning-your-environment-according-to-object-maximums":11673,"scalability_and_performance/optimizing-storage":11674,"scalability_and_performance/routing-optimization":11675,"scalability_and_performance/optimizing-networking":11676,"scalability_and_performance/managing-bare-metal-hosts":11677,"scalability_and_performance/what-huge-pages-do-and-how-they-are-consumed":11678,"scalability_and_performance/cnf-performance-addon-operator-for-low-latency-nodes":11679,"scalability_and_performance/cnf-performing-platform-verification-latency-tests":11680,"scalability_and_performance/cnf-create-performance-profiles":11681,"support/index":11682,"support/support-overview":11683,"support/managing-cluster-resources":11684,"support/getting-support":11685,"support/remote-health-monitoring-with-connected-clusters":11686,"support/gathering-cluster-data":11687,"support/summarizing-cluster-specifications":11688,"support/troubleshooting":11689,"service_mesh/index":11690,"service_mesh/service-mesh-2-x":11691,"service_mesh/service-mesh-1-x":11692,"distributed_tracing/index":11693,"distributed_tracing/distr-tracing-release-notes":11694,"distributed_tracing/distributed-tracing-architecture":11695,"distributed_tracing/distributed-tracing-installation":11696,"serverless/index":11697,"serverless/serverless-release-notes":11698,"serverless/discover":11699,"serverless/install":11700,"serverless/knative-cli":11701,"serverless/develop":11702,"serverless/administer":11703,"serverless/monitor":11704,"serverless/serverless-tracing":11705,"serverless/serverless-support":11706,"serverless/security":11707,"serverless/functions":11708,"serverless/integrations":11709,"openshift_virtualization/index":11710,"openshift_virtualization/about-virt":11711,"openshift_virtualization/start-here-with-openshift-virtualization":11712,"openshift_virtualization/openshift-virtualization-release-notes":11713,"openshift_virtualization/installing-openshift-virtualization":11714,"openshift_virtualization/upgrading-openshift-virtualization":11715,"openshift_virtualization/virt-additional-security-privileges-controller-and-launcher":11716,"openshift_virtualization/virt-using-the-cli-tools":11717,"openshift_virtualization/virtual-machines":11718,"openshift_virtualization/virtual-machine-templates":11719,"openshift_virtualization/live-migration":11720,"openshift_virtualization/node-maintenance":11721,"openshift_virtualization/node-networking":11722,"openshift_virtualization/logging-events-and-monitoring":11723,"windows_container_support_for_openshift/index":11724,"windows_container_support_for_openshift/windows-container-overview":11725,"windows_container_support_for_openshift/windows-containers-release-notes-3-x":11726,"windows_container_support_for_openshift/understanding-windows-container-workloads":11727,"windows_container_support_for_openshift/enabling-windows-container-workloads":11728,"windows_container_support_for_openshift/creating-windows-machineset-objects":11729,"windows_container_support_for_openshift/scheduling-windows-workloads":11730,"windows_container_support_for_openshift/windows-node-upgrades":11731,"windows_container_support_for_openshift/byoh-windows-instance":11732,"windows_container_support_for_openshift/removing-windows-nodes":11733,"windows_container_support_for_openshift/disabling-windows-container-workloads":11734,"operators/legal-notice":11735},{"prevt":23,"next":22},{"prevt":23,"next":43},{"prevt":31,"next":54},{"prevt":43,"next":76},{"prevt":54,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":387},{"prevt":391,"next":417},{"prevt":387,"next":428},{"prevt":417,"next":443},{"prevt":428,"next":461},{"prevt":443,"next":476},{"prevt":461,"next":23},{"prevt":22,"next":23},{"prevt":23,"next":503},{"prevt":495,"next":588},{"prevt":503,"next":611},{"prevt":588,"next":682},{"prevt":611,"next":812},{"prevt":682,"next":866},{"prevt":812,"next":877},{"prevt":866,"next":885},{"prevt":877,"next":896},{"prevt":885,"next":907},{"prevt":896,"next":914},{"prevt":907,"next":923},{"prevt":914,"next":23},{"prevt":23,"next":23},{"prevt":23,"next":948},{"prevt":939,"next":961},{"prevt":948,"next":983},{"prevt":961,"next":1282},{"prevt":983,"next":1486},{"prevt":1282,"next":1803},{"prevt":1486,"next":1984},{"prevt":1803,"next":2068},{"prevt":1984,"next":2168},{"prevt":2068,"next":2276},{"prevt":2168,"next":2382},{"prevt":2276,"next":2685},{"prevt":2382,"next":2807},{"prevt":2685,"next":3072},{"prevt":2807,"next":3340},{"prevt":3072,"next":3396},{"prevt":3340,"next":3422},{"prevt":3396,"next":3437},{"prevt":3422,"next":3449},{"prevt":3437,"next":23},{"prevt":23,"next":23},{"prevt":23,"next":3475},{"prevt":3469,"next":3489},{"prevt":3475,"next":3503},{"prevt":3489,"next":3509},{"prevt":3503,"next":3517},{"prevt":3509,"next":3524},{"prevt":3517,"next":3537},{"prevt":3524,"next":3548},{"prevt":3537,"next":23},{"prevt":23,"next":22},{"prevt":23,"next":3605},{"prevt":3594,"next":3614},{"prevt":3605,"next":3642},{"prevt":3614,"next":3718},{"prevt":3642,"next":3784},{"prevt":3718,"next":3794},{"prevt":3784,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":3827},{"prevt":3819,"next":3839},{"prevt":3827,"next":3853},{"prevt":3839,"next":3861},{"prevt":3853,"next":3869},{"prevt":3861,"next":3879},{"prevt":3869,"next":3955},{"prevt":3879,"next":3974},{"prevt":3955,"next":3981},{"prevt":3974,"next":3989},{"prevt":3981,"next":4000},{"prevt":3989,"next":4007},{"prevt":4000,"next":4015},{"prevt":4007,"next":4022},{"prevt":4015,"next":4043},{"prevt":4022,"next":4051},{"prevt":4043,"next":4080},{"prevt":4051,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":4137},{"prevt":4128,"next":4143},{"prevt":4137,"next":4151},{"prevt":4143,"next":4164},{"prevt":4151,"next":4175},{"prevt":4164,"next":4210},{"prevt":4175,"next":4219},{"prevt":4210,"next":4227},{"prevt":4219,"next":4240},{"prevt":4227,"next":4249},{"prevt":4240,"next":4260},{"prevt":4249,"next":4296},{"prevt":4260,"next":4349},{"prevt":4296,"next":4421},{"prevt":4349,"next":4488},{"prevt":4421,"next":4563},{"prevt":4488,"next":4585},{"prevt":4563,"next":4624},{"prevt":4585,"next":4653},{"prevt":4624,"next":4661},{"prevt":4653,"next":4670},{"prevt":4661,"next":4682},{"prevt":4670,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":4708},{"prevt":4696,"next":4720},{"prevt":4708,"next":4760},{"prevt":4720,"next":4770},{"prevt":4760,"next":23},{"prevt":22,"next":23},{"prevt":23,"next":4789},{"prevt":4783,"next":4798},{"prevt":4789,"next":4821},{"prevt":4798,"next":4877},{"prevt":4821,"next":4963},{"prevt":4877,"next":5000},{"prevt":4963,"next":5029},{"prevt":5000,"next":5064},{"prevt":5029,"next":5072},{"prevt":5064,"next":23},{"prevt":23,"next":22},{"prevt":23,"next":5109},{"prevt":5094,"next":5114},{"prevt":5109,"next":5127},{"prevt":5114,"next":5136},{"prevt":5127,"next":5147},{"prevt":5136,"next":5177},{"prevt":5147,"next":5204},{"prevt":5177,"next":5212},{"prevt":5204,"next":5221},{"prevt":5212,"next":5233},{"prevt":5221,"next":5271},{"prevt":5233,"next":23},{"prevt":22,"next":23},{"prevt":23,"next":5334},{"prevt":5323,"next":5349},{"prevt":5334,"next":5378},{"prevt":5349,"next":5404},{"prevt":5378,"next":5411},{"prevt":5404,"next":5418},{"prevt":5411,"next":5426},{"prevt":5418,"next":5437},{"prevt":5426,"next":5474},{"prevt":5437,"next":23},{"prevt":23,"next":22},{"prevt":23,"next":5536},{"prevt":5527,"next":5542},{"prevt":5536,"next":5548},{"prevt":5542,"next":5639},{"prevt":5548,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":5672},{"prevt":5667,"next":5714},{"prevt":5672,"next":5721},{"prevt":5714,"next":5730},{"prevt":5721,"next":5737},{"prevt":5730,"next":5750},{"prevt":5737,"next":5773},{"prevt":5750,"next":5791},{"prevt":5773,"next":5807},{"prevt":5791,"next":5830},{"prevt":5807,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":5863},{"prevt":5850,"next":5875},{"prevt":5863,"next":5880},{"prevt":5875,"next":5910},{"prevt":5880,"next":5932},{"prevt":5910,"next":5939},{"prevt":5932,"next":5947},{"prevt":5939,"next":5966},{"prevt":5947,"next":23},{"prevt":22,"next":23},{"prevt":23,"next":5989},{"prevt":5980,"next":5995},{"prevt":5989,"next":6001},{"prevt":5995,"next":6007},{"prevt":6001,"next":6022},{"prevt":6007,"next":6032},{"prevt":6022,"next":6038},{"prevt":6032,"next":23},{"prevt":23,"next":23},{"prevt":23,"next":6090},{"prevt":6084,"next":6335},{"prevt":6090,"next":6418},{"prevt":6335,"next":6425},{"prevt":6418,"next":6516},{"prevt":6425,"next":6524},{"prevt":6516,"next":23},{"prevt":23,"next":22},{"prevt":23,"next":6567},{"prevt":6556,"next":6593},{"prevt":6567,"next":6630},{"prevt":6593,"next":6646},{"prevt":6630,"next":6672},{"prevt":6646,"next":6724},{"prevt":6672,"next":6744},{"prevt":6724,"next":6754},{"prevt":6744,"next":6761},{"prevt":6754,"next":6772},{"prevt":6761,"next":6779},{"prevt":6772,"next":6796},{"prevt":6779,"next":6805},{"prevt":6796,"next":6811},{"prevt":6805,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":6835},{"prevt":6826,"next":6985},{"prevt":6835,"next":7001},{"prevt":6985,"next":7110},{"prevt":7001,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":7260},{"prevt":7241,"next":7276},{"prevt":7260,"next":7288},{"prevt":7276,"next":7307},{"prevt":7288,"next":7327},{"prevt":7307,"next":7347},{"prevt":7327,"next":7353},{"prevt":7347,"next":7361},{"prevt":7353,"next":7374},{"prevt":7361,"next":7399},{"prevt":7374,"next":7413},{"prevt":7399,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":7457},{"prevt":7449,"next":7538},{"prevt":7457,"next":7621},{"prevt":7538,"next":7638},{"prevt":7621,"next":7705},{"prevt":7638,"next":7757},{"prevt":7705,"next":7815},{"prevt":7757,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":7843},{"prevt":7830,"next":7851},{"prevt":7843,"next":7867},{"prevt":7851,"next":7879},{"prevt":7867,"next":23},{"prevt":22,"next":23},{"prevt":23,"next":7900},{"prevt":7892,"next":8006},{"prevt":7900,"next":8019},{"prevt":8006,"next":8074},{"prevt":8019,"next":8257},{"prevt":8074,"next":23},{"prevt":23,"next":22},{"prevt":23,"next":8429},{"prevt":8300,"next":8449},{"prevt":8429,"next":8458},{"prevt":8449,"next":8502},{"prevt":8458,"next":8508},{"prevt":8502,"next":8515},{"prevt":8508,"next":8542},{"prevt":8515,"next":8550},{"prevt":8542,"next":8556},{"prevt":8550,"next":8563},{"prevt":8556,"next":8571},{"prevt":8563,"next":8604},{"prevt":8571,"next":8610},{"prevt":8604,"next":8614},{"prevt":8610,"next":8618},{"prevt":8614,"next":8623},{"prevt":8618,"next":8627},{"prevt":8623,"next":8631},{"prevt":8627,"next":8635},{"prevt":8631,"next":8639},{"prevt":8635,"next":8643},{"prevt":8639,"next":8647},{"prevt":8643,"next":8651},{"prevt":8647,"next":8656},{"prevt":8651,"next":8661},{"prevt":8656,"next":8668},{"prevt":8661,"next":8702},{"prevt":8668,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":8726},{"prevt":8714,"next":8749},{"prevt":8726,"next":8761},{"prevt":8749,"next":8774},{"prevt":8761,"next":8796},{"prevt":8774,"next":8803},{"prevt":8796,"next":8810},{"prevt":8803,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":8840},{"prevt":8823,"next":8861},{"prevt":8840,"next":8873},{"prevt":8861,"next":8885},{"prevt":8873,"next":8896},{"prevt":8885,"next":8902},{"prevt":8896,"next":8910},{"prevt":8902,"next":8917},{"prevt":8910,"next":8932},{"prevt":8917,"next":8943},{"prevt":8932,"next":8953},{"prevt":8943,"next":8961},{"prevt":8953,"next":8968},{"prevt":8961,"next":8976},{"prevt":8968,"next":8987},{"prevt":8976,"next":8997},{"prevt":8987,"next":9047},{"prevt":8997,"next":9061},{"prevt":9047,"next":23},{"prevt":22,"next":23},{"prevt":23,"next":9088},{"prevt":9079,"next":9094},{"prevt":9088,"next":9104},{"prevt":9094,"next":9138},{"prevt":9104,"next":9155},{"prevt":9138,"next":5620},{"prevt":9155,"next":23},{"prevt":23,"next":22},{"prevt":23,"next":9680},{"prevt":9247,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":9914},{"prevt":9884,"next":9923},{"prevt":9914,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":10025},{"prevt":9971,"next":10048},{"prevt":10025,"next":10077},{"prevt":10048,"next":10131},{"prevt":10077,"next":10260},{"prevt":10131,"next":10337},{"prevt":10260,"next":10357},{"prevt":10337,"next":10366},{"prevt":10357,"next":10377},{"prevt":10366,"next":10395},{"prevt":10377,"next":10500},{"prevt":10395,"next":23},{"prevt":22,"next":22},{"prevt":23,"next":10525},{"prevt":10518,"next":10533},{"prevt":10525,"next":10551},{"prevt":10533,"next":10603},{"prevt":10551,"next":10614},{"prevt":10603,"next":10623},{"prevt":10614,"next":10630},{"prevt":10623,"next":10956},{"prevt":10630,"next":10986},{"prevt":10956,"next":11008},{"prevt":10986,"next":11034},{"prevt":11008,"next":11060},{"prevt":11034,"next":23},{"prevt":22,"next":23},{"prevt":23,"next":11128},{"prevt":11123,"next":11155},{"prevt":11128,"next":11168},{"prevt":11155,"next":11177},{"prevt":11168,"next":11198},{"prevt":11177,"next":11207},{"prevt":11198,"next":11213},{"prevt":11207,"next":11220},{"prevt":11213,"next":11226},{"prevt":11220,"next":23},{"prev":11736,"next":11736},"",{"product":23,"version":23},{"index":11739,"operators-overview":11740,"understanding-operators":11741,"user-tasks":11742,"administrator-tasks":11743,"developing-operators":11744,"cluster-operators-ref":11745,"legal-notice":11746},[11252],[11256],[11260],[11264],[11268],[11271],[11275],[11278],{"products":11748},[11749,11750,11751,11752,11753,11754,11755,11756,11757,11758,11759,11760,11761],"builds_for_red_hat_openshift","migration_toolkit_for_virtualization","openshift_container_platform","openshift_sandboxed_containers","red_hat_advanced_cluster_security_for_kubernetes","red_hat_advanced_cluster_management_for_kubernetes","red_hat_openshift_data_foundation","red_hat_openshift_dev_spaces","red_hat_openshift_gitops","red_hat_openshift_local","red_hat_openshift_pipelines","red_hat_openshift_serverless","workload_availability_for_red_hat_openshift",[11763,11766,11769,11772,11775,11778,11781,11784,11787,11790,11793,11796,11799],{"title":11764,"visible":17,"weight":21,"urlFragment":8074,"anchor":8076,"singlePageAnchor":8076,"subChapters":11765},"About the Operator SDK",[8077,8078,8079],{"title":11767,"visible":17,"weight":30,"urlFragment":8074,"anchor":8080,"singlePageAnchor":8080,"subChapters":11768},"Installing the Operator SDK CLI",[8081],{"title":11770,"visible":17,"weight":42,"urlFragment":8074,"anchor":8082,"singlePageAnchor":8082,"subChapters":11771},"Upgrading projects for newer Operator SDK versions",[8083,8084],{"title":11773,"visible":17,"weight":53,"urlFragment":8074,"anchor":8085,"singlePageAnchor":8085,"subChapters":11774},"Go-based Operators",[8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114],{"title":11776,"visible":17,"weight":75,"urlFragment":8074,"anchor":8115,"singlePageAnchor":8115,"subChapters":11777},"Ansible-based Operators",[8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143,8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156],{"title":11779,"visible":17,"weight":442,"urlFragment":8074,"anchor":8157,"singlePageAnchor":8157,"subChapters":11780},"Helm-based Operators",[8158,8159,8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181],{"title":11782,"visible":17,"weight":460,"urlFragment":8074,"anchor":8182,"singlePageAnchor":8182,"subChapters":11783},"Defining cluster service versions (CSVs)",[8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208],{"title":11785,"visible":17,"weight":475,"urlFragment":8074,"anchor":8209,"singlePageAnchor":8209,"subChapters":11786},"Working with bundle images",[8210,8211,8212,8213,8214,8215],{"title":11788,"visible":17,"weight":876,"urlFragment":8074,"anchor":8216,"singlePageAnchor":8216,"subChapters":11789},"Validating Operators using the scorecard tool",[8217,8218,8219,8220,8221,8222,8223,8224],{"title":11791,"visible":17,"weight":884,"urlFragment":8074,"anchor":8225,"singlePageAnchor":8225,"subChapters":11792},"Configuring built-in monitoring with Prometheus",[8226,8227,8228,8229,8230],{"title":11794,"visible":17,"weight":895,"urlFragment":8074,"anchor":8231,"singlePageAnchor":8231,"subChapters":11795},"Configuring leader election",[8232,8233,8234],{"title":11797,"visible":17,"weight":906,"urlFragment":8074,"anchor":8235,"singlePageAnchor":8235,"subChapters":11798},"Migrating package manifest projects to bundle format",[8236,8237],{"title":11800,"visible":17,"weight":913,"urlFragment":8074,"anchor":8238,"singlePageAnchor":8238,"subChapters":11801},"Operator SDK CLI reference",[8239,8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253],{"default":11803},[11804,11813,11819,11828,11836,11844,11851,11859,11865],{"nid":11805,"type":11806,"langcode":11807,"Published":21,"title":11808,"Created":11809,"Updated":11810,"body_value":23,"field_documentation banner_text_value":23,"field_documentation banner_text_format":23,"field_paths_value":11811,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":11812},580,"rebrand banner","en","OpenShift Container Storage is now OpenShift Data Foundation starting with version 4.9.","2023-01-11 15:38:32","2023-01-11 15:40:04","/documentation/red_hat_openshift_container_storage\r\n/documentation/red_hat_openshift_container_storage/\r\n/documentation/red_hat_openshift_container_storage/*","internal:/documentation/red_hat_openshift_data_foundation/",{"nid":11814,"type":11806,"langcode":11807,"Published":21,"title":11808,"Created":11815,"Updated":11816,"body_value":23,"field_documentation banner_text_value":23,"field_documentation banner_text_format":23,"field_paths_value":11817,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":11818},581,"2023-01-11 15:41:31","2023-01-11 15:42:04","/documentation/red_hat_openshift_data_foundation/4.9\r\n/documentation/red_hat_openshift_data_foundation/4.9/\r\n/documentation/red_hat_openshift_data_foundation/4.9/*\r\n/documentation/red_hat_openshift_data_foundation/4.10\r\n/documentation/red_hat_openshift_data_foundation/4.10/\r\n/documentation/red_hat_openshift_data_foundation/4.10/*\r\n/documentation/red_hat_openshift_data_foundation/4.11\r\n/documentation/red_hat_openshift_data_foundation/4.11/\r\n/documentation/red_hat_openshift_data_foundation/4.11/*","internal:/documentation/red_hat_openshift_container_storage/",{"nid":11820,"type":11821,"langcode":11807,"Published":21,"title":11822,"Created":11823,"Updated":11824,"body_value":23,"field_documentation banner_text_value":11825,"field_documentation banner_text_format":11826,"field_paths_value":11827,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":23},582,"developer preview banner","MicroShift is Developer Preview software only","2023-01-11 15:50:24","2023-01-30 19:00:52","\u003Cp slot=header>MicroShift is Developer Preview software only.\u003C/p>For more information about the support scope of Red Hat Developer Preview software, see \u003Ca href=\"https://access.redhat.com/support/offerings/devpreview/\">Developer Preview Support Scope\u003C/a>.","documentation banner","/documentation/microshift/4.12\r\n/documentation/microshift/4.12/*\r\n/documentation/red_hat_build_of_microshift/4.12\r\n/documentation/red_hat_build_of_microshift/4.12/*",{"nid":11829,"type":11830,"langcode":11807,"Published":21,"title":11831,"Created":11832,"Updated":11833,"body_value":23,"field_documentation banner_text_value":11834,"field_documentation banner_text_format":11826,"field_paths_value":11835,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":23},583,"obsolete documentation banner","RHACS EOL - DAT-3433","2023-01-23 16:36:43","2023-01-23 16:39:14","\u003Cp slot=header>You are viewing documentation for a release that is no longer maintained. To view the documentation for the most recent version, see the \u003Ca href=\"/documentation/red_hat_advanced_cluster_security_for_kubernetes/\">latest RHACS docs\u003C/a>.\u003C/p>","/documentation/red_hat_advanced_cluster_security_for_kubernetes/3.69\r\n/documentation/red_hat_advanced_cluster_security_for_kubernetes/3.69/*\r\n/documentation/red_hat_advanced_cluster_security_for_kubernetes/3.70\r\n/documentation/red_hat_advanced_cluster_security_for_kubernetes/3.70/*\r\n/documentation/red_hat_advanced_cluster_security_for_kubernetes/3.71\r\n/documentation/red_hat_advanced_cluster_security_for_kubernetes/3.71/*",{"nid":11837,"type":11838,"langcode":11807,"Published":21,"title":11839,"Created":11840,"Updated":11841,"body_value":23,"field_documentation banner_text_value":11842,"field_documentation banner_text_format":11826,"field_paths_value":11843,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":23},584,"end of life banner","EOL banner for RHV","2023-05-23 14:58:05","2023-05-24 15:19:42","\u003Cp slot=header>The Red Hat Virtualization\u003C/p>Maintenance Phase runs until August 31, 2024, followed by the Extended Life Phase with no more software fixes through August 31, 2026. See \u003Ca href=\"https://access.redhat.com/articles/6975303\">Migration Paths for OpenShift Container Platform deployed on Red Hat Virtualization\u003C/a> for details.","/documentation/red_hat_virtualization/4.4",{"nid":11845,"type":11838,"langcode":11807,"Published":21,"title":11846,"Created":11847,"Updated":11848,"body_value":23,"field_documentation banner_text_value":11849,"field_documentation banner_text_format":11826,"field_paths_value":11850,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":23},585,"RHHI-V EOL","2023-06-01 16:52:57","2023-06-01 17:03:44","\u003Cp slot=header>Red Hat Hyperconverged Infrastructure for Virtualization\u003C/p> is in the \u003Ca href=\"https://access.redhat.com/support/policy/updates/rhhiv\">Maintenance Support Phase\u003C/a> of its lifecycle until October 31, 2024. After that date, the product will be End of Life. See the \u003Ca href=\"https://access.redhat.com/announcements/6972521\">RHHI-V announcement\u003C/a> for next steps.","/documentation/red_hat_hyperconverged_infrastructure_for_virtualization/1.8",{"nid":11852,"type":11853,"langcode":11807,"Published":21,"title":11854,"Created":11855,"Updated":11856,"body_value":23,"field_documentation banner_text_value":11857,"field_documentation banner_text_format":11826,"field_paths_value":11858,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":23},586,"preview banner","MicroShift is Technology Preview software only","2024-03-18 16:53:05","2024-03-18 16:54:56","\u003Cp slot=header>MicroShift is Technology Preview software only.\u003C/p>For more information about the support scope of Red Hat Technology Preview software, see \u003Ca href=\"https://access.redhat.com/support/offerings/techpreview/\">Technology Preview Support Scope\u003C/a>.","/documentation/red_hat_build_of_microshift/4.13\r\n/documentation/red_hat_build_of_microshift/4.13/*",{"nid":11860,"type":11853,"langcode":11807,"Published":21,"title":11861,"Created":11862,"Updated":11863,"body_value":23,"field_documentation banner_text_value":11864,"field_documentation banner_text_format":11826,"field_paths_value":11736,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":23},588,"Ansible 2.5 upgrade limitation","2024-09-30 16:53:05","2024-10-28 16:54:56","\u003Cp slot=\"header\">Support added for upgrades from 2.4\u003C/p>Ansible Automation Platform 2.5-3, released on October 28, 2024, adds support for upgrades from 2.4. See the upgrade documentation for more information.",{"nid":11866,"alertType":11867,"type":11868,"langcode":11807,"Published":21,"title":11869,"Created":11736,"Updated":11736,"body_value":23,"field_documentation banner_text_value":11870,"field_documentation banner_text_format":11826,"field_paths_value":11871,"field_documentation_training_url_uri":23,"field_title_title_id":23,"field_rebrand banner_link_uri":23},587,"warning","Warning banner","Red Hat build of Apache Camel K","\u003Cp slot=header>Red Hat Camel K is deprecated\u003C/p>Red Hat Camel K is deprecated and the End of Life date for this product is June 30, 2025. For help migrating to the current go-to solution, \u003Ca target=_blank href=\"https://docs.redhat.com/en/documentation/red_hat_build_of_apache_camel\">Red Hat build of Apache Camel\u003C/a>, see the \u003Ca target=_blank href=\"https://docs.redhat.com/en/documentation/red_hat_build_of_apache_camel_k/1.10.7/html/migration_guide_camel_k_to_camel_extensions_for_quarkus/index\">Migration Guide\u003C/a>.","/documentation/red_hat_build_of_apache_camel_k/*",["Reactive",11873],{"$snuxt-i18n-meta":11874,"$sisLoading":11875,"$sisSinglePage":11875,"$sisInFocusMode":11875,"$smobileTocOpen":11875,"$sisLargeTOC":17,"$scurrentChapter":8074,"$scurrentSection":8074,"$scurrentSubSection":11736},{},false,["Set"],["ShallowReactive",11878],{"s8LoCEfG4A":23,"rFVLKcOK8e":23,"uUstF4AIyn":23,"MdHNSZP4nR":23,"Pn02PlJOas":23},"/en/documentation/openshift_container_platform/4.8/html/operators/developing-operators"]</script> <script>window.__NUXT__={};window.__NUXT__.config={public:{contentEnv:"",collectFeedback:true,i18n:{baseUrl:"",defaultLocale:"en",defaultDirection:"ltr",strategy:"prefix",lazy:false,rootRedirect:"",routesNameSeparator:"___",defaultLocaleRouteNameSuffix:"default",skipSettingLocaleOnNavigate:false,differentDomains:false,trailingSlash:false,configLocales:[{code:"en",name:"English",iso:"en-US"},{code:"fr",name:"Français",iso:"fr-FR"},{code:"ko",name:"한국어",iso:"ko-KR"},{code:"ja",name:"日本語",iso:"ja-JP"},{code:"zh-cn",name:"中文 (中国)",iso:"zh-CN"},{code:"de",name:"Deutsch",iso:"de_DE"},{code:"it",name:"Italiano",iso:"it_IT"},{code:"pt-br",name:"Português",iso:"pt_BR"},{code:"es",name:"Español",iso:"es-ES"}],locales:{en:{domain:""},fr:{domain:""},ko:{domain:""},ja:{domain:""},"zh-cn":{domain:""},de:{domain:""},it:{domain:""},"pt-br":{domain:""},es:{domain:""}},detectBrowserLanguage:{alwaysRedirect:false,cookieCrossOrigin:false,cookieDomain:"",cookieKey:"i18n_redirected",cookieSecure:false,fallbackLocale:"",redirectOn:"root",useCookie:true},experimental:{localeDetector:"",switchLocalePathLinkSSR:false,autoImportTranslationFunctions:false}}},app:{baseURL:"/",buildId:"1e9767f5-0835-47d0-9b5e-ba8895a28f36",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10