天天看點

在K8S中使用Argo CD做持續部署

在K8S中使用Argo CD做持續部署

作者 | 喬克

持續部署這個詞對技術人員來說并不陌生,很多時候我們都将CI和CD揉在一起了,今天我們将他們分開。

什麼是ArgoCD

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.

Argo CD是一個基于Kubernetes的聲明式的GitOps工具。

在說Argo CD之前,我們先來了解一下什麼是GitOps。

什麼是GitOps

GitOps是以Git為基礎,使用CI/CD來更新運作在雲原生環境的應用,它秉承了DevOps的核心理念--“建構它并傳遞它(you built it you ship it)”。

概念說起來有點虛,我畫了張圖,看了你就明白了。

在K8S中使用Argo CD做持續部署

image.png

  • 當開發人員将開發完成的代碼推送到git倉庫會觸發CI制作鏡像并推送到鏡像倉庫
  • CI處理完成後,可以手動或者自動修改應用配置,再将其推送到git倉庫
  • GitOps會同時對比目标狀态和目前狀态,如果兩者不一緻會觸發CD将新的配置部署到叢集中

其中,目标狀态是Git中的狀态,現有狀态是叢集的裡的應用狀态。

不用GitOps可以麼?

當然可以,我們可以使用kubectl、helm等工具直接釋出配置,但這會存在一個很嚴重的安全問題,那就是密鑰共享。

為了讓CI系統能夠自動的部署應用,我們需要将叢集的通路密鑰共享給它,這會帶來潛在的安全問題。

ArgoCD

Argo CD遵循GitOps模式,使用Git存儲庫存儲所需應用程式的配置。

Kubernetes清單可以通過以下幾種方式指定:

  • kustomize應用程式
  • helm圖表
  • ksonnet應用程式
  • jsonnet檔案
  • 基于YAML/json配置
  • 配置管理插件配置的任何自定義配置管理工具

Argo CD實作為kubernetes控制器,它持續監視運作中的應用程式,并将目前的活動狀态與期望的目标狀态進行比較(如Git repo中指定的那樣)。如果已部署的應用程式的活動狀态偏離了目标狀态,則認為是OutOfSync。Argo CD報告和可視化這些差異,同時提供了方法,可以自動或手動将活動狀态同步回所需的目标狀态。在Git repo中對所需目标狀态所做的任何修改都可以自動應用并反映到指定的目标環境中。

Argo CD就處在如下位置:

在K8S中使用Argo CD做持續部署

它的優勢總結如下:

  • 應用定義、配置和環境資訊是聲明式的,并且可以進行版本控制;
  • 應用部署和生命周期管理是全自動化的,是可審計的,清晰易懂;
  • Argo CD是一個獨立的部署工具,支援對多個環境、多個Kubernetes叢集上的應用進行統一部署和管理

實踐

前提:有一個可用的Kubernetes叢集。

實驗環境:

  • kubernetes:1.17.2
  • argo cd:latest

安裝Argo CD

安裝很簡單,不過在實際使用中需要對資料進行持久化。

我這裡直接使用官方文檔的安裝指令:

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
           

執行成功後會在

argocd

的namespace下建立如下資源。

# kubectl get all -n argocd 
NAME                                      READY   STATUS    RESTARTS   AGE
pod/argocd-application-controller-0       1/1     Running   0          16h
pod/argocd-dex-server-74d9998fdb-mvpmh    1/1     Running   0          16h
pod/argocd-redis-59dbdbb8f9-msxrp         1/1     Running   0          16h
pod/argocd-repo-server-599bdc7cf5-ccv8l   1/1     Running   0          16h
pod/argocd-server-576b4c7ff4-cnp9d        1/1     Running   0          16h

NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/argocd-dex-server       ClusterIP   10.105.217.139   <none>        5556/TCP,5557/TCP,5558/TCP   16h
service/argocd-metrics          ClusterIP   10.97.116.36     <none>        8082/TCP                     16h
service/argocd-redis            ClusterIP   10.105.63.34     <none>        6379/TCP                     16h
service/argocd-repo-server      ClusterIP   10.111.153.131   <none>        8081/TCP,8084/TCP            16h
service/argocd-server           ClusterIP   10.105.229.250   <none>        80/TCP,443/TCP               16h
service/argocd-server-metrics   ClusterIP   10.104.8.45      <none>        8083/TCP                     16h

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argocd-dex-server    1/1     1            1           16h
deployment.apps/argocd-redis         1/1     1            1           16h
deployment.apps/argocd-repo-server   1/1     1            1           16h
deployment.apps/argocd-server        1/1     1            1           16h

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/argocd-dex-server-74d9998fdb    1         1         1       16h
replicaset.apps/argocd-redis-59dbdbb8f9         1         1         1       16h
replicaset.apps/argocd-repo-server-599bdc7cf5   1         1         1       16h
replicaset.apps/argocd-server-576b4c7ff4        1         1         1       16h

NAME                                             READY   AGE
statefulset.apps/argocd-application-controller   1/1     16h
           

通路Argo server的方式有兩種:

  • 通過web ui
  • 使用argocd 用戶端工具

我這裡直接使用web ui進行管理。

通過

kubectl edit -n argocd svc argocd-server

将service的type類型改為NodePort。改完後通過以下指令檢視端口:

# kubectl get svc -n argocd 
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
argocd-dex-server       ClusterIP   10.105.217.139   <none>        5556/TCP,5557/TCP,5558/TCP   17h
argocd-metrics          ClusterIP   10.97.116.36     <none>        8082/TCP                     17h
argocd-redis            ClusterIP   10.105.63.34     <none>        6379/TCP                     17h
argocd-repo-server      ClusterIP   10.111.153.131   <none>        8081/TCP,8084/TCP            17h
argocd-server           NodePort    10.105.229.250   <none>        80:32109/TCP,443:30149/TCP   17h
argocd-server-metrics   ClusterIP   10.104.8.45      <none>        8083/TCP                     17h
           

然後通過http://IP:32109通路頁面,如下:

在K8S中使用Argo CD做持續部署

登入賬号為admin,密碼通過以下指令擷取。

kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
           

然後進入如下界面。

在K8S中使用Argo CD做持續部署

建立應用

這裡僅僅是為了測試argo,是以并沒有做ci部分。

我在gitlab上準備了一個倉庫,倉庫裡的檔案很簡單,如下:

在K8S中使用Argo CD做持續部署

其中manifests下就是一個deployment檔案,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: devops-argocd-test
  name: devops-argocd-test
  namespace: default
spec:
  minReadySeconds: 60
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: devops-argocd-test
  template:
    metadata:
      labels:
        app: devops-argocd-test
    spec:
      containers:
        - name: devops-argocd-test
          image: registry.cn-hangzhou.aliyuncs.com/rookieops/argocd-test-app:v1
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
              name: tcp-8080
              protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: devops-argocd-test
  name: devops-argocd-test
  namespace: default
spec:
  ports:
    - name: tcp-8080
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: devops-argocd-test
  sessionAffinity: None
  type: NodePort
           

現在我們在Argo裡建立應用,步驟如下:

(1)添加倉庫位址,Settings → Repositories,點選

Connect Repo using HTTPS

按鈕:

在K8S中使用Argo CD做持續部署

填入以下資訊。

在K8S中使用Argo CD做持續部署

驗證通過後顯示如下:

在K8S中使用Argo CD做持續部署

(2)建立應用

在K8S中使用Argo CD做持續部署
在K8S中使用Argo CD做持續部署

建立完成後如下所示:

在K8S中使用Argo CD做持續部署

由于我設定的是手動SYNC,是以需要點一下下面的SYNC進行同步。

然後可以看到狀态都變成正常。

在K8S中使用Argo CD做持續部署

這時候我們在叢集裡可以看到建立了v1版本的應用了。

# kubectl get pod | grep devops-argocd-test
devops-argocd-test-7f5fdd9fcf-xbzmp      1/1     Running   0          118s
# kubectl get svc | grep devops-argocd-test
devops-argocd-test   NodePort    10.97.159.140   <none>        8080:31980/TCP   2m6s
           

這時候通路應用,如下:

在K8S中使用Argo CD做持續部署

配置變更

接下來我手動進行配置變更,修改manifests下的deploymeny.yaml檔案中的鏡像為v2版本,如下:

在K8S中使用Argo CD做持續部署

然後送出到倉庫。

這是到ArgoCD中可以看到狀态變成了OutOfSync

在K8S中使用Argo CD做持續部署

這時候再手動sync一下,直到狀态都變正常。再通路上面的應用。

在K8S中使用Argo CD做持續部署
在K8S中使用Argo CD做持續部署

可以看到應用已經更新部署了。

我們可以看到整個應用的關系狀态,如下:

在K8S中使用Argo CD做持續部署

還可以看到部署曆史。

在K8S中使用Argo CD做持續部署

也可以通過這個界面進行復原。

在K8S中使用Argo CD做持續部署

不過這個復原并不會復原gitlab上的代碼哈。