【云原生 | Kubernetes 系列】--Gitops持续交付 ArgoCD自动同步策略

1. ArgoCD自动同步策略

自动同步策略允许ArgoCD在检测到GitRepo与实际状态之间存在差异时,自动启动同步操作.

Prune Resource(自动修剪):在集群上某个资源在GitRepo中找不到对应的配置时,自动删除集群上的该资源
Self Heal(自愈): 因各种原因(如手动修改)集群上资源的实时状态而导致与GitRepo不匹配时,自动将实际状态与GitRepo的期望状态同步.

  1. 自动同步仅发生在应用处于OutOfSync状态时,ArgoCD并不会对处于Synced或Error状态的Applicationzhix自动同步
  2. 对于GitRepo上的一次提交,自动同步仅会执行一次,除非同时启用Self-Heal机制.
  3. 启用了自动同步的Application不支持RollBack.

请添加图片描述

2. ArgoCD Sync Options

用于禁用或启用同步过程中的某些特性

  1. ApplyOutOfSyncOnly.仅对于那些OutOfSync状态的资源执行同步操作,可以加速同步过程
  2. PrunePropagationPolicy,资源修剪传播策略,默认使用foreground策略,还能选择background和orphan
  3. PruneLast,在同步操作的最后再执行修剪操作,即使它资源已经部署且转为健康状态后再进行Prue
  4. Replace,对资源的修改,以replace方式进行,而非默认的apply.先删除后创建,apply以补丁方式覆盖更新
  5. FailOnSharedResource,默认的同步操作不会考虑GitRepo中定义的资源是否已经被其他Application所使用.将该选项设置为true,意味着在发现资源已经被其他Application所使用时,则将同步状态设置为fail.当删除或修剪碰到共享资源时,将状态改为false,即不进行修改
  6. RespectIgnoreDifferences,在同步阶段忽略期望状态的字段
  7. CreateNamespace,创建缺失的名称空间
  8. Validation,是否执行资源规范格式的校验,相当于"kubectl apply --validate={true|false}" ,默认为true.

请添加图片描述

3. 通过Cli修改同步方式

将guestbook的同步方式设置为自动

# argocd app get guestbook
Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd.intra.com/applications/guestbook
Repo:               http://192.168.31.199/root/argocd-example-apps.git
Target:             
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>		# 此处sync是none状态
Sync Status:        Synced to  (58982ea)
Health Status:      Healthy

GROUP  KIND        NAMESPACE  NAME          STATUS  HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  Synced  Healthy        service/guestbook-ui created
apps   Deployment  default    guestbook-ui  Synced  Healthy        deployment.apps/guestbook-ui created
# argocd app set guestbook --sync-policy aut

通过命令行可以看到此时guestbook的同步方式已经变更为了自动

# argocd app get guestbook
Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd.intra.com/applications/guestbook
Repo:               http://192.168.31.199/root/argocd-example-apps.git
Target:             
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        Automated
Sync Status:        Synced to  (58982ea)
Health Status:      Healthy

GROUP  KIND        NAMESPACE  NAME          STATUS  HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  Synced  Healthy        service/guestbook-ui created
apps   Deployment  default    guestbook-ui  Synced  Healthy        deployment.apps/guestbook-ui created

自动修剪

argocd app set guestbook --auto-prune

自动修复

argocd app set guestbook --self-heal

禁止修剪特定的资源

metadata:
  annotations:
    argocd.argoproj.io/sync-options:Prunc=false

禁用kubectl验证

metadata:
  annotations:
    argocd.argoproj.io/sync-options:Validate=false

有选择的同步

argocd app set guestbook --sync-option ApplyOutOfSyncOnly=true

资源修剪传播策略

argocd app set guestbook --sync-option PrunePropagationPolicy={
    
    foreground|background|orphan}

是否同步完成后再进行修剪

argocd app set guestbook --sync-option PruneLast=true

是否replace资源而非执行apply

argocd app set guestbook --sync-option Replace={
    
    true|false}

若存在共享资源,是否将同步置为Fail

argocd app set guestbook --sync-option FailOnSharedResource={
    
    true|false}

是否忽略差异

argocd app set guestbook --sync-option RespectIgnoreDifferences={
    
    true|false}

是否自动创建命名空间

argocd app set guestbook --sync-option CreateNamespace={
    
    true|false}

4. ArgoCD CLI回滚

查看项目的历史版本

# argocd app  history argocd/spring-boot-helloworld 
ID  DATE                           REVISION
0   2022-11-18 16:22:17 +0800 CST  HEAD (d3f19ac)
1   2022-11-18 16:35:43 +0800 CST  HEAD (bbf73a3)
2   2022-11-18 16:45:39 +0800 CST  HEAD (b82bb4a)

回滚前需要先将sync-policy的自动关闭

# argocd app set  argocd/spring-boot-helloworld   --sync-policy none
# argocd app rollback argocd/spring-boot-helloworld --prune 1
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME      STATUS   HEALTH        HOOK  MESSAGE
2022-11-21T12:20:49+08:00          Namespace                        helloworld      Synced                       
2022-11-21T12:20:49+08:00            Service  helloworld  spring-boot-helloworld    Synced  Healthy              
2022-11-21T12:20:49+08:00   apps  Deployment  helloworld  spring-boot-helloworld    Synced  Healthy              
2022-11-21T12:20:51+08:00          Namespace                        helloworld      Synced                       namespace/helloworld unchanged
2022-11-21T12:20:51+08:00            Service  helloworld  spring-boot-helloworld    Synced  Healthy              service/spring-boot-helloworld unchanged
2022-11-21T12:20:51+08:00   apps  Deployment  helloworld  spring-boot-helloworld    Synced  Healthy              deployment.apps/spring-boot-helloworld configured
2022-11-21T12:20:51+08:00   apps  Deployment  helloworld  spring-boot-helloworld  OutOfSync  Progressing              deployment.apps/spring-boot-helloworld configured

Name:               argocd/spring-boot-helloworld
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          
URL:                https://argocd.intra.com/applications/argocd/spring-boot-helloworld
Repo:               http://192.168.31.199/root/spring-boot-helloworld-deployment.git
Target:             HEAD
Path:               kubernetes
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        OutOfSync from HEAD (b82bb4a)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      bbf73a31cb13c11dc9d82717119bc03df7aac040
Phase:              Succeeded
Start:              2022-11-21 12:20:48 +0800 CST
Finished:           2022-11-21 12:20:51 +0800 CST
Duration:           3s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE   NAME                    STATUS     HEALTH       HOOK  MESSAGE
       Namespace               helloworld              Synced                        namespace/helloworld unchanged
       Service     helloworld  spring-boot-helloworld  Synced     Healthy            service/spring-boot-helloworld unchanged
apps   Deployment  helloworld  spring-boot-helloworld  OutOfSync  Progressing        deployment.apps/spring-boot-helloworld configured

此时同步状态就会显示OutOfSync

请添加图片描述

再将自动同步打开,此时又会被同步到最新状态

# argocd app set  argocd/spring-boot-helloworld   --sync-policy auto

请添加图片描述

5. ArgoCD上添加Application

argocd app create guestbook --repo http://192.168.31.199/root/spring-boot-helloWorld.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default

参数含义

参数 含义
–repo Git仓库Url
–path Git Repository中含有配置文件的子目录路径
–directory-recurse 对目录进行递归
–revision string 要使用revision通常是指源码branch,tag,commit和Helm chart版本
-f,–file string 部署Application用到的配置文件路径或URL
–release-name string 配置为Helm Charts时,为其指定release的名称
–project string 隶属于Project,默认为default
–dest-server string 目标K8s集群的API Server URL
–dest-namespace 目标名称空间

6. 将Repository添加到ArgoCD

一般私有仓库需要进行添加,公有仓库一般不需要添加

请添加图片描述

请添加图片描述

命令行添加

argocd repo add --password 

管理GitRepo常用参数

参数 含义
–name 当前Repo的名称
–ssh-private-key-path 用于访问GitRepo的SSH私钥文件路径
–insecure-ignore-host-key 不校验host key
–insecure-skip-server-verification 不校验host key和server cerificate
–username string 用户名
–password string 密码
–project string Repo所属的Project
–type string Repo的类型

管理Cluster

argocd cluster add context-intra --kubeconfig=.kube/config
参数 含义
–name Cluster的名称
–in-cluster ArgoCD自身运行在Kubernetes集群,访问地址为https://kubernetes.default.svc
–kubeconfig string 使用指定的kubeconfig文件
–namespace string Array
–project string 所属的Project
–service-account string 使用的ServiceAccount

7. 创建一个application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: spring-boot-helloworld
  namespace: argocd
spec:
  project: default
  source:
    repoURL: http://192.168.31.199/root/spring-boot-helloworld-deployment.git 
    targetRevision: HEAD
    path: kubernetes
  destination:
    server: https://kubernetes.default.svc
    namespace: helloworld
  syncPolicy:
    automated: 
      prune: true # 是否修剪
      selfHeal: true  #是否自愈
      allowEmpty: false # 是否允许空资源
    syncOptions:
    - Validate=false  # 是否校验
    - CreateNamespace=true  # 是否自动创建命名空间
    - PrunePropagationPolicy=foreground
    - PruneLast=true # 增改后是否做Prun操作
    retry:  # 重试策略
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

删除原有app,然后新增spring-boot-helloworld app

# argocd app list
NAME                           CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                              PATH        TARGET
argocd/guestbook               https://kubernetes.default.svc  default    default  Synced  Healthy  Auto        <none>      http://192.168.31.199/root/argocd-example-apps.git                guestbook   
argocd/spring-boot-helloworld  https://kubernetes.default.svc             default  Synced  Healthy  Auto        <none>      http://192.168.31.199/root/spring-boot-helloworld-deployment.git  kubernetes  HEAD

# argocd app delete argocd/spring-boot-helloworld
Are you sure you want to delete 'argocd/spring-boot-helloworld' and all its resources? [y/n] y
application 'argocd/spring-boot-helloworld' deleted
# argocd app list
NAME              CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                PATH       TARGET
argocd/guestbook  https://kubernetes.default.svc  default    default  Synced  Healthy  Auto        <none>      http://192.168.31.199/root/argocd-example-apps.git  guestbook  
# kubectl apply -f 01-application-helloworld.yaml 
application.argoproj.io/spring-boot-helloworld created

请添加图片描述

请添加图片描述

8. 基于Project CRD创建项目

Project负责为Application提供逻辑分组.主要功能如下:

  1. 限制可以部署的内容(指定受信任的Git Source仓库)通过黑,白名单实现.
  2. 限制Application可以部署到的目标位置(指定目标Cluster和Namespace)
  3. 限制能够及不能够部署的对象类型
  4. 定义Project Role,从而为Application提供RBAC机制,以绑定到OIDC组成JWT Token

ArgoCD的默认项目

​ default Project由ArgoCD自动部署,它允许用户按需修改,但不能被删除

白名单方式

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: default
  namespace: argocd
spec:
  clusterResourceWhitelist:
  - group: "*"
    kind: "*"
  destinations:
  - namespace: "*"
    server: "*"
  sourceRepos:
  - "*"

黑名单

spec:
  clusterResourceBlacklist:

9. ApplicationSet

ApplicationSet CRD用于定义可自动生成Application的模板,从而能够在monorepo(单个Repo中定义了多个ArgoCD Application)或多个Repo,以及跨大量Cluster的场景中自动化管理ArgoCD Application

ApplicationSet CRD需要同其专用的ApplicationSet控制器支撑实现

ApplicationSet可以提供

  1. 目标Cluster的模板化,从而能够在单个资源配置文件中适配部署到多个kubernetes集群
  2. 源Git配置仓库的模板化
  3. 较好地支持monorepo

ApplicationSet控制器负责生成Application,ApplicationSet控制器生成或更新Application资源
生成或更新Application资源是有Application控制器确保期望状态和实际状态的一致
ApplicationSet控制器仅负责确保ApplicationSet资源的期望状态与实际状态的一致

请添加图片描述

AS CRD资源定义–>AS控制器–>Apps CRD —> Application Controller -->目标集群上创建

9.2 ApplicationSet CRD资源规范

在ApplicationSet CRD的spec下可以定义以下三个字段

  1. generators

​ 定义负责生成参数的生成器,这些参数会被用于template字段中定义的模板
​ 生成器的关键作用在于,他们是模板参数的数据源
​ ApplicationSet支持多种不同类型的generator

  1. syncPolicy

​ 资源同步策略,仅支持一个布尔类型字段preserverResourcesOnDeletion

  1. template

​ Application资源模板,配置格式与Application规范相同,但它包含有一些参数化的配置
​ 通过将这些参数替换为generators生成的值,完成模板的实例化

9.3 ApplicationSet多环境适配

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: helloworld
  namespace: argocd
spec:
  generators:
  - list:
      elements:
      - environment: dev
      - environment: staging
      - environment: prod
  template:
    metadata:
      name: '{
    
    {environment}}-guestbook'
    spec:
      project: default
      source:
        repoURL: http://192.168.31.199/root/spring-boot-helloworld-deployment.git
        targetRevision: HEAD
        path: helloworld/{
    
    {
    
    environment}}
      destination:
        server: https://kubernetes.default.svc
        namespace: '{
    
    {environment}}'
      syncPolicy:
        automated: 
          prune: true
          selfHeal: true
          allowEmpty: false
        syncOptions:
        - Validate=false
        - CreateNamespace=true
        - PrunePropagationPolicy=foreground
        - PruneLast=true
        retry:
          limit: 5
          backoff:
            duration: 5s
            factor: 2
            maxDuration: 3m
  syncPolicy:
    preserveResourcesOnDeletion: false  # 是否在资源删除是保留

部署

# kubectl apply -f 02-applicationset-demo.yaml 
applicationset.argoproj.io/helloworld created

此时分别在3个命名空间完成创建

# kubectl get pods -n dev
NAME                                      READY   STATUS    RESTARTS   AGE
spring-boot-helloworld-78596987bc-pqtbv   1/1     Running   0          29s
# kubectl get pods -n prod
NAME                                     READY   STATUS    RESTARTS   AGE
spring-boot-helloworld-9fbc44457-5g8tt   1/1     Running   0          34s
spring-boot-helloworld-9fbc44457-jxcm2   1/1     Running   0          34s
spring-boot-helloworld-9fbc44457-s6jpj   1/1     Running   0          34s
# kubectl get pods -n staging
NAME                                     READY   STATUS    RESTARTS   AGE
spring-boot-helloworld-9fbc44457-pp74b   1/1     Running   0          39s
# argocd appset list
NAME        NAMESPACE  PROJECT  SYNCPOLICY                                                     CONDITIONS                                                                                                                                                                                                                                     REPO                                                              PATH                        TARGET
helloworld  argocd     default  &ApplicationSetSyncPolicy{
    
    PreserveResourcesOnDeletion:false,}  [{
    
    ParametersGenerated Successfully generated parameters for all Applications 2022-11-22 11:40:34 +0800 CST True ParametersGenerated} {
    
    ResourcesUpToDate ApplicationSet up to date 2022-11-22 11:40:34 +0800 CST True ApplicationSetUpToDate}]  http://192.168.31.199/root/spring-boot-helloworld-deployment.git  helloworld/{
    
    {
    
    environment}}  HEAD

请添加图片描述

决定不同版本具体区别的是在git仓库helloworld/prod,helloworld/dev,helloworld/staging/下的配置

# cat prod/02-deployment.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: spring-boot-helloworld
  labels:
    app: spring-boot-helloworld
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-boot-helloworld
  template:
    metadata:
      name: spring-boot-helloworld
      labels:
        app: spring-boot-helloworld
    spec:
      containers:
      - name: spring-boot-helloworld
        image: ikubernetes/spring-boot-helloworld:v0.8.0
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
        resources:
          requests:
            cpu: 50m
            memory: 32Mi
# cat staging/02-deployment.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: spring-boot-helloworld
  labels:
    app: spring-boot-helloworld
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-helloworld
  template:
    metadata:
      name: spring-boot-helloworld
      labels:
        app: spring-boot-helloworld
    spec:
      containers:
      - name: spring-boot-helloworld
        image: ikubernetes/spring-boot-helloworld:v0.8.0
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
        resources:
          requests:
            cpu: 50m
            memory: 32Mi

猜你喜欢

转载自blog.csdn.net/qq_29974229/article/details/127981526