1"use strict";(globalThis.webpackChunkd7y_io||=[]).push([[14714],{71089(e,n,r){r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"setup/install/helm-charts","title":"Helm Charts","description":"Now we can deploy all components of Dragonfly in","source":"@site/versioned_docs/version-v2.0.5/setup/install/helm-charts.md","sourceDirName":"setup/install","slug":"/setup/install/helm-charts","permalink":"/docs/v2.0.5/setup/install/helm-charts","draft":false,"unlisted":false,"editUrl":"https://github.com/dragonflyoss/d7y.io/edit/main/docs/setup/install/helm-charts.md","tags":[],"version":"v2.0.5","lastUpdatedBy":"Josh Soref","lastUpdatedAt":1773306083000,"frontMatter":{"id":"helm-charts","title":"Helm Charts"},"sidebar":"docs","previous":{"title":"Kubernetes","permalink":"/docs/v2.0.5/getting-started/quick-start/kubernetes/"},"next":{"title":"Docker Compose","permalink":"/docs/v2.0.5/getting-started/quick-start/docker-compose/"}}');var s=r(74848),a=r(28453);const t={id:"helm-charts",title:"Helm Charts"},l=void 0,o={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Runtime Configuration Guide for Dragonfly Helm Chart",id:"runtime-configuration-guide-for-dragonfly-helm-chart",level:2},{value:"1. Docker",id:"1-docker",level:3},{value:"Case 1: [Preferred] Implicit registries support without restart docker",id:"case-1-preferred-implicit-registries-support-without-restart-docker",level:4},{value:"Case 2: Arbitrary registries support with restart docker",id:"case-2-arbitrary-registries-support-with-restart-docker",level:4},{value:"2. Containerd",id:"2-containerd",level:3},{value:"Case 1: Version 2 config with config_path",id:"case-1-version-2-config-with-config_path",level:4},{value:"Case 2: Version 2 config without config_path",id:"case-2-version-2-config-without-config_path",level:4},{value:"Case 3: Version 1",id:"case-3-version-1",level:4},{value:"3. [WIP] CRI-O",id:"3-wip-cri-o",level:3},{value:"Prepare Kubernetes Cluster",id:"prepare-kubernetes-cluster",level:2},{value:"Install Dragonfly",id:"install-dragonfly",level:2},{value:"Install with default configuration",id:"install-with-default-configuration",level:3},{value:"Install with custom configuration",id:"install-with-custom-configuration",level:3},{value:"Install with an existing manager",id:"install-with-an-existing-manager",level:3},{value:"Wait Dragonfly Ready",id:"wait-dragonfly-ready",level:2},{value:"Manager Console",id:"manager-console",level:2},{value:"Configure Runtime Manually",id:"configure-runtime-manually",level:2},{value:"Using Dragonfly",id:"using-dragonfly",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["Now we can deploy all components of Dragonfly in\nKubernetes cluster. We deploy scheduler and seed peer as ",(0,s.jsx)(n.code,{children:"StatefulSets"}),",\ndaemon as ",(0,s.jsx)(n.code,{children:"DaemonSets"}),", manager as ",(0,s.jsx)(n.code,{children:"Deployments"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Kubernetes cluster 1.20+"}),"\n",(0,s.jsx)(n.li,{children:"Helm v3.8.0+"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"runtime-configuration-guide-for-dragonfly-helm-chart",children:"Runtime Configuration Guide for Dragonfly Helm Chart"}),"\n",(0,s.jsxs)(n.p,{children:["When enable runtime configuration in dragonfly,\nyou can skip ",(0,s.jsx)(n.a,{href:"#configure-runtime-manually",children:"Configure Runtime"})," manually."]}),"\n",(0,s.jsx)(n.h3,{id:"1-docker",children:"1. Docker"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"We did not recommend to using dragonfly\nwith docker in Kubernetes"}),"\ndue to many reasons:\nno fall back image pulling policy.\ndeprecated in Kubernetes.\nBecause the original ",(0,s.jsx)(n.code,{children:"daemonset"})," in\nKubernetes did not support ",(0,s.jsx)(n.code,{children:"Surging Rolling Update"})," policy.\nWhen kill current dfdaemon pod,\nthe new pod image cannot be pulled anymore.\nIf you cannot change runtime from docker to others,\nremind to choose a plan when upgrade dfdaemon:\npull newly dfdaemon image manually before upgrade dragonfly,\nor use ",(0,s.jsx)(n.a,{href:"https://openkruise.io/docs/user-manuals/imagepulljob",children:"ImagePullJob"})," to\npull image automate.\nkeep the image registry of dragonfly is\ndifferent from common registries and add host in ",(0,s.jsx)(n.code,{children:"containerRuntime.docker.skipHosts"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Dragonfly helm supports config docker automatically."}),"\n",(0,s.jsx)(n.p,{children:"Config cases:"}),"\n",(0,s.jsx)(n.h4,{id:"case-1-preferred-implicit-registries-support-without-restart-docker",children:"Case 1: [Preferred] Implicit registries support without restart docker"}),"\n",(0,s.jsx)(n.p,{children:"Chart customize values.yaml:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"containerRuntime:\n docker:\n enable: true\n # -- Inject domains into /etc/hosts to force redirect traffic to dfdaemon.\n # Caution: This feature need dfdaemon to implement SNI Proxy, confirm image tag is greater than v2.0.0.\n # When use certs and inject hosts in docker, no necessary to restart docker daemon.\n injectHosts: true\n registryDomains:\n - 'harbor.example.com'\n - 'harbor.example.net'\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This config enables docker pulling images from\nregistries ",(0,s.jsx)(n.code,{children:"harbor.example.com"})," and ",(0,s.jsx)(n.code,{children:"harbor.example.net"})," via Dragonfly.\nWhen deploying Dragonfly with above config,\nit's unnecessary to restart docker daemon."]}),"\n",(0,s.jsx)(n.p,{children:"Advantages:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Support upgrade dfdaemon smoothness"}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["In this mode, when dfdaemon pod deleted,\nthe ",(0,s.jsx)(n.code,{children:"preStop"})," hook will remove all injected hosts info in /etc/hosts,\nall images traffic falls back to original registries."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Limitations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Only support implicit registries"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"case-2-arbitrary-registries-support-with-restart-docker",children:"Case 2: Arbitrary registries support with restart docker"}),"\n",(0,s.jsx)(n.p,{children:"Chart customize values.yaml:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"containerRuntime:\n docker:\n enable: true\n # -- Restart docker daemon to redirect traffic to dfdaemon\n # When containerRuntime.docker.restart=true, containerRuntime.docker.injectHosts and containerRuntime.registry.domains is ignored.\n # If did n
1ot want restart docker daemon, keep containerRuntime.docker.restart=false and containerRuntime.docker.injectHosts=true.\n restart: true\n skipHosts:\n - '127.0.0.1'\n - 'docker.io' # Dragonfly use this image registry to upgrade itself, so we need skip it. Change it in real environment.\n"})}),"\n",(0,s.jsx)(n.p,{children:"This config enables docker pulling images from arbitrary registries via Dragonfly.\nWhen deploying Dragonfly with above config, dfdaemon will restart docker daemon."}),"\n",(0,s.jsx)(n.p,{children:"Advantages:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Support arbitrary registries"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Limitations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Must enable live-restore feature in docker"}),"\n",(0,s.jsx)(n.li,{children:"Need restart docker daemon"}),"\n",(0,s.jsx)(n.li,{children:"When upgrade dfdaemon, new image must be pulled beforehand."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"2-containerd",children:"2. Containerd"}),"\n",(0,s.jsx)(n.p,{children:"The config of containerd has two version with complicated fields.\nThese are many cases to consider:"}),"\n",(0,s.jsx)(n.h4,{id:"case-1-version-2-config-with-config_path",children:"Case 1: Version 2 config with config_path"}),"\n",(0,s.jsxs)(n.p,{children:["There is ",(0,s.jsx)(n.code,{children:"config_path"})," in ",(0,s.jsx)(n.code,{children:"/etc/containerd/config.toml"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[plugins."io.containerd.grpc.v1.cri".registry]\n config_path = "/etc/containerd/certs.d"\n'})}),"\n",(0,s.jsx)(n.p,{children:"This case is very simple to enable multiple registry mirrors support."}),"\n",(0,s.jsx)(n.p,{children:"Chart customize values.yaml:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"containerRuntime:\n containerd:\n enable: true\n"})}),"\n",(0,s.jsx)(n.h4,{id:"case-2-version-2-config-without-config_path",children:"Case 2: Version 2 config without config_path"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Option 1 - Allow charts to inject config_path and restart containerd."}),"\n",(0,s.jsx)(n.p,{children:"This option also enable multiple registry mirrors support."}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["Caution: if there are already many other mirror config in config.toml,\nshould not use this option, or migrate your config with ",(0,s.jsx)(n.code,{children:"config_path"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Chart customize values.yaml:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"containerRuntime:\n containerd:\n enable: true\n injectConfigPath: true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Option 2 - Just mirror only one registry\nwhich ",(0,s.jsx)(n.code,{children:"dfdaemon.config.proxy.registryMirror.url"})," is Chart customize values.yaml:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"containerRuntime:\n containerd:\n enable: true\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"case-3-version-1",children:"Case 3: Version 1"}),"\n",(0,s.jsxs)(n.p,{children:["With version 1 config.toml, only support\nthe registry which ",(0,s.jsx)(n.code,{children:"dfdaemon.config.proxy.registryMirror.url"})," is."]}),"\n",(0,s.jsx)(n.p,{children:"Chart customize values.yaml:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"containerRuntime:\n containerd:\n enable: true\n"})}),"\n",(0,s.jsx)(n.h3,{id:"3-wip-cri-o",children:"3. [WIP] CRI-O"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"DON'T USE, Work in progress"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Dragonfly helm supports config CRI-O automatically with drop-in registries."}),"\n",(0,s.jsx)(n.p,{children:"Chart customize values.yaml:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"containerRuntime:\n crio:\n # -- Enable CRI-O support\n # Inject drop-in mirror config into /etc/containers/registries.conf.d.\n enable: true\n # Registries full urls\n registries:\n - 'https://ghcr.io'\n - 'https://quay.io'\n - 'https://harbor.example.com:8443'\n"})}),"\n",(0,s.jsx)(n.h2,{id:"prepare-kubernetes-cluster",children:"Prepare Kubernetes Cluster"}),"\n",(0,s.jsxs)(n.p,{children:["If there is no available Kubernetes cluster for testing,\n",(0,s.jsx)(n.a,{href:"https://minikube.sigs.k8s.io/docs/start/",children:"minikube"})," is\nrecommended. Just run ",(0,s.jsx)(n.code,{children:"minikube start"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"install-dragonfly",children:"Install Dragonfly"}),"\n",(0,s.jsx)(n.h3,{id:"install-with-default-configuration",children:"Install with default configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"helm repo add dragonfly https://dragonflyoss.github.io/helm-charts/\nhelm install --create-namespace --namespace dragonfly-system dragonfly dragonfly/dragonfly\n"})}),"\n",(0,s.jsx)(n.h3,{id:"install-with-custom-configuration",children:"Install with custom configuration"}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:"values.yaml"})," configuration file.\nIt is recommended to use external redis and mysql instead of containers."]}),"\n",(0,s.jsxs)(n.p,{children:["The example uses external mysql and redis.\nRefer to the document for\n",(0,s.jsx)(n.a,{href:"https://artifacthub.io/packages/helm/dragonfly/dragonfly#values",children:"configuration"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"mysql:\n enable: false\n\nexternalMysql:\n migrate: true\n host: mysql-host\n username: dragonfly\n password: dragonfly\n database: manager\n port: 3306\n\nredis:\n enable: false\n\nexternalRedis:\n host: redis-host\n password: dragonfly\n port: 6379\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Install dragonfly with ",(0,s.jsx)(n.code,{children:"values.yaml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"helm repo add dragonfly https://dragonflyoss.github.io/helm-charts/\nhelm install --create-namespace --namespace dragonfly-system \\\n dragonfly dragonfly/dragonfly -f values.yaml\n"})}),"\n",(0,s.jsx)(n.h3,{id:"install-with-an-existing-manager",children:"Install with an existing manager"}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:"values.yaml"})," configuration file.\nNeed to configure the cluster id associated with scheduler and seed peer."]}),"\n",(0,s.jsxs)(n.p,{children:["The example is to deploy a cluster using the existing manager and redis.\nRefer to the document for ",(0,s.jsx)(n.a,{href:"https://artifacthub.io/packages/helm/dragonfly/dragonfly#values",children:"configuration"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"scheduler:\n config:\n manager:\n schedulerClusterID: 1\n\nseedPeer:\n config:\n scheduler:\n manager:\n seedPeer:\n clusterID: 1\n\nmanager:\n enable: false\n\nexternalManager:\n enable: true\n host: 'dragonfly-manager.dragonfly-system.svc.cluster.local'\n restPort: 8080\n grpcPort: 65003\n\nredis:\n enable: false\n\nexternalRedis:\n host: redis-host\n password: dragonfly\n port: 6379\n\nmysql:\n enable: false\n"})}),"\n",(0,s.jsx)(n.h2,{id:"wait-dragonfly-ready",children:"Wait Dragonfly Ready"}),"\n",(0,s.jsx)(n.p,{children:"Wait all pods running"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl -n dragonfly-system wait --for=condition=ready --all --timeout=10m pod\n"})}),"\n",(0,s.jsx)(n.h2,{id:"manager-console",children:"Manager Console"}),"\n",(0,s.jsxs)(n.p,{children:["The console page will be displayed on ",(0,s.jsx)(n.code,{children:"dragonfly-manager.dragonfly-system.svc.cluster.local:8080"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If you need to bind Ingress, you can refer to\n",(0,s.jsx)(n.a,{href:"https://artifacthub.io/packages/helm/dragonfly/dragonfly#values",children:"configuration options"}),"\nof Helm Charts, or create it manually."]}),"\n",(0,s.jsxs)(n.p,{children:["Console features preview reference document ",(0,s.jsx)(n.a,{href:"/docs/v2.0.5/reference/manage-console",children:"console preview"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"configure-runtime-manually",children:"Configure Runtime Manually"}
1),"\n",(0,s.jsxs)(n.p,{children:["Use Containerd with CRI as example, ",(0,s.jsx)(n.a,{href:"/docs/v2.0.5/getting-started/quick-start/kubernetes/",children:"more runtimes are available"})]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["This example is for single registry, you can also ",(0,s.jsx)(n.a,{href:"/docs/v2.0.5/setup/runtime/containerd/",children:"configure multiple registries"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For private registry:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'# explicitly use v2 config format, if already v2, skip the "version = 2"\nversion = 2\n[plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.example.com"]\nendpoint = ["http://127.0.0.1:65001", "https://harbor.example.com"]\n'})}),"\n",(0,s.jsx)(n.p,{children:"For docker public registry:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'# explicitly use v2 config format, if already v2, skip the "version = 2"\nversion = 2\n[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\nendpoint = ["http://127.0.0.1:65001", "https://index.docker.io"]\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Add above config to ",(0,s.jsx)(n.code,{children:"/etc/containerd/config.toml"})," and restart Containerd"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"systemctl restart containerd\n"})}),"\n",(0,s.jsx)(n.h2,{id:"using-dragonfly",children:"Using Dragonfly"}),"\n",(0,s.jsxs)(n.p,{children:["After all above steps, create a new pod with\ntarget registry. Or just pull an image with ",(0,s.jsx)(n.code,{children:"crictl"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"crictl harbor.example.com/library/alpine:latest\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"crictl pull docker.io/library/alpine:latest\n"})}),"\n",(0,s.jsx)(n.p,{children:"After pulled images, find logs in dfdaemon pod:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'# find pods\nkubectl -n dragonfly-system get pod -l component=dfdaemon\n# find logs\npod_name=dfdaemon-xxxxx\nkubectl -n dragonfly-system exec -it ${pod_name} -- grep "peer task done" /var/log/dragonfly/daemon/core.log\n'})}),"\n",(0,s.jsx)(n.p,{children:"Example output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'{\n "level": "info",\n "ts": "2022-09-07 12:04:26.485",\n "caller": "peer/peertask_conductor.go:1500",\n "msg": "peer task done, cost: 1ms",\n "peer": "10.140.2.175-5184-1eab18b6-bead-4b9f-b055-6c1120a30a33",\n "task": "b423e11ddb7ab19a3c2c4c98e5ab3b1699a597e974c737bb4004edeef6016ed2",\n "component": "PeerTask"\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453(e,n,r){r.d(n,{R:()=>t,x:()=>l});var i=r(96540);const s={},a=i.createContext(s);function t(e){const n=i.useContext(a);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]);
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.