1"use strict";(globalThis.webpackChunkratify=globalThis.webpackChunkratify||[]).push([[2712],{28453(e,a,i){i.d(a,{R:()=>s,x:()=>r});var n=i(96540);const t={},l=n.createContext(t);function s(e){const a=n.useContext(l);return n.useMemo(function(){return"function"==typeof e?e(a):{...a,...e}},[a,e])}function r(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),n.createElement(l.Provider,{value:a},e.children)}},61207(e,a,i){i.r(a),i.d(a,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"quickstarts/ratify-high-availability","title":"Install Ratify for High Availability","description":"Feature status: Experimental.","source":"@site/versioned_docs/version-1.4/quickstarts/ratify-high-availability.md","sourceDirName":"quickstarts","slug":"/quickstarts/ratify-high-availability","permalink":"/docs/quickstarts/ratify-high-availability","draft":false,"unlisted":false,"editUrl":"https://github.com/ratify-project/ratify-web/blob/main/versioned_docs/version-1.4/quickstarts/ratify-high-availability.md","tags":[],"version":"1.4","sidebarPosition":5,"frontMatter":{"sidebar_position":5},"sidebar":"tutorialSidebar","previous":{"title":"Ratify with Venafi CodeSign Protect","permalink":"/docs/quickstarts/ratify-with-venafi"},"next":{"title":"Creating Plugins","permalink":"/docs/quickstarts/creating-plugins"}}');var t=i(74848),l=i(28453);const s={sidebar_position:5},r="Install Ratify for High Availability",d={},o=[{value:"Automated Installation",id:"automated-installation",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Uninstall Steps",id:"uninstall-steps",level:3},{value:"Manual Installation Steps",id:"manual-installation-steps",level:2},{value:"Add Helm Chart Dependencies",id:"add-helm-chart-dependencies",level:3},{value:"Install Dapr",id:"install-dapr",level:3},{value:"Install Gatekeeper",id:"install-gatekeeper",level:3},{value:"Install Redis",id:"install-redis",level:3},{value:"Install Ratify",id:"install-ratify",level:3},{value:"See Ratify in action",id:"see-ratify-in-action",level:3},{value:"Uninstall Ratify",id:"uninstall-ratify",level:3},{value:"Development Testing with Helmfile (build your own images)",id:"development-testing-with-helmfile-build-your-own-images",level:2},{value:"Update <code>dev.high-availability.helmfile.yaml</code>",id:"update-devhigh-availabilityhelmfileyaml",level:3}];function c(e){const a={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(a.header,{children:(0,t.jsx)(a.h1,{id:"install-ratify-for-high-availability",children:"Install Ratify for High Availability"})}),"\n",(0,t.jsxs)(a.blockquote,{children:["\n",(0,t.jsxs)(a.p,{children:["Feature status: ",(0,t.jsx)(a.strong,{children:"Experimental"}),".\nExperimental features are intended for testing and feedback as their functionality or design may change in a future release without warning."]}),"\n"]}),"\n",(0,t.jsx)(a.p,{children:"The default Ratify installation relies on a single Ratify pod processing all requests. For higher performance and availability requirements, Ratify can be set to run with multiple replicas and a shared state store."}),"\n",(0,t.jsxs)(a.p,{children:["Ratify installation/upgrade for HA scenarios can be done via a ",(0,t.jsx)(a.code,{children:"helmfile"})," or manual installation steps. Both options are outlined in this document."]}),"\n",(0,t.jsx)(a.h2,{id:"automated-installation",children:"Automated Installation"}),"\n",(0,t.jsxs)(a.blockquote,{children:["\n",(0,t.jsx)(a.p,{children:"Note: Helmfile does not have a stable release and thus is NOT recommended for production environments"}),"\n"]}),"\n",(0,t.jsx)(a.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"# Download and install yq\n curl -L https://github.com/mikefarah/yq/releases/download/v4.34.2/yq_linux_amd64 --output /usr/bin/yq && chmod +x /usr/bin/yq\n"})}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"# Download and install helmfile\n curl -LO https://github.com/helmfile/helmfile/releases/download/v0.155.0/helmfile_0.155.0_linux_amd64.tar.gz\n mkdir helmfile-install\n tar -zxf helmfile*.tar.gz -C helmfile-install/\n mv helmfile-install/helmfile /usr/bin\n rm -rf helmfile*.tar.gz helmfile-install/\n"})}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"# Sync helm chart resources defined with cluster\nhelmfile sync -f git::https://github.com/notaryproject/[email protected]\n"})}),"\n",(0,t.jsx)(a.h3,{id:"uninstall-steps",children:"Uninstall Steps"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"helmfile destroy --skip-charts -f git::https://github.com/notaryproject/[email protected]\n"})}),"\n",(0,t.jsx)(a.h2,{id:"manual-installation-steps",children:"Manual Installation Steps"}),"\n",(0,t.jsx)(a.h3,{id:"add-helm-chart-dependencies",children:"Add Helm Chart Dependencies"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"helm repo add dapr https://dapr.github.io/helm-charts/\nhelm repo add bitnami https://charts.bitnami.com/bitnami\nhelm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts\nhelm repo add ratify https://notaryproject.github.io/ratify\nhelm repo update\n"})}),"\n",(0,t.jsx)(a.h3,{id:"install-dapr",children:"Install Dapr"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"helm upgrade --install dapr dapr/dapr --namespace dapr-system --create-namespace --wait\n"})}),"\n",(0,t.jsx)(a.h3,{id:"install-gatekeeper",children:"Install Gatekeeper"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"helm install gatekeeper/gatekeeper \\\n --name-template=gatekeeper \\\n --namespace gatekeeper-system --create-namespace \\\n --set enableExternalData=true \\\n --set validatingWebhookTimeoutSeconds=5 \\\n --set mutatingWebhookTimeoutSeconds=2 \\\n --set externaldataProviderResponseCac
1heTTL=10s\n"})}),"\n",(0,t.jsx)(a.h3,{id:"install-redis",children:"Install Redis"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:'helm upgrade --install redis bitnami/redis --namespace gatekeeper-system --set image.tag="7.0-debian-11" --wait\n'})}),"\n",(0,t.jsx)(a.p,{children:"Apply dapr state store encyrption secret using a generated key:"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"SIGN_KEY=$(openssl rand 16 | hexdump -v -e '/1 \"%02x\"' | base64)\n\ncat <<EOF > dapr-redis-secret.yaml\napiVersion: v1\nkind: Secret\nmetadata:\n name: ratify-dapr-signing-key\ndata:\n signingKey: $SIGN_KEY\nEOF\n\nkubectl apply -f dapr-redis-secret.yaml -n gatekeeper-system\n"})}),"\n",(0,t.jsx)(a.p,{children:"Apply dapr state store Component custom resource:"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"cat <<EOF > dapr-redis.yaml\napiVersion: dapr.io/v1alpha1\nkind: Component\nmetadata:\n name: dapr-redis\nspec:\n type: state.redis\n version: v1\n metadata:\n - name: redisHost\n value: redis-master:6379\n - name: redisPassword\n secretKeyRef:\n name: redis\n key: redis-password\n - name: primaryEncryptionKey\n secretKeyRef:\n name: ratify-dapr-signing-key\n key: signingKey\nauth:\n secretStore: kubernetes\nEOF\n\nkubectl apply -f dapr-redis.yaml -n gatekeeper-system\n"})}),"\n",(0,t.jsx)(a.h3,{id:"install-ratify",children:"Install Ratify"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:'# download the notation verification certificate\ncurl -sSLO https://raw.githubusercontent.com/deislabs/ratify/main/test/testdata/notation.crt\nhelm install ratify \\\n ratify/ratify --atomic \\\n --namespace gatekeeper-system \\\n --set-file notationCerts={./notation.crt} \\\n --set featureFlags.RATIFY_CERT_ROTATION=true \\\n --set featureFlags.RATIFY_DAPR_CACHE_PROVIDER=true \\\n --set replicaCount=3 \\\n --set provider.cache.type="dapr" \\\n --set provider.cache.name="dapr-redis"\n'})}),"\n",(0,t.jsx)(a.h3,{id:"see-ratify-in-action",children:"See Ratify in action"}),"\n",(0,t.jsxs)(a.ul,{children:["\n",(0,t.jsxs)(a.li,{children:["Deploy a ",(0,t.jsx)(a.code,{children:"demo"})," constraint"]}),"\n"]}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"kubectl apply -f https://notaryproject.github.io/ratify/library/default/template.yaml\nkubectl apply -f https://notaryproject.github.io/ratify/library/default/samples/constraint.yaml\n"})}),"\n",(0,t.jsx)(a.p,{children:"Once the installation is completed, you can test the deployment of an image that is signed using notation."}),"\n",(0,t.jsxs)(a.ul,{children:["\n",(0,t.jsxs)(a.li,{children:["This will successfully create the pod ",(0,t.jsx)(a.code,{children:"demo"})]}),"\n"]}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"kubectl run demo --image=ghcr.io/deislabs/ratify/notary-image:signed\nkubectl get pods demo\n"})}),"\n",(0,t.jsxs)(a.p,{children:["Optionally you can see the output of the pod logs via: ",(0,t.jsx)(a.code,{children:"kubectl logs demo"})]}),"\n",(0,t.jsxs)(a.ul,{children:["\n",(0,t.jsx)(a.li,{children:"Now deploy an unsigned image"}),"\n"]}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"kubectl run demo1 --image=ghcr.io/deislabs/ratify/notary-image:unsigned\n"})}),"\n",(0,t.jsx)(a.p,{children:"You will see a deny message from Gatekeeper denying the request to create it as the image doesn't have any signatures."}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:'Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: [ratify-constraint] Subject failed verification: wabbitnetworks.azurecr.io/test/net-monitor:unsigned\n'})}),"\n",(0,t.jsx)(a.p,{children:"You just validated the container images in your k8s cluster!"}),"\n",(0,t.jsx)(a.h3,{id:"uninstall-ratify",children:"Uninstall Ratify"}),"\n",(0,t.jsxs)(a.blockquote,{children:["\n",(0,t.jsx)(a.p,{children:"Note: Helm does NOT support upgrading CRDs, so uninstalling Ratify will require you to delete the CRDs manually. Otherwise, you might fail to install CRDs of newer versions when installing Ratify"}),"\n"]}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"kubectl delete -f https://notaryproject.github.io/ratify/library/default/template.yaml\nkubectl delete -f https://notaryproject.github.io/ratify/library/default/samples/constraint.yaml\nhelm delete ratify --namespace gatekeeper-system\nkubectl delete crd stores.config.ratify.deislabs.io verifiers.config.ratify.deislabs.io certificatestores.config.ratify.deislabs.io policies.config.ratify.deislabs.io\nhelm delete redis --namespace gatekeeper-system\nhelm delete dapr --namespace dapr-system\nkubectl delete Component dapr-redis -n gatekeeper-system\nkubectl delete Secret ratify-dapr-signing-key -n gatekeeper-system\nhelm delete gatekeeper -n gatekeeper-system\n"})}),"\n",(0,t.jsx)(a.h2,{id:"development-testing-with-helmfile-build-your-own-images",children:"Development Testing with Helmfile (build your own images)"}),"\n",(0,t.jsxs)(a.p,{children:["While developing for HA scenarios, the ",(0,t.jsx)(a.code,{children:"dev.high-availability.helmfile.yaml"})," can be useful."]}),"\n",(0,t.jsx)(a.p,{children:"Prerequisites:"}),"\n",(0,t.jsxs)(a.ul,{children:["\n",(0,t.jsx)(a.li,{children:"Install helmfile"}),"\n",(0,t.jsxs)(a.li,{children:["Build your own images (follow instructions ",(0,t.jsx)(a.a,{href:"https://github.com/notaryproject/ratify/blob/main/CONTRIBUTING.md#build-an-image-with-your-local-changes",children:"here"}),")"]}
1),"\n",(0,t.jsxs)(a.li,{children:["Install Ratify + Gatekeeper on cluster with ",(0,t.jsx)(a.code,{children:"dev.helmfile.yaml"})," (follow instructions ",(0,t.jsx)(a.a,{href:"https://github.com/notaryproject/ratify/blob/main/CONTRIBUTING.md#deploy-using-dev-helmfile",children:"here"}),")"]}),"\n"]}),"\n",(0,t.jsxs)(a.h3,{id:"update-devhigh-availabilityhelmfileyaml",children:["Update ",(0,t.jsx)(a.code,{children:"dev.high-availability.helmfile.yaml"})]}),"\n",(0,t.jsxs)(a.p,{children:["Replace ",(0,t.jsx)(a.code,{children:"repository"}),", ",(0,t.jsx)(a.code,{children:"crdRepository"}),", and ",(0,t.jsx)(a.code,{children:"tag"})," with previously built images:"]}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-yaml",children:"- name: image.repository \n value: <YOUR RATIFY IMAGE REPOSITORY NAME>\n- name: image.crdRepository\n value: <YOUR RATIFY CRD IMAGE REPOSITORY NAME>\n- name: image.tag\n value: <YOUR IMAGES TAG NAME>\n"})}),"\n",(0,t.jsx)(a.p,{children:"Deploy to cluster:"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-bash",children:"helmfile sync -f dev.high-availability.helmfile.yaml\n"})})]})}function h(e={}){const{wrapper:a}={...(0,l.R)(),...e.components};return a?(0,t.jsx)(a,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.