介绍

本指南将引导您在 Kubernetes 集群上设置渐进式交付 GitOps 管道。

GitOps 是什么?

GitOps 是一种进行持续交付的方法,它通过将 Git 用作声明性基础结构和工作负载的真实来源来工作。对于 Kubernetes,这意味着使用 git push 代替 kubectl create/apply 或者 kubectl create/apply

GitOps vs CiOps 在传统的 CI/CD 管道中,CD 是由持续集成工具支持的实现扩展,用于将构建工件升级到生产环境。在 GitOps 管道模型中,对生产的任何更改必须先在源代码管理中提交(最好通过拉取请求),然后再应用于集群。如果整个生产状态受版本控制并在单个Git 存储库中进行描述,则在灾难发生时,可以快速恢复整个基础架构,而无需重新运行 CI 管道。

Kubernetes 反模式:让我们做 GitOps,而不是 CIOps!

为了将 GitOps 模型应用到 Kubernetes 上,你需要做三件事:

  • 一个 Git 存储库,其中包含以 YAM 格式定义的工作负载、Helm charts 和定义集群所需状态的任何其他 Kubernetes 自定义资源
  • 一个容器注册中心(registry),CI 系统在其中推送不可变的镜像(没有 latest 标签,使用 语义版本控制 或 git commit sha
  • 一个进行双向同步的 Kubernetes 控制器:
    • 监视配置存储库中的更改并将其应用于您的集群
    • 监视容器 registry(注册中心) 的新映像,并根据部署策略更新工作负载定义。

在本研讨会中,您将使用 GitHub 托管配置存储库,使用 Docker Hub 作为容器注册中心,使用 Flux 作为 GitOps 控制器,并使用 Helm Operator 进行应用程序生命周期管理。

什么是渐进式交付?

渐进式交付是高级部署模式(如金丝雀,功能标记和 A/B 测试)的总称。

通过给予应用程序开发人员和 SRE 团队对爆炸半径的细粒度控制,渐进交付技术被用来降低在生产中引入新软件版本的风险。

使用金丝雀的好处是能够在生产环境中使用发现问题的安全回滚策略对新版本进行容量测试。通过缓慢增加负载,您可以监视和捕获有关新版本如何影响生产环境的指标。

Martin Fowler 博客

在本研讨会中,您将使用

Flagger,

Linkerd

Prometheus

来自动化金丝雀分布 Helm charts。

前提条件

为了安装研讨会的前提条件,您需要一个 Kubernetes 集群(1.13 或更新版本),并支持 负载平衡器RBAC

确保您已经在本地安装了以下工具:

  • kubectl 1.16
  • git 2.20

Helm v3

在 macOS 上安装 Helm v3 CLI:

  1. brew install helm

在 Linux 或 Windows 上,您可以从官方发布页面下载二进制文件。

Git

Fork workshop 仓库并克隆它到本地(使用你的 GitHub 用户名替换 GHUSER):

  1. export GHUSER=stefanprodan
  2. git clone https://github.com/${GHUSER}/gitops-helm-workshop

设置您的 GitHub 用户名和电子邮件:

  1. cd gitops-helm-workshop
  2. git config user.name "${GHUSER}"
  3. git config user.email "your@main.address"

集群状态目录结构:

  1. ├── cluster
  2. ├── canaries
  3. ├── charts
  4.    └── podinfo
  5. ├── namespaces
  6. └── releases

Flux

将 Flux 存储库添加到 Helm 存储库:

  1. helm repo add fluxcd https://charts.fluxcd.io

创建 fluxcd namespace:

  1. kubectl create ns fluxcd

通过提供您的 GitHub 存储库 URL 安装 Flux:

  1. helm upgrade -i flux fluxcd/flux --wait \
  2. --namespace fluxcd \
  3. --set registry.pollInterval=1m \
  4. --set git.pollInterval=1m \
  5. --set git.url=git@github.com:${GHUSER}/gitops-helm-workshop

安装 fluxctl:

  1. # macOS and linux
  2. curl -sL https://fluxcd.io/install | sh
  3. export PATH=$PATH:$HOME/.fluxcd/bin
  4. # windows
  5. https://github.com/fluxcd/flux/releases

找到 Git SSH 公钥:

  1. export FLUX_FORWARD_NAMESPACE=fluxcd
  2. fluxctl identity

复制公钥并在 GitHub 存储库上创建具有写访问权的部署密钥。转到 Settings > Deploy keys,单击 Add deploy key,选中 Allow write access,粘贴 Flux 公钥并单击 Add key

Helm Operator

fluxcd 命名空间中安装 Flux Helm Operator:

  1. helm upgrade -i helm-operator fluxcd/helm-operator --wait \
  2. --namespace fluxcd \
  3. --set git.ssh.secretName=flux-git-deploy \
  4. --set git.pollInterval=1m \
  5. --set chartsSyncInterval=1m \
  6. --set helm.versions=v3

Linkerd

下载 Linkerd v2 CLI:

  1. # macOS and linux
  2. curl -sL https://run.linkerd.io/install | sh
  3. export PATH=$PATH:$HOME/.linkerd2/bin
  4. # windows
  5. https://github.com/linkerd/linkerd2/releases

linkerd 名称空间中安装 Linkerd 控制平面:

  1. linkerd install | kubectl apply -f -

使用以下命令验证安装:

  1. linkerd check

Flagger

添加 Flagger Helm 仓库:

  1. helm repo add flagger https://flagger.app

安装 Flagger 的金丝雀 CRD:

  1. kubectl apply -f https://raw.githubusercontent.com/weaveworks/flagger/master/artifacts/flagger/crd.yaml

linkerd 命名空间中安装 Flagger:

  1. helm upgrade -i flagger flagger/flagger --wait \
  2. --namespace linkerd \
  3. --set crd.create=false \
  4. --set metricsServer=http://linkerd-prometheus:9090 \
  5. --set meshProvider=linkerd

Helm 发布

一个 chart 发布是通过 Kubernetes 自定义资源 HelmRelease 进行描述的。

一个 Helm release 可以引用的 chart,如下:

  • 通过 HTTPS 的公共或私有 Helm 存储库
  • 通过 SSH 的公共或私有 Git 存储库

安装 NGINX

为了将应用程序暴露在集群之外,您将使用 NGINX ingress 控制器。控制器将在 Linkerd 网格内运行。

创建一个启用 linkerd 注入的名称空间:

  1. apiVersion: v1
  2. kind: Namespace
  3. metadata:
  4. annotations:
  5. fluxcd.io/ignore: "false"
  6. linkerd.io/inject: enabled
  7. name: ingress-nginx

创建一个 Helm release 来安装 NGINX ingress 控制器:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. metadata:
  4. name: nginx-ingress
  5. namespace: ingress-nginx
  6. annotations:
  7. fluxcd.io/ignore: "false"
  8. spec:
  9. releaseName: nginx-ingress
  10. chart:
  11. repository: https://kubernetes-charts.storage.googleapis.com/
  12. name: nginx-ingress
  13. version: 1.33.4
  14. values:
  15. controller:
  16. service:
  17. type: LoadBalancer

应用更改:

  1. git add -A && \
  2. git commit -m "install ingress" && \
  3. git push origin master && \
  4. fluxctl sync

验证 Helm operator 是否已安装 release:

  1. kubectl -n ingress-nginx get hr

查找 ingress 控制器的公共 IP:

  1. kubectl -n ingress-nginx get svc

安装 podinfo

Podinfo 是一个很小的 Go Web 应用程序。您将使用存储 cluster/charts/podinfo 的 git 仓库中的 Helm chart 安装 podinfo。

创建启用 linkerd 注入的 prod 命名空间:

  1. apiVersion: v1
  2. kind: Namespace
  3. metadata:
  4. annotations:
  5. fluxcd.io/ignore: "false"
  6. linkerd.io/inject: enabled
  7. name: prod

创建一个 Helm release 以安装 podinfo chart(替换 GHUSER 为你的 GitHub 用户名和使用你的 ingress IP 替换 LB-PUBLIC-IP):

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. metadata:
  4. name: podinfo
  5. namespace: prod
  6. annotations:
  7. fluxcd.io/ignore: "false"
  8. spec:
  9. releaseName: podinfo
  10. chart:
  11. git: git@github.com:GHUSER/gitops-helm-workshop
  12. ref: master
  13. path: cluster/charts/podinfo
  14. values:
  15. image:
  16. repository: stefanprodan/podinfo
  17. tag: 3.1.0
  18. service:
  19. enabled: true
  20. type: ClusterIP
  21. ingress:
  22. enabled: true
  23. annotations:
  24. kubernetes.io/ingress.class: "nginx"
  25. nginx.ingress.kubernetes.io/configuration-snippet: |
  26. proxy_set_header l5d-dst-override $service_name.$namespace.svc.cluster.local:9898;
  27. proxy_hide_header l5d-remote-ip;
  28. proxy_hide_header l5d-server-id;
  29. path: /
  30. hosts:
  31. - LB-PUBLIC-IP.nip.io

请注意,如果您使用的是 EKS,则主机应设置为 elb.amazonaws.com 地址:

  1. kubectl -n ingress-nginx get svc | grep Ingress

应用更改:

  1. git add -A && \
  2. git commit -m "install podinfo" && \
  3. git push origin master && \
  4. fluxctl sync

验证 Helm operator 是否已安装 podinfo:

  1. kubectl -n prod get hr

打开浏览器并导航到 http://LB-PUBLIC-IP.nip.io/,您应该看到 podinfo v3.1.0 UI

自动升级

Flux 可以用于自动化集群中的容器映像更新。

您可以通过注释 Helm release 对象来启用自动化 image 标记更新。

您还可以通过使用 glob、regex 或语义版本表达式来控制更新应该考虑哪些标记。

编辑 podinfo Helm release 并启用 Flux 自动 Image 更新:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. metadata:
  4. annotations:
  5. fluxcd.io/automated: "true"
  6. fluxcd.io/tag.chart-image: semver:~3.1

应用更改:

  1. git add -A && \
  2. git commit -m "automate podinfo" && \
  3. git push origin master && \
  4. fluxctl sync

验证 Helm operator 是否已升级 podinfo:

  1. kubectl -n prod get hr

在本地拉取 Flux 所做的更改:

  1. git pull origin master

打开浏览器并导航到 http://LB-PUBLIC-IP.nip.io/,您应该看到 podinfo v3.1.5 UI。

密封的 secrets

为了将 secrets 安全地存储在公共 Git 存储库中,您可以使用 Sealed Secrets 控制器 并将您的 Kubernetes Secrets 加密为 SealedSecrets。只能通过在集群中运行的控制器来解密密封的 secrets。

创建 Sealed Secrets Helm release:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. metadata:
  4. name: sealed-secrets
  5. namespace: fluxcd
  6. annotations:
  7. fluxcd.io/ignore: "false"
  8. spec:
  9. releaseName: sealed-secrets
  10. chart:
  11. repository: https://kubernetes-charts.storage.googleapis.com/
  12. name: sealed-secrets
  13. version: 1.8.0

应用更改:

  1. git add -A && \
  2. git commit -m "install sealed-secrets" && \
  3. git push origin master && \
  4. fluxctl sync

安装 kubeseal CLI:

  1. wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v1.8.0/kubeseal-darwin-amd64
  2. sudo install -m 755 kubeseal-darwin-amd64 /usr/local/bin/kubeseal

在启动时,sealed-secrets 控制器生成一个 RSA key 并记录公钥。使用 kubeseal,您可以将您的公钥保存为 pub-cert.pem,公钥可安全存储在 Git 中,可用于加密 secrets,无需直接访问 Kubernetes 集群:

  1. kubeseal --fetch-cert \
  2. --controller-namespace=fluxcd \
  3. --controller-name=sealed-secrets \
  4. > pub-cert.pem

您可以使用 kubectl 在本地生成 Kubernetes secret,并使用 kubeseal 对其进行加密:

  1. kubectl -n prod create secret generic basic-auth \
  2. --from-literal=user=admin \
  3. --from-literal=password=admin \
  4. --dry-run \
  5. -o json > basic-auth.json
  6. kubeseal --format=yaml --cert=pub-cert.pem < basic-auth.json > basic-auth.yaml

这将生成一个类型为 SealedSecret 的自定义资源,其中包含加密的凭据。

Flux 将在您的集群上应用 sealed secret,然后 sealed-secrets 的控制器将其解密为 Kubernetes secret。

为了准备进行灾难恢复,您应该使用以下命令备份 Sealed Secrets 控制器的私钥:

  1. kubectl get secret -n fluxcd sealed-secrets-key -o yaml \
  2. --export > sealed-secrets-key.yaml

要在灾难后从备份中恢复,请替换新创建的密钥并重新启动控制器:

  1. kubectl replace secret -n fluxcd sealed-secrets-key -f sealed-secrets-key.yaml
  2. kubectl delete pod -n fluxcd -l app=sealed-secrets

金丝雀发布

一个金丝雀发布是用名为 Canary 的 Kubernetes 自定义资源描述的。

应用程序启动

编辑 podinfo Helm release 和禁用 image 更新和 ClusterIP 服务:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. metadata:
  4. name: podinfo
  5. namespace: prod
  6. annotations:
  7. fluxcd.io/automated: "false"
  8. spec:
  9. releaseName: podinfo
  10. values:
  11. image:
  12. repository: stefanprodan/podinfo
  13. tag: 3.1.0
  14. service:
  15. enabled: false
  16. type: ClusterIP

应用更改:

  1. git add -A && \
  2. git commit -m "prep canary" && \
  3. git push origin master && \
  4. fluxctl sync

创建一个针对 podinfo 的金丝雀发布:

  1. apiVersion: flagger.app/v1beta1
  2. kind: Canary
  3. metadata:
  4. name: podinfo
  5. namespace: prod
  6. annotations:
  7. fluxcd.io/ignore: "false"
  8. spec:
  9. targetRef:
  10. apiVersion: apps/v1
  11. kind: Deployment
  12. name: podinfo
  13. service:
  14. port: 9898
  15. analysis:
  16. interval: 10s
  17. maxWeight: 100
  18. stepWeight: 5
  19. threshold: 5
  20. metrics:
  21. - name: request-success-rate
  22. thresholdRange:
  23. min: 99
  24. interval: 1m
  25. - name: request-duration
  26. thresholdRange:
  27. max: 500
  28. interval: 1m
  29. webhooks:
  30. - name: acceptance-test
  31. type: pre-rollout
  32. url: http://flagger-loadtester.prod/
  33. timeout: 30s
  34. metadata:
  35. type: bash
  36. cmd: "curl -sd 'test' http://podinfo-canary.prod:9898/token | grep token"
  37. - name: load-test
  38. type: rollout
  39. url: http://flagger-loadtester.prod/
  40. metadata:
  41. cmd: "hey -z 2m -q 10 -c 2 http://podinfo-canary.prod:9898/"

应用更改:

  1. git add -A && \
  2. git commit -m "add canary" && \
  3. git push origin master && \
  4. fluxctl sync

验证 Flagger 已经初始化金丝雀:

  1. kubectl -n prod get canary

自动金丝雀提升

安装负载测试服务以在金丝雀分析期间生成流量:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. metadata:
  4. name: load-tester
  5. namespace: prod
  6. annotations:
  7. fluxcd.io/ignore: "false"
  8. spec:
  9. releaseName: load-tester
  10. chart:
  11. git: https://github.com/weaveworks/flagger
  12. ref: 1.0.0-rc.1
  13. path: charts/loadtester
  14. values:
  15. fullnameOverride: load-tester

当您部署新的 podinfo 版本时,Flagger 逐渐将流量转移到金丝雀,同时测量请求的成功率以及平均响应持续时间。

基于对这些Linkerd提供的指标的分析,金丝雀部署要么提升要么回滚。

通过更新容器映像来触发金丝雀部署:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. spec:
  4. releaseName: podinfo
  5. values:
  6. image:
  7. tag: 3.1.1

应用更改:

  1. git add -A && \
  2. git commit -m "update podinfo" && \
  3. git push origin master && \
  4. fluxctl sync

当 Flagger 检测到部署修订版本已更改时,它将开始新的部署。您可以使用以下方法监视流量的变化:

  1. watch kubectl -n prod get canaries

自动回滚

在金丝雀分析期间,您可能会生成 HTTP 500 错误和高延迟,以测试 Flagger 是否暂停并回滚有故障的版本。

触发另一只金丝雀的发布:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. spec:
  4. releaseName: podinfo
  5. values:
  6. image:
  7. tag: 3.1.2

应用更改:

  1. git add -A && \
  2. git commit -m "update podinfo" && \
  3. git push origin master && \
  4. fluxctl sync

执行到测试 pod 和产生 HTTP 500 错误:

  1. kubectl -n prod exec -it $(kubectl -n prod get pods -o name | grep -m1 load-tester | cut -d'/' -f 2) bash
  2. $ hey -z 1m -c 5 -q 5 http://podinfo-canary:9898/status/500
  3. $ hey -z 1m -c 5 -q 5 http://podinfo-canary:9898/delay/1

当检查失败的数量达到金丝雀分析阈值时,流量将路由回主要服务器,并且金丝雀将比例缩放为零。

观看Flagger日志:

  1. $ kubectl -n linkerd logs deployment/flagger -f | jq .msg
  2. Starting canary analysis for podinfo.prod
  3. Advance podinfo.test canary weight 5
  4. Advance podinfo.test canary weight 10
  5. Advance podinfo.test canary weight 15
  6. Halt podinfo.test advancement success rate 69.17% < 99%
  7. Halt podinfo.test advancement success rate 61.39% < 99%
  8. Halt podinfo.test advancement success rate 55.06% < 99%
  9. Halt podinfo.test advancement request duration 1.20s > 0.5s
  10. Halt podinfo.test advancement request duration 1.45s > 0.5s
  11. Rolling back podinfo.prod failed checks threshold reached 5
  12. Canary failed! Scaling down podinfo.test

使用 Linkerd 进行监视

Linkerd 仪表板可实时提供有关服务情况的高级视图。

它可用于可视化服务依赖关系,流量拆分和了解特定服务路由的运行状况。

通过运行以下命令打开仪表板:

  1. linkerd dashboard --port=50750

在金丝雀分析期间,导航至:

  1. http://127.0.0.1:50750/namespaces/ingress-nginx/deployments/nginx-ingress-controller

您可以使用以下命令从命令行监视生产名称空间的实时流量:

  1. linkerd -n prod top deploy

您可以使用以下命令查看 podinfo 公开的所有路由:

  1. linkerd -n prod routes service/podinfo

以上路由是从 podinfo swagger 规范生成的,并作为 Linkerd 服务配置文件导出。

Canary Helm 测试

Flagger 附带有一个测试服务,该服务在配置为 Webhook 时可以运行 Helm 测试。

创建测试

为 podinfo 令牌 API 创建一个测试:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: {{ template "podinfo.fullname" . }}-jwt-test-{{ randAlphaNum 5 | lower }}
  5. labels:
  6. heritage: {{ .Release.Service }}
  7. release: {{ .Release.Name }}
  8. chart: {{ .Chart.Name }}-{{ .Chart.Version }}
  9. app: {{ template "podinfo.name" . }}
  10. annotations:
  11. linkerd.io/inject: disabled
  12. "helm.sh/hook": test-success
  13. spec:
  14. containers:
  15. - name: tools
  16. image: giantswarm/tiny-tools
  17. command:
  18. - sh
  19. - -c
  20. - |
  21. TOKEN=$(curl -sd 'test' ${PODINFO_SVC}/token | jq -r .token) &&
  22. curl -H "Authorization: Bearer ${TOKEN}" ${PODINFO_SVC}/token/validate | grep test
  23. env:
  24. - name: PODINFO_SVC
  25. value: {{ template "podinfo.fullname" . }}:{{ .Values.service.externalPort }}
  26. restartPolicy: Never

将以上文件保存在 cluster/charts/podinfo/tests 中。

prod 名称空间中部署 Helm 测试运行器:

  1. apiVersion: helm.fluxcd.io/v1
  2. kind: HelmRelease
  3. metadata:
  4. name: helm-tester
  5. namespace: prod
  6. annotations:
  7. fluxcd.io/ignore: "false"
  8. spec:
  9. releaseName: helm-tester
  10. chart:
  11. git: https://github.com/weaveworks/flagger
  12. ref: 1.0.0-rc.1
  13. path: charts/loadtester
  14. values:
  15. fullnameOverride: helm-tester
  16. serviceAccountName: helm-tester

应用更改:

  1. git add -A && \
  2. git commit -m "install helm-tester" && \
  3. git push origin master && \
  4. fluxctl sync

运行测试

将 helm 测试添加为预发布 webhook:

  1. apiVersion: flagger.app/v1beta1
  2. kind: Canary
  3. metadata:
  4. name: podinfo
  5. namespace: prod
  6. spec:
  7. analysis:
  8. webhooks:
  9. - name: "helm test"
  10. type: pre-rollout
  11. url: http://helm-tester.prod/
  12. timeout: 2m
  13. metadata:
  14. type: "helmv3"
  15. cmd: "test podinfo"
  16. - name: load-test
  17. url: http://load-tester.prod/
  18. metadata:
  19. cmd: "hey -z 2m -q 10 -c 2 http://podinfo-canary.prod:9898/"

应用更改:

  1. git add -A && \
  2. git commit -m "update podinfo" && \
  3. git push origin master && \
  4. fluxctl sync

当金丝雀分析开始时,Flagger 将在将流量路由到金丝雀之前调用预发布 Webhooks。

如果 helm 测试失败,Flagger 将重试,直到达到分析阈值并且金丝雀回退为止。

使用 Flux,Helm v3,Linkerd 和 Flagger 渐进式交付 Kubernetes的更多相关文章

  1. 初探云原生应用管理(二): 为什么你必须尽快转向 Helm v3

    系列介绍:这个系列是介绍如何用云原生技术来构建.测试.部署.和管理应用的内容专辑.做这个系列的初衷是为了推广云原生应用管理的最佳实践,以及传播开源标准和知识.在这个系列文章的开篇初探云原生应用管理(一 ...

  2. Helm V3 新版本发布

    Helm v3.0.0 Alpha 1 is coming! Helm 作为 Kubernetes 体系的包管理工具,已经逐渐成为了事实上的应用分发标准.根据 2018 年 CNCF 的一项云原生用户 ...

  3. 小白学k8s(7)helm[v3]使用了解

    helm使用 什么是helm 安装helm Helm V2 & V3 架构设计 配置kube config helm使用 添加仓库 helm安装nginx helm的核心概念 Chart Co ...

  4. Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署

    渐进式交付是持续交付的下一步, 它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估, 如果不匹配某些关键指标,则进行回滚. 这里有一些有趣的项目,使得渐进式交付在 Ku ...

  5. DevOps - 从渐进式交付说起(含实践 Demo)

    作者:CODING - 王炜 1. 开篇 如果让你主导一款千万.甚至亿级用户产品的功能迭代,你会怎么做?你需要面对的挑战可能来自于: 商业战略的变化带来新的产品诉求,而产品的任何改动哪怕仅是界面调整, ...

  6. 使用 flux2+kustomize+helm+github 进行多集群 GitOps 云原生渐进式交付

    对于此示例,我们假设有两个集群的场景:暂存(staging)和生产(production). 最终目标是利用 Flux 和 Kustomize 来管理两个集群,同时最大限度地减少重复声明. 我们将配置 ...

  7. 使用 Flux+Flagger+Istio+Kubernetes 实战 GitOps 云原生渐进式(金丝雀)交付

    在这篇指南中,你将获得使用 Kubernetes 和 Istio 使用 GitOps 进行渐进式交付(Progressive Delivery)的实际经验. 介绍 gitops-istio GitOp ...

  8. 云原生生态周报 Vol. 19 | Helm 推荐用户转向 V3

    作者| 禅鸣.忠源.天元.进超.元毅 业界要闻 Helm 官方推荐用户迁移到 V3 版本 Helm 官方发布博客,指导用户从 v2 迁移到 v3,这标志着官方开始正式推进 helm 从 v2 转向 v ...

  9. [转帖]Helm V2 迁移到 V3 版本

    Helm V2 迁移到 V3 版本 -- :: Mr-Liuqx 阅读数 63更多 分类专栏: kubernetes 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上 ...

随机推荐

  1. if-then-else、loop控制语句在SIMD指令下的后端指令生成实现--笔记

    作者:Yaong 出处:https://www.cnblogs.com/yaongtime/p/14111134.html 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者同意,必须保留此 ...

  2. 【Codeforces 809E】Surprise me!(莫比乌斯反演 & 虚树)

    Description 给定一颗 \(n\) 个顶点的树,顶点 \(i\) 的权值为 \(a_i\).求: \[\frac{1}{n(n-1)}\sum_{i=1}^n\sum_{j=1}^n\var ...

  3. 计算机语言与JAVA的发展

    计算机语言与JAVA的发展 第一代语言 2进制 第二代语言 汇编语言 解决人类无法读懂的问题 指令替代二进制 目前应用 逆向工程 机器人 病毒 第三代语言 摩尔定律 性能提升愈来愈慢 高级语言 面向过 ...

  4. Linux下weblogic启动慢

    修改Linux上Weblogic使用的jdk $JAVA_HOME/jre/lib/security/java.security (/bea/weblogic/jdk150_12/jre/lib/se ...

  5. RMAN duplicate from active database

    在Oracle 11G有二种方法实现duplicate: 1.Active database duplication 2.Backup-based duplication Active databas ...

  6. java_day03

    一.this关键字的作用 昨天学了Java private 关键字 ,private关键字主要是为了 保护变量 ,感觉用着好像并不是特别方便 如果需要访问本类当中的成员变量,需要使用的格式: this ...

  7. Ecshop V2.7代码执行漏洞分析

    0x01 此漏洞形成是由于未对Referer的值进行过滤,首先导致SQL注入,其次导致任意代码执行. 0x02 payload: 554fcae493e564ee0dc75bdf2ebf94caads ...

  8. Azure Databricks 第一篇:创建工作区、集群和Notebook

    Azure Databricks是一个可扩展的数据分析平台,基于Apache Spark.Azure Databricks 工作区(Workspace)是一个交互式的环境,工作区把对象(noteboo ...

  9. JavaScript实现自定义右键菜单

    JavaScript实现自定义右键菜单,思路如下: 1. 屏蔽默认右键事件: 2. 隐藏自定义的菜单模块(如div.ul等): 3. 右键点击特定或非特定区域,显示菜单模块: 4. 再次点击,隐藏菜单 ...

  10. ASP.NET Core 3.1使用Swagger

    一.什么是Swagger 随着技术的不断方法,现在的网站开发基本都是使用前后端分离的模式,这样使前端开发者和后端开发者只需要专注自己擅长的即可.但这种方式会存在一种问题:前后端通过API接口的方式进行 ...