मैन्युअल परिनियोजन त्रुटि-प्रवण नहीं हैं। इसके अलावा, उनमें दोहराए जाने वाले और जटिल कार्यों का एक समूह शामिल है। विकास दल किसी एप्लिकेशन के नए संस्करण को तैनात करने की जटिलता और इससे होने वाले सिरदर्द से डरते हैं। कभी-कभी, किसी एप्लिकेशन को तैनात करने के लिए उन्नत प्लेटफ़ॉर्म कौशल की आवश्यकता होती है। परिनियोजन समस्याओं को डीबग करना एक कठिन प्रक्रिया है।
फ्लक्ससीडी आपको मैन्युअल और दोहराव वाले कार्यों के लिए समर्पित प्रयास को कम करने में मदद करता है। यह परिनियोजन त्रुटियों और मानवीय अंतःक्रियाओं को भी कम करता है। यह घोषणात्मक फ़ाइलों का उपयोग करके आपकी तैनाती की स्थिति को ट्रैक करने और अपडेट करने के लिए उपकरण प्रदान करता है, जिससे आपकी विकास टीमों के लिए तैनाती और डिबगिंग प्रक्रिया आसान हो जाती है।
यह आलेख आपकी परिनियोजन प्रक्रियाओं के स्वचालन की पड़ताल करता है ताकि उन्हें फ्लक्ससीडी , फ्लैगर और ग्राफाना का उपयोग करके निरंतर परिनियोजन प्रक्रियाओं में परिवर्तित किया जा सके।
किसी एप्लिकेशन को लगातार वितरित करने के बारे में अधिक जानने के लिए पहला लेख देखें:
सीआई/सीडी व्यावहारिक: एक सरल लेकिन कार्यात्मक सतत एकीकरण वर्कफ़्लो [भाग 1]।
GitHub उदाहरण: https://github.com/joan-mido-qa/continous-deployment-example
कुबेरनेट्स क्लस्टर स्थापित करने के लिए KinD और टेराफॉर्म का उपयोग करें। सबसे पहले, क्लस्टर बनाएं और कुबेरनेट्स प्रदाता को सेट करने के लिए कुबेरनेट्स कॉन्फ़िगरेशन को निर्यात करें:
$ kind create cluster --name develop $ kind export kubeconfig --name develop --kubeconfig kubeconfig
एक नया GitHub रिपॉजिटरी और रिपॉजिटरी अनुमतियों के साथ एक डेवलपर टोकन बनाएं, टेराफोम को फ्लक्ससीडी सेटअप करने की आवश्यकता होती है। टेराफ़ॉर्म प्रारंभ करें और परिवर्तन लागू करें:
$ terraform init $ terraform apply -var="github_owner=owner_name" -var="github_repository=repo_name" # Introduce your GitHub token
एक बार जब टेराफॉर्म इंस्टॉलेशन प्रक्रिया पूरी कर लेता है, तो आपके KinD क्लस्टर में फ्लक्ससीडी चलनी चाहिए और आपके रिपॉजिटरी में क्लस्टर नामक एक नया फ़ोल्डर होना चाहिए।
हुड के तहत, टेराफॉर्म मेटलएलबी स्थापित करता है और आईपी रेंज को कॉन्फ़िगर करता है। आप लेख के पहले भाग में मेटलएलबी कॉन्फ़िगरेशन के बारे में अधिक पढ़ सकते हैं:
resource "helm_release" "metallb" { name = "metallb" repository = "https://metallb.github.io/metallb" chart = "metallb" } data "docker_network" "kind" { name = "kind" } resource "kubectl_manifest" "kind-address-pool" { yaml_body = yamlencode({ "apiVersion" : "metallb.io/v1beta1", "kind" : "IPAddressPool", "metadata" : { "name" : "kind-address-pool" }, "spec" : { "addresses" : [replace(tolist(data.docker_network.kind.ipam_config)[0].subnet, ".0.0/16", ".255.0/24")] } }) depends_on = [helm_release.metallb] } resource "kubectl_manifest" "kind-advertisement" { yaml_body = <<YAML apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: kind-advertisement YAML depends_on = [helm_release.metallb] }
फिर, यह FLuxCD हेल्म चार्ट स्थापित करता है और फ्लक्ससीडी का उपयोग करने के लिए GitHub रिपॉजिटरी को कॉन्फ़िगर करता है:
resource "helm_release" "flux" { repository = "https://fluxcd-community.github.io/helm-charts" chart = "flux2" name = "flux2" namespace = "flux-system" create_namespace = true version = "2.9.2" } resource "tls_private_key" "flux" { depends_on = [helm_release.flux] algorithm = "ECDSA" ecdsa_curve = "P256" } resource "github_repository_deploy_key" "flux" { depends_on = [tls_private_key.flux] title = "Flux" repository = var.github_repository key = tls_private_key.flux.public_key_openssh read_only = "false" } resource "flux_bootstrap_git" "this" { depends_on = [github_repository_deploy_key.flux] path = "clusters/develop" }
प्री-कमिट हुक सुझाव:
फ्लक्ससीडी कुबेरनेट्स क्लस्टर को नवीनतम स्रोत नियंत्रण परिवर्तनों (जैसे गिट रिपॉजिटरी) के साथ रखने के लिए एक GitOps उपकरण है। फ़्लक्स नए कोड की तैनाती को स्वचालित करता है।
एक बार जब फ्लक्स क्लस्टर में चल रहा हो, तो आइए देखें कि यह कैसे काम करता है। हम ingress-nginx को एक ingress प्रदाता के रूप में तैनात करेंगे। फ्लक्स प्रोजेक्ट फ़ोल्डर संरचना को लागू नहीं करता है। आप इसे अपनी इच्छानुसार कॉन्फ़िगर कर सकते हैं या अपने पसंदीदा मानक का पालन कर सकते हैं।
इंफ्रास्ट्रक्चर नाम के फोल्डर के अंदर आधार नाम का फोल्डर बनाएं। बेस फ़ोल्डर में आपके सभी क्लस्टर के लिए बुनियादी ढांचागत कॉन्फ़िगरेशन है। इसके बाद, ingress-nginx नाम का एक फोल्डर बनाएं। फ़ोल्डर नाम के रूप में नेमस्पेस नाम का उपयोग करें।
--- apiVersion: v1 kind: Namespace metadata: name: ingress-ngnix --- apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: name: ingress-nginx spec: interval: 2h url: https://kubernetes.github.io/ingress-nginx --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: ingress-nginx spec: interval: 15m chart: spec: chart: ingress-nginx version: 4.7.1 sourceRef: kind: HelmRepository name: ingress-nginx interval: 15m --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: ingress-ngnix resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml
अपने ऑब्जेक्ट को परिभाषित करने के लिए एकाधिक फ़ाइलों का उपयोग करें: hemrelease.yaml , hemrepository.yaml , namespace.yaml , kustomization.yaml , आदि।
अनुकूलन संसाधनों को पढ़ता है और उन्हें लागू करने के लिए संसाधित करता है। अंतिम लेकिन महत्वपूर्ण बात, आपको अपने क्लस्टर कॉन्फ़िगरेशन को सिंक्रनाइज़ करने के लिए एक अनुकूलन ऑब्जेक्ट बनाने की आवश्यकता है। क्लस्टर/क्लस्टर_नाम फ़ोल्डर के अंदर इंफ्रास्ट्रक्चर. yaml नामक एक YAML फ़ाइल बनाएं:
--- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: infra-base namespace: flux-system spec: interval: 1h retryInterval: 1m timeout: 5m sourceRef: kind: GitRepository name: flux-system path: ./infrastructure/base prune: true wait: true
आपके परिवर्तनों को आपके रिपॉजिटरी में भेजने और भेजने के बाद, फ्लक्स इनग्रेस-नेगनेक्स हेल्म चार्ट को स्थापित करने के लिए क्लस्टर स्थिति का मिलान करेगा।
फ़्लैगर एक कुबेरनेट्स ऑपरेटर है जो नीले/हरे परिनियोजन, कैनरी रिलीज़, या ए/बी परीक्षण का उपयोग करके आपके एप्लिकेशन को उत्तरोत्तर वितरित करता है।
आप अपने स्टैक को अपने सभी क्लस्टरों में स्थापित करने के लिए बेस फ़ोल्डर का उपयोग कर सकते हैं या क्लस्टर के आधार पर अपने इंस्टॉलेशन को अनुकूलित करने के लिए किसी भिन्न फ़ोल्डर का उपयोग कर सकते हैं। उदाहरण के लिए, हम फ़्लैगर को केवल विकास क्लस्टर में स्थापित करना चाहते हैं।
इंफ्रास्ट्रक्चर फ़ोल्डर के अंदर अपने क्लस्टर नाम का उपयोग करके एक नया फ़ोल्डर बनाएं। फिर, अपने क्लस्टर/क्लस्टर_नाम में i nfrastructure.yaml नाम की एक फ़ाइल बनाएं:
--- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: infra-cluster-name namespace: flux-system spec: dependsOn: - name: infra-base interval: 1h retryInterval: 1m timeout: 5m sourceRef: kind: GitRepository name: flux-system path: ./infrastructure/cluster_name prune: true
फ़्लक्ससीडी इन्फ्रा-बेस कस्टमाइज़ेशन लागू करने के बाद क्लस्टर स्थिति को सिंक्रनाइज़ करेगा। फ़्लैगर स्थापित करें, इंफ्रास्ट्रक्चर/क्लस्टर_नाम/फ़्लैगर-सिस्टम फ़ोल्डर के अंदर निम्न YAML फ़ाइल बनाएं:
--- apiVersion: v1 kind: Namespace metadata: name: flagger-system --- apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: flagger spec: interval: 1h url: https://flagger.app --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: flagger spec: interval: 1h install: crds: CreateReplace upgrade: crds: CreateReplace chart: spec: chart: flagger version: 1.xx interval: 6h sourceRef: kind: HelmRepository name: flagger --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: flagger-loadtester spec: interval: 1h chart: spec: chart: loadtester version: 0.xx interval: 6h sourceRef: kind: HelmRepository name: flagger --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: flagger-system resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml
पॉडइन्फो एप्लिकेशन निरंतर परिनियोजन पाइपलाइन बनाने के लिए, ऐप्स/क्लस्टर_नाम/पॉडइन्फो में इंस्टॉलेशन YAML फ़ाइल बनाएं *:*
--- apiVersion: v1 kind: Namespace metadata: name: podinfo --- apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: podinfo spec: interval: 5m url: https://stefanprodan.github.io/podinfo --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: podinfo spec: releaseName: podinfo chart: spec: chart: podinfo version: 6.5.0 sourceRef: kind: HelmRepository name: podinfo interval: 50m install: remediation: retries: 3 values: ingress: enabled: true className: nginx hpa: enabled: true --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml
आप अपने स्थानीय परिवेश होस्ट को अपडेट करने के लिए अपडेट होस्ट पायथन स्क्रिप्ट का उपयोग कर सकते हैं, जैसा कि लेख के पहले भाग में बताया गया है।
फिर, अपने ऐप्स को सिंक्रनाइज़ करने के लिए क्लस्टर/क्लस्टर_नाम फ़ोल्डर में अनुकूलन फ़ाइल बनाएं:
--- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: apps namespace: flux-system spec: interval: 10m0s dependsOn: - name: infra-cluster-name sourceRef: kind: GitRepository name: flux-system path: ./apps/cluster_name prune: true wait: true timeout: 5m0s
इसके बाद, हम पॉडिनफो इमेज हेल्म चार्ट संस्करण को ऑटो-अपडेट करने के लिए फ्लक्ससीडी को कॉन्फ़िगर कर सकते हैं। छवि ऑटो-अपडेट को कॉन्फ़िगर करने के लिए, हमें नई छवि टैग को स्कैन करने के लिए एक छवि रिपॉजिटरी, अपडेट करने के लिए संस्करण पैटर्न को परिभाषित करने के लिए एक छवि अपडेट नीति और परिवर्तन को आगे बढ़ाने के लिए रिपॉजिटरी को कॉन्फ़िगर करने के लिए एक छवि ऑटो-अपडेट बनाने की आवश्यकता है।
--- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImageRepository metadata: name: podinfo-chart spec: image: ghcr.io/stefanprodan/charts/podinfo interval: 5m --- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImagePolicy metadata: name: podinfo-chart spec: imageRepositoryRef: name: podinfo-chart policy: semver: range: 6.xx --- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImageUpdateAutomation metadata: name: podinfo-chart spec: interval: 30m sourceRef: kind: GitRepository name: flux-system namespace: flux-system git: checkout: ref: branch: main commit: author: email: [email protected] name: fluxcdbot messageTemplate: 'chore(develop): update podinfo chart to {{range .Updated.Images}}{{println .}}{{end}}' push: branch: main update: path: ./apps/cluster_name/podinfo strategy: Setters --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - imagepolicy.yaml - imagerepository.yaml - imageautoupdate.yaml
अंत में, जिस छवि या टैग को आप अपडेट करना चाहते हैं, उस पर छवि अद्यतन नीति लागू करें:
apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: podinfo spec: releaseName: podinfo chart: spec: chart: podinfo version: 6.5.0 # {"$imagepolicy": "podinfo:podinfo-chart:tag"} sourceRef: kind: HelmRepository name: podinfo interval: 50m install: remediation: retries: 3
जब भी पॉडिनफो चार्ट में 6.xx की रेंज में एक नया संस्करण होगा, तो फ्लक्ससीडी रिपॉजिटरी में एक प्रतिबद्धता को आगे बढ़ाएगा, वर्तमान संस्करण को नए के साथ अपडेट करेगा।
यह सुनिश्चित करने के लिए कि एप्लिकेशन की कार्यक्षमता, प्रदर्शन और सुरक्षा अपेक्षित हैं, उपयोगकर्ताओं के एक छोटे उपसमूह के लिए एक नया एप्लिकेशन संस्करण जारी करें। फ्लक्ससीडी स्वचालित रूप से चार्ट संस्करण को अपडेट करता है और इसे उपयोगकर्ताओं के लिए उपलब्ध कराता है। विफलता की स्थिति में, फ्लक्ससीडी स्वचालित रूप से छवि संस्करण को पिछले संस्करण में रोलबैक कर देता है।
फ़्लैगर उत्तरोत्तर उपयोगकर्ताओं के एक उपसमूह को नया एप्लिकेशन संस्करण वितरित करता है और एप्लिकेशन की स्थिति पर नज़र रखता है। यह नए एप्लिकेशन संस्करणों के लिए एक नया परिनियोजन बनाता है और आने वाले ट्रैफ़िक को नए परिनियोजन पर उत्तरोत्तर पुनर्निर्देशित करता है। यह मेट्रिक्स के सफल विश्लेषण के बाद कैनरी तैनाती को बढ़ावा देगा। विफलता की स्थिति में, फ़्लैगर नए परिनियोजन को हटा देता है और ट्रैफ़िक प्रवाह को पुराने परिनियोजन पर पुनः स्थापित कर देता है। यह प्रक्रिया अपने सभी उपयोगकर्ताओं तक एप्लिकेशन पहुंचाने से पहले दोषों, समस्याओं और त्रुटियों का पता लगाने का दिखावा करती है।
सबसे पहले, फ़्लैगर को यह बताने के लिए एक मीट्रिक टेम्पलेट बनाएं कि आवेदन की स्थिति क्या है। अनुरोध सफलता दर मापने के लिए हम प्रोमेथियस का उपयोग करते हैं:
--- apiVersion: flagger.app/v1beta1 kind: MetricTemplate metadata: name: podinfo-request-success-rate spec: provider: type: prometheus address: http://loki-stack-prometheus-server.loki-stack:80 query: | 100 - sum( rate( http_requests_total{ app_kubernetes_io_name="podinfo", namespace="{{ namespace }}", status!~"5.*" }[{{ interval }}] ) ) / sum( rate( http_requests_total{ app_kubernetes_io_name="podinfo", namespace="{{ namespace }}", }[{{ interval }}] ) ) * 100 --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - metrictemplate.yaml
फिर, कैनरी रिलीज़ प्रक्रिया को परिभाषित करें। हम आने वाले ट्रैफ़िक को आकार देने के लिए प्रदाता के रूप में nginx का उपयोग करते हैं। फ़्लैगर आपकी रिलीज़ को कॉन्फ़िगर करने के लिए कई तरीके और टूल प्रदान करता है।
--- apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo spec: provider: nginx targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo ingressRef: apiVersion: networking.k8s.io/v1 kind: Ingress name: podinfo autoscalerRef: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler name: podinfo progressDeadlineSeconds: 60 service: port: 9898 targetPort: 9898 analysis: interval: 10s threshold: 10 maxWeight: 50 stepWeight: 5 metrics: - name: podinfo-request-success-rate thresholdRange: min: 99 interval: 1m webhooks: - name: acceptance-test type: pre-rollout url: http://flagger-loadtester.flagger-system/ timeout: 30s metadata: type: bash cmd: curl -sd 'test' http://podinfo-canary.podinfo:9898/token | grep token - name: load-test url: http://flagger-loadtester.flagger-system/ timeout: 5s metadata: cmd: hey -z 1m -q 10 -c 2 http://podinfo-canary.podinfo:9898/healthz --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - canary.yaml
फ़्लैगर को आपके परिनियोजन, प्रवेश और पॉड ऑटो-एस्केलर के संदर्भ की आवश्यकता होती है। जब भी फ़्लैगर एक नए संस्करण का पता लगाता है, तो यह तैनाती को बढ़ाएगा, एक प्राथमिक और माध्यमिक सेवा बनाएगा, और आने वाले ट्रैफ़िक को संबंधित सेवा में भेजने के लिए nginx को कॉन्फ़िगर करेगा। अधिकतम ट्रैफ़िक पुनर्निर्देशन प्रतिशत और वृद्धिशील चरण प्रतिशत को कॉन्फ़िगर करने के लिए मैक्सवेट और स्टेपवेट गुणों का उपयोग करें।
फ़्लैगर हुक का उपयोग करके अपने एप्लिकेशन को लोड-परीक्षण करें। इसमें कई हुक हैं. स्वीकृति हुक कैनरी परिनियोजन तत्परता की जांच करते हैं, और लोड परीक्षण हुक निरंतर आने वाले ट्रैफ़िक उत्पन्न करता है।
फ़्लैगर कैनरी परिनियोजन पदोन्नति मामले पर निर्णय लेने के लिए पूर्व-निर्धारित सफलता दर मीट्रिक का उपयोग करके कैनरी रिलीज़ स्थिति की निगरानी करेगा। फ़्लैगर को कैनरी परिनियोजन को बढ़ावा देने के लिए 99% अनुरोध सफलता दर की उम्मीद है। रोलबैक से पहले विफल मीट्रिक जांचों की अधिकतम संख्या को कॉन्फ़िगर करने के लिए थ्रेशोल्ड प्रॉपर्टी का उपयोग करें।
ग्राफाना + लोकी + प्रोमेथियस का उपयोग करके क्लस्टर संसाधनों की स्थिति की निगरानी के लिए लोकी स्टैक का उपयोग करें। इंफ्रास्ट्रक्चर/क्लस्टर_नाम/लोकी-स्टैक फ़ोल्डर के अंदर निम्नलिखित YAML फ़ाइल बनाकर लोकी स्टैक स्थापित करें:
--- apiVersion: v1 kind: Namespace metadata: name: loki-stack --- apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: name: grafana spec: interval: 2h url: https://grafana.github.io/helm-charts --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: loki-stack spec: interval: 1h chart: spec: chart: loki-stack version: v2.9.11 sourceRef: kind: HelmRepository name: grafana interval: 1h values: grafana: enabled: true ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx hosts: - grafana.local prometheus: enabled: true nodeExporter: enabled: true --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: loki-stack resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml
लोकी स्टैक इंस्टॉलेशन ग्राफाना इंग्रेस को ग्राफाना, प्रोमेथियस को आपके पर्यावरण मेट्रिक्स को इकट्ठा करने और नोड एक्सपोर्टर को आपके नोड मेट्रिक्स को निर्यात करने में सक्षम बनाता है।
आप अपने स्थानीय परिवेश होस्ट को अपडेट करने के लिए अपडेट होस्ट पायथन स्क्रिप्ट का उपयोग कर सकते हैं, जैसा कि लेख के पहले भाग में बताया गया है
व्यवस्थापक उपयोगकर्ता नाम और पासवर्ड का उपयोग करके ग्राफाना में लॉग इन करें। आप इंस्टॉलेशन मानों का उपयोग करके व्यवस्थापक पासवर्ड परिभाषित कर सकते हैं। डिफ़ॉल्ट रूप से, चार्ट एक यादृच्छिक पासवर्ड संग्रहीत करने के लिए एक कुबेरनेट्स रहस्य बनाता है। बेस64 पासवर्ड मान प्राप्त करने और उसे डिकोड करने के रहस्य का वर्णन करें।
आप अपने पसंदीदा डैशबोर्ड को उनकी आईडी का उपयोग करके या कच्चे JSON की प्रतिलिपि बनाकर आयात कर सकते हैं:
पहले लेख में यह पता लगाया गया कि एक अच्छी तरह से परीक्षण किया गया एप्लिकेशन कैसे वितरित किया जाए। यह आलेख बताता है कि डिलिवरेबल को लगातार कैसे तैनात किया जाए और तैनाती की स्थिति की निगरानी कैसे की जाए।
फ्लक्ससीडी और फ्लैगर आपके एप्लिकेशन की स्थिति का लगातार परीक्षण, तैनाती और निगरानी करने के लिए कई सुविधाएँ प्रदान करते हैं। यह आलेख उनमें से कुछ का उपयोग करता है, लेकिन हमने वेबहुक और अधिसूचना सुविधाएं नहीं देखीं। यह जानने के लिए अधिसूचना सुविधाओं का उपयोग करें कि कोई तैनाती कब विफल हुई या नए वातावरण में तैनाती को बढ़ावा देने या नए संस्करणों के खिलाफ अपने परीक्षण लॉन्च करने के लिए वेब-हुक सुविधा का उपयोग करें। अपनी परिनियोजन पाइपलाइन को समृद्ध करने के लिए फ़्लक्ससीडी को अन्य उपकरणों के साथ एकीकृत करें।
मैन्युअल तैनाती से बचें. वे जटिल हैं और त्रुटि-प्रवण नहीं हैं। विकास टीमों को अपने अनुप्रयोगों को बनाए रखने के लिए प्रोत्साहित करें, जिससे तैनाती प्रक्रिया आसान हो जाएगी। स्वचालित तैनाती से लीड समय, फीडबैक लूप और समग्र लागत कम हो जाती है। डेवलपर्स उस पर ध्यान केंद्रित कर सकते हैं जो वास्तव में मायने रखता है।