GitOps入門與實踐:如何集成Git和K8S?

也許你之前聽說過GitOps,但是對其并不了解坊谁。在本文中费彼,我將對其進行簡單介紹,它其實是一個應(yīng)用程序開發(fā)和管理中的一個術(shù)語口芍,其核心思想是將應(yīng)用系統(tǒng)的聲明性基礎(chǔ)架構(gòu)和應(yīng)用程序存放在Git的版本控制庫中箍铲。我們將介紹GitOps是什么,它將如何影響組織以及如何與Kubernetes保持同步鬓椭。

image

什么是GitOps

GitOps是一種實現(xiàn)持續(xù)交付的模型虹钮,利用Git開發(fā)工具對云原生應(yīng)用程序進行操作和管理。當(dāng)將應(yīng)用程序部署到Kubernetes時膘融,Git應(yīng)該是唯一的事實來源。當(dāng)開發(fā)人員更改應(yīng)用程序時祭玉,Git將自動把它們push到Kubernetes進行部署氧映。而且,如果Kubernetes內(nèi)的運行狀態(tài)發(fā)生變化但與Git內(nèi)的狀態(tài)不一致脱货,則它們會從Git內(nèi)恢復(fù)到已知狀態(tài)岛都。

GitOps與CI/CD:它們之間有什么聯(lián)系?

GitOps和CI/CD是十分重要的工作伙伴振峻。CI/CD可以讓開發(fā)人員持續(xù)迭代臼疫、開發(fā)和部署應(yīng)用程序。而迭代通常通過一個Git配置倉庫進行(盡管也會有其他配置倉庫)扣孟。在部署/交付階段烫堤,構(gòu)建的基于容器的應(yīng)用程序被“push”到Kubernetes進行部署。GitOps會通過Kubernetes使用“pull”的方法來增強CI/CD模型凤价,從而將運維層面帶入部署/交付中鸽斟。

但是,如果有人更改了Kubernetes集群中運行的某些內(nèi)容利诺,會發(fā)生什么富蓄?我們將使用Git作為聲明性部署工具的主要事實來源,并利用其他工具在出現(xiàn)差異時向我們發(fā)出警報慢逾。此外立倍,通過利用可以識別運行狀態(tài)和聲明狀態(tài)之間差異的工具,Kubernetes可以修復(fù)為已知/聲明的運行狀態(tài)侣滩。

注意:持續(xù)集成和持續(xù)開發(fā)是互補但獨立的過程口注。在理想狀態(tài)下,GitOps會將批處理規(guī)模拆分為單件流程胜卤,每次只處理一個單元疆导。但是,由于CI和CD流程發(fā)生在不同的組中,因此組織之間的流程可能會有所不同澈段。

GitOps和應(yīng)用程序生命周期

讓我們從應(yīng)用程序生命周期的視角來看一下GitOps的作用悠菜。在典型的生命周期中,應(yīng)用程序會經(jīng)歷多個狀態(tài)败富,包括:

  • 代碼

  • 構(gòu)建

  • 創(chuàng)建鏡像

  • 測試

  • 發(fā)布

而使用GitOps悔醋,這些狀態(tài)將會擴展為:

  • 部署

  • 在Git倉庫中監(jiān)控更改

  • 日志更改和事件

  • 發(fā)生更改時發(fā)出警報,并于現(xiàn)有的監(jiān)控/告警系統(tǒng)集成

  • 更新

在GitOps操作模型下兽叮,當(dāng)應(yīng)用程序發(fā)布時芬骄,Kubernetes需要確保其按預(yù)期運行。同時鹦聪,Kubernetes通過確保其穩(wěn)定性和可用性來管理應(yīng)用程序的運維工作账阻。如果一個開發(fā)人員通過Git更改了該應(yīng)用程序,Kubernetes將會接受聲明并根據(jù)需要應(yīng)用它泽本。

GitOps帶來了什么淘太?

  • GitOps為應(yīng)用程序提供一個操作模型,它可以確保Git提供一個框架來統(tǒng)一應(yīng)用程序的運行规丽、操作和持續(xù)開發(fā)蒲牧。

  • 作為CI/CD流水線的一部分,GitOps為應(yīng)用程序構(gòu)建/交付與運行它的位置之間提供了粘合劑赌莺。

  • 在Kubernetes平臺中冰抢,Git為應(yīng)用程序的開發(fā)和運維提供了唯一的事實來源。

  • 應(yīng)用程序交付和平臺管理都是聲明式的艘狭,同時還能通過Git進行版本控制

  • Git可以控制回滾挎扰、升級以及更改

  • 開發(fā)人員不需要知道如何操作運維平臺(如Kubernetes),無需了解復(fù)雜的部署交付流程巢音,僅需使用熟悉的工具發(fā)布新功能即可鼓鲁。極大提升開發(fā)者體驗。

  • Git控制并修證差異或“漂移”

  • GitOps利用審核港谊、監(jiān)控以及回滾功能來增加應(yīng)用程序發(fā)布的可靠性和穩(wěn)定性

最后骇吭,盡管在GitOps模式下還有很多工作要做,但是GitOps歧寺、DevOps以及現(xiàn)有CI/CD模式之間存在十分明顯的協(xié)同作用燥狰。GitOps提供了一種用于將應(yīng)用程序交付到Kubernetes平臺的模型,該模型確保了Git是唯一的事實來源并且充分利用Kubernetes平臺上的功能斜筐。但值得注意的是龙致,GitOps不能替代工具。恰恰相反顷链,GitOps通過聲明性的流程和工具來強化流程目代、提高其成熟度并幫助團隊交付應(yīng)用程序。

GitOps實踐:FluxCD Demo

FluxCD(或Flux)是一個很棒的工具,它可以將Git和Kubernetes集成起來榛了。Flux本質(zhì)上是一個Kubernetes Operator在讶,這意味著,你作為一個管理員可以將其安裝到Kubernetes 以管理Git和原生Kubernetes之間的集成霜大。

在Kubernetes中构哺,Operator是Kubernetes原生平臺的擴展,是一種自定義資源的模式战坤,該自定義資源主要用于管理應(yīng)用程序及其組件曙强。這意味著,在Kubernetes內(nèi)部Operator的幫助下途茫,所需狀態(tài)(如運行狀態(tài))將不斷檢查和調(diào)整以符合Git倉庫聲明的內(nèi)容碟嘴。Flux可以集成到你現(xiàn)有的CI/CD工具集中,以進行其他工作流程囊卜、權(quán)限批準(zhǔn)和審核臀防。在Kubernetes中,F(xiàn)lux會監(jiān)控你通過配置聲明的Git倉庫是否發(fā)生更改边败,并且如果 Kubernetes Pod上在本地發(fā)生了不應(yīng)發(fā)生的更改,F(xiàn)lux將會把Kubernetes更新到所需的運行狀態(tài)捎废。請記住笑窜,Git是事實來源。Flux Operator會檢測到這一點登疗,并將正在運行的配置更改回聲明的狀態(tài)排截。

以下demo,我將會展示如何安裝和實現(xiàn)Flux辐益。

前期準(zhǔn)備

你將需要:

  • 一個Docker Hub鏡像倉庫断傲,你可以將Flaskapp docker鏡像上傳到此處

  • 一個Git Repo并連接它,然后你可以在整個演示過程中根據(jù)需要用你的設(shè)置替換“< >”中的任何內(nèi)容

具體步驟

  • 安裝Kubernetes

  • 安裝并配置fluxctl智政,F(xiàn)lux部署的原生安裝程序

  • 配置Flux以連接到Git Repo

  • 在Git Repo中升級deployment manifest

  • 升級容器鏡像并同步

  • 配置漂移(drift)并同步

你可以使用以下配置進行測試或演示认罩。它包括Flask應(yīng)用程序的Docker file以及Kubernetes deployment/配置文件。在演示中续捂,你會需要它們垦垂,此外你還可以將它們上傳到你指定的Git倉庫中。

Docker File

FROM python:3
    
    RUN pip install flask
    
    RUN mkdir -p /corp/app
    WORKDIR /corp/app
    COPY main.py .
    ENV FLASK_APP=/corp/app/main.py
    
    ENV APP_NAME=MyApp.DevOps
    ENV APP_VERSION=v1.0.0
    
    CMD ["flask", "run", "--host=127.0.0.1"]

main.py Python 腳本文件

import os
from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    appname = os.environ['APP_NAME']
    appversion = os.environ['APP_VERSION']

    response = "%s - %s.%s\n" %('Hello World', appname, appversion)
    return response

Kubernetes Deployment文件

apiVersion: v1 
kind: Namespace 
metadata: 
  name: my-demo 
--- 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: fluxdemo 
  namespace: my-demo 
  annotations: 
    flux.weave.works/tag.flask: glob:develop-v* 
    flux.weave.works/automated: 'true' 
  labels: 
    role: fluxdemo 
    env: demo 
    app: flux 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      role: fluxdemo 
  template: 
    metadata: 
      labels: 
        role: fluxdemo 
    spec: 
      containers: 
      - name: nginx 
        image: nginx:1.16-perl 
        imagePullPolicy: IfNotPresent 
        ports: 
        - name: http 
          containerPort: 80 
        volumeMounts: 
        - name: nginx-proxy-config 
          mountPath: /etc/nginx/conf.d/default.conf 
          subPath: nginx.conf 
      - name: flask 
        image: docker.io/<your docker repo>/flaskapp:develop-v1.8.0 
        imagePullPolicy: IfNotPresent 
        ports: 
        - name: http 
          containerPort: 5000 
        env: 
        - name: APP_NAME 
          value: myfluxdemo.K8s.GitOps 
        - name: APP_VERSION 
          value: v1.0.5 
      volumes: 
      - name: nginx-proxy-config 
        configMap: 
          name: nginx-conf 
---
apiVersion: v1
kind: ConfigMap 
metadata: 
  name: nginx-conf
  namespace: my-demo
data:
  nginx.conf: |-
    #CODE1.0:
    #add the nginx.conf configuration - this will be referenced within the deployment.yaml
    server {
        listen 80;
        server_name localhost;

        location / {
            proxy_pass http://localhost:5000/;
            proxy_set_header Host "localhost";
        }
    }

安裝Flux

  • 安裝Fluxctl

https://docs.fluxcd.io/en/1.18.0/references/fluxctl.html

  • 安裝Fluxcd

https://docs.fluxcd.io/en/1.18.0/tutorials/get-started.html

為Repo配置Flux

創(chuàng)建一個命名空間

kubectl create ns <namespace>
export FLUX_FORWARD_NAMESPACE= <namespace>
fluxctl list-workloads

安裝Fluxcd以建立與你的Git Repo的連接

export GHUSER=""
export REPO="gitops-demo"
export NS="flux"
fluxctl install \
--git-user=${GHUSER} \
--git-email=${GHUSER}@users.noreply.github.com \
--git-url=git@github.com:
Image download failed.
{REPO} \
--namespace=${NS} | kubectl apply -f -

創(chuàng)建SSH密鑰以添加到Github倉庫

在你的terminal中輸入以下命令牙瓢,以獲取下一步所需的密鑰:

fluxctl identity

打開Github劫拗,導(dǎo)航到安裝Fluxcd時添加的倉庫,轉(zhuǎn)到設(shè)置-部署密鑰矾克,單擊【添加部署密鑰】页慷,為其指定title,選中【允許write access】,粘貼公共密鑰酒繁,然后單擊【添加密鑰】滓彰。

在Git Repo中升級Deployment Manifest

打開你的Git Repo,里面應(yīng)該有deployment.yaml文件欲逃,向下滑動直到如下所示部分找蜜,然后更改APP_VERSION號碼

 env:
    - name: APP_NAME
      value: myfluxdemo.K8s.GitOps
    - name: APP_VERSION
      value: v1.0.5

保存并Commit更改到你的Repo。

Flux將在5分鐘之內(nèi)升級你的deployment

要從localhost進行測試稳析,請在Kubernetes中使用“Port-forward”命令:

kubectl get pods -n  copy the pod name kubectl port-forward  8080:80 -n

打開其他terminal:

curl -s -i http://localhost:8080

升級容器鏡像并同步

現(xiàn)在讓我們對Docker鏡像進行修改并將其上傳到我們的Docker Hub鏡像倉庫中洗做。為此,我們將修改flaskapp目錄中的main.py文件彰居。

升級main.py文件诚纸。將Hello World更改為其他內(nèi)容

response = "%s - %s.%s\n" %('Flux World', appname, appversion)

創(chuàng)建一個新的Docker文件并上傳到Docker(以及另一個增量版本號)。

等待5分鐘陈惰,F(xiàn)lux將會自動部署新鏡像

配置漂移并同步

現(xiàn)在畦徘,我們來測試一下手動更改正在運行的配置會發(fā)生什么。

kubectl scale deployment/fluxdemo --replicas=4 -n

現(xiàn)在抬闯,我們花幾分鐘來看看pod并觀察發(fā)生了什么井辆。我們將會在短時間內(nèi)(5分鐘以內(nèi))看到其他的pod,此外我們還將看到許多pod終止溶握。因此杯缺,F(xiàn)lux已使配置恢復(fù)到當(dāng)前在Git中保留的已聲明的部署狀態(tài)。

kubectl get po -n  --watch

重新運行相同的命令睡榆,并且你會看到目前僅有一個正在運行的pod萍肆。

別忘了清理和移除deployment和Git連接(如果你想移除它)。否則胀屿,你需要開始添加更多的倉庫并繼續(xù)進行構(gòu)建塘揣。

總 結(jié)

本文中我們簡單介紹了GitOps概念、它與CI/CD的關(guān)系以及它對應(yīng)用程序的生命周期的改變宿崭。最后我們還demo了GitOps中的一個小工具Flux亲铡,它可以幫助把Kubernetes和Git集成起來,從而優(yōu)化CI/CD流程葡兑。

本文僅僅是一個GitOps的引子奴愉,希望你可以通過它更好地入門GitOps,進而提升你的開發(fā)部署體驗铁孵。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锭硼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蜕劝,更是在濱河造成了極大的恐慌檀头,老刑警劉巖轰异,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異暑始,居然都是意外死亡搭独,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門廊镜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牙肝,“玉大人,你說我怎么就攤上這事嗤朴∨渫郑” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵雹姊,是天一觀的道長股缸。 經(jīng)常有香客問我,道長吱雏,這世上最難降的妖魔是什么敦姻? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮歧杏,結(jié)果婚禮上镰惦,老公的妹妹穿的比我還像新娘。我一直安慰自己犬绒,他們只是感情好旺入,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著懂更,像睡著了一般。 火紅的嫁衣襯著肌膚如雪急膀。 梳的紋絲不亂的頭發(fā)上沮协,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天,我揣著相機與錄音卓嫂,去河邊找鬼慷暂。 笑死,一個胖子當(dāng)著我的面吹牛晨雳,可吹牛的內(nèi)容都是我干的行瑞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼餐禁,長吁一口氣:“原來是場噩夢啊……” “哼血久!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帮非,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤氧吐,失蹤者是張志新(化名)和其女友劉穎讹蘑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體筑舅,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡座慰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翠拣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片版仔。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖误墓,靈堂內(nèi)的尸體忽然破棺而出蛮粮,到底是詐尸還是另有隱情,我是刑警寧澤优烧,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布蝉揍,位于F島的核電站,受9級特大地震影響畦娄,放射性物質(zhì)發(fā)生泄漏又沾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一熙卡、第九天 我趴在偏房一處隱蔽的房頂上張望杖刷。 院中可真熱鬧,春花似錦驳癌、人聲如沸滑燃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽表窘。三九已至,卻和暖如春甜滨,著一層夾襖步出監(jiān)牢的瞬間乐严,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工衣摩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留昂验,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓艾扮,卻偏偏與公主長得像既琴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泡嘴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容