首页 > 其他分享 >基于Gitlab-CI的容器应用DevOps工作流简单实践

基于Gitlab-CI的容器应用DevOps工作流简单实践

时间:2024-09-04 13:54:20浏览次数:15  
标签:CI v2rayreporter kubernetes app Gitlab DevOps io 镜像 name

前言

        基于Gitlab,Gitlab-Runner和Gitlab集成的CICD的DevOps工作流部署容器应用到测试或生产环境,可以快速方便的通过代码迭代自动部署到相应环境中,我已经提前准备好了容器内环境的Gitlab和Gitlab-Runner,有需要的同学可以鉴别参考,以及准备好Harbor私有镜像仓用来镜像的存储和转移,以此为前提进行我们的实践。

参考

        gitlab-runner + k8s 实现自动部署_慕课手记 (imooc.com)

一、打通Gitlab和K8S的工作流

这里我会介绍两个办法,一个是通过安装好Kubectl软件的镜像来导入k8s-api-config去和我们的K8S集群进行互动。另一个则是在Gitlab-Runner的镜像去直接导入。

1.配置文件变量导入镜像法

(1)构建镜像

        构建一个Kubectl镜像来方便我们部署的时候进行操作,下面我们用一个dockerfile来构建

FROM alpine:latest

ARG KUBE_LATEST_VERSION=v1.23.10

# 使用alpine:latest作为基础镜像

# 下载kubectl二进制文件并设置可执行权限
RUN apk add --update -t deps curl && \
    curl -L https://storage.googleapis.com/kubernetes-release/release/${KUBE_LATEST_VERSION}/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl && \
    chmod +x /usr/local/bin/kubectl

# 安装必要的依赖(curl),并下载kubectl二进制文件到/usr/local/bin目录,并赋予可执行权限

# 清理安装过程中的临时文件和缓存
RUN apk del --purge deps && \
    rm /var/cache/apk/*

# 删除已安装的依赖包及其依赖,以及清理apk缓存,减小镜像体积

        使用docker build来构建,构建完后,打上标签,然后登录harbor仓库给推送过去方便我们的统一管理和维护性迭代。

docker build --build-arg KUBE_LATEST_VERSION="v1.23.10" -t kubectl:v1.23.10 .
docker login $HARBOR_URL -u $HARBOR_USERNAME
docker tag kubectl:v1.23.10 $HARBOR_URL/library/kubectl:v1.23.10
docker push $HARBOR_URL/library/kubectl:v1.23.10

 (2)准备K8S配置文件并写入Gitlab管理的环境变量内

  • 配置文件也可以集成在镜像里面,但是不太灵活,一旦配置有变或者有多个集群,镜像就得修改或者准备多个版本,因此通过 gitlab ci/cd 环境变量传递

  • 首先取得配置信息,通过命令kubectl config view --raw -o yaml得到配置信息,复制到 gitlab 的 ci/cd 环境变量中

  • 这里要注意的是,命令必须带参数--raw,为了将 certificate-authority-data 的值输出,否则只能看到 DATA+OMITTED。另外,环境变量必须选择文件类型,否则最后输出格式不对,导致mapping values are not allowed in this context错误,当然选择-o json,使用 json 格式,就不用担心格式问题

  • 记得修改其中lb.kubernetes.local为master节点的IP地址

        这里因为流水线都会用到这个kube_config文件,所以我直接在全局设置的变量中填入,这里也有我提前做好的harbor的相关环境变量。

到这一步别忘了也给你的gitlab在harbor配置一个专用的账户和存储变量哦

(3)使用Gitlab-CI流水线测试该镜像是否可以成功管理K8S集群

        重要前提:之前我们的Gitlab-runner中已经映射了主机的docker给Gitlab-runner,所以这里是可以直接使用docker命令的。

        在Gitlab项目中编辑流水线编辑器如图所示:

 

stages:
  - pull
  - test

push:
  stage: pull
  script:
    - docker images
    - docker login $HARBOR_URL -u $HARBOR_USERNAME -p $HARBOR_PASSWORD
    - docker pull $HARBOR_URL/library/kubectl:v1.23.10

test:
  stage: test
  image: $HARBOR_URL/library/kubectl:v1.23.10
  script:
    - mkdir $HOME/.kube && cat $KUBE_CONFIG > $HOME/.kube/config
    - kubectl get pods -n gitlab

        提交后看到流水线如图所示就代表已成功搭建该工作流

 

        这样我们就算是完成了这一步啦。 

2.Runner配置法

        前面提到的Gitlab-runner其实可以直接配置helper和主机的映射关系,首先创建k8s服务账户给Gitlab-runner授权。

kubectl create secrete generic -n gitlab --from-file ~/.kube/config

在Gitlab-runner的配置中有:(为了方便观看,这里用的是Kubesphere的Web管理平台展示) 

我们把这里的注释改掉,并且将上方默认的指定镜像的参数改成我们harbor里面已经打包好了的基于alpine的kubectl镜像(没有的话用dockerfile去打包一个也很容易的)。

这样我们可以直接省略掉.gitlab-ci文件中的

 二、一个简单的CICD项目演示

项目介绍

我这里用了我自己平时图方便做的v2rayReporter的v2ray订阅发布程序来作为一个示例

这里的代码文件结构主要是 源代码+dockerfile+k8s-app.yml+.gitlab-ci.yml

dockerfile用于编译我的代码构建运行时镜像

k8s-app.yml用于连接k8s集群时所部署的应用的配置

.gitlab-ci是我们cicd的主要工程配置

代码和配置

dockerfile

# 第一个阶段:使用Golang镜像构建可执行文件
FROM $HARBOR_URL/library/golang:1.20.7 AS builder

# 设置工作目录
WORKDIR /app

# 复制代码
COPY ./app /app/

# 编译可执行文件 netgo标签是为了能够在alpine上运行
RUN go build -o v2rayReporter --tags netgo ./main.go 

# 第二个阶段:使用Alpine Linux镜像作为最终镜像
FROM alpine:latest

# 设置工作目录
WORKDIR /app

# 从第一个阶段中复制可执行文件到Alpine镜像中
COPY --from=builder /app/v2rayReporter /app/

# 声明运行时的命令
CMD ["./v2rayReporter"]

下面是部署Deployment的yaml文件,我们要记得在template里面加上一个时间戳用于实现滚动更新的效果镜像因为版本用的latest可以试试将拉取策略改为一直拉取 

apiVersion: app.k8s.io/v1beta1
kind: Application
metadata:
  name: v2rayreporter
  namespace: network
  labels:
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: v2rayreporter
  annotations:
    servicemesh.kubesphere.io/enabled: 'true'
spec:
  selector:
    matchLabels:
      app.kubernetes.io/version: v1
      app.kubernetes.io/name: v2rayreporter
  addOwnerRef: true
  componentKinds:
    - group: ''
      kind: Service
    - group: apps
      kind: Deployment
    - group: apps
      kind: StatefulSet
    - group: networking.k8s.io
      kind: Ingress
    - group: servicemesh.kubesphere.io
      kind: Strategy
    - group: servicemesh.kubesphere.io
      kind: ServicePolicy
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: network
  labels:
    version: v1
    app: v2rayreporter-svc
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: v2rayreporter
  name: v2rayreporter-svc-v1
  annotations:
    servicemesh.kubesphere.io/enabled: 'true'
spec:
  replicas: 1
  selector:
    matchLabels:
      version: v1
      app: v2rayreporter-svc
      app.kubernetes.io/version: v1
      app.kubernetes.io/name: v2rayreporter
  template:
    metadata:
      labels:
        version: v1
        app: v2rayreporter-svc
        app.kubernetes.io/version: v1
        app.kubernetes.io/name: v2rayreporter
      annotations:
        kubesphere.io/imagepullsecrets: '{"v2rayreporter":"harbor"}'
        sidecar.istio.io/inject: 'true'
        kubectl.kubernetes.io/restartedAt: "{{ .RunCreatedAt }}"  #由此来触发滚动更新
    spec:
      containers:
        - name: v2rayreporter
          imagePullPolicy: Always
          image: '$HARBOR_URL/library/v2rayreporter:latest'
          ports:
            - name: http-0
              protocol: TCP
              containerPort: 8001
          volumeMounts:
            - name: host-time
              mountPath: /etc/localtime
              readOnly: true
      serviceAccountName: default
      terminationGracePeriodSeconds: 30
      initContainers: []
      volumes:
        - hostPath:
            path: /etc/localtime
            type: ''
          name: host-time
      imagePullSecrets:
        - name: harbor
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%

---

apiVersion: v1
kind: Service
metadata:
  namespace: network
  labels:
    version: v1
    app: v2rayreporter-svc
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: v2rayreporter
  annotations:
    kubesphere.io/serviceType: statelessservice
    servicemesh.kubesphere.io/enabled: 'true'
  name: v2rayreporter-svc
spec:
  sessionAffinity: None
  selector:
    app: v2rayreporter-svc
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: v2rayreporter
  ports:
    - name: http-0
      protocol: TCP
      port: 80
      targetPort: 8001

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: network
  labels:
    app.kubernetes.io/version: v1
    app.kubernetes.io/name: v2rayreporter
  name: v2rayreporter-ingress-pybd68
  annotations:
    nginx.ingress.kubernetes.io/upstream-vhost: v2rayreporter-svc.network.svc.cluster.local
spec:
  rules:
    - host: v2ray.povison-pro.com
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              service:
                name: v2rayreporter-svc
                port:
                  number: 80
  tls: []

cicd工程配置如下

主要分为简单的build流程和deploy流程

build是利用dockerfile构建好应用运行时的镜像并推送到仓库

deploy是利用v2rayreport.yml在k8s集群中部署应用

variables: #编辑容器内环境变量
  IMAGE_NAME: v2rayreporter #镜像名称

stages:
  - build
  - deploy

build: #没有指定image时用runner配置中指定的默认镜像
  stage: build
  script:
    - docker build -f dockerfile -t harbor.povison-pro.com/library/$IMAGE_NAME . #构建镜像
    - docker login $HARBOR_URL -u $HARBOR_USERNAME -p $HARBOR_PASSWORD #登录镜像仓库
    - docker push $HARBOR_URL/library/$IMAGE_NAME #推送镜像
    - docker rmi $HARBOR_URL/library/$IMAGE_NAME  #删除镜像(镜像清理原则)
    - docker image prune -a -f  #清理无用镜像

deploy:
  stage: deploy
  image: $HARBOR_URL/library/kubectl:v1.23.10 #部署到K8S集群需要用到这个工具镜像 这个要看用的哪个方法做的和K8S互动
  script:
    - mkdir $HOME/.kube && cat $KUBE_CONFIG > $HOME/.kube/config #链接K8S集群用
    - kubectl apply -f v2rayreporter.yml

效果展示 

到这里这个简单思路的实践就完成啦! 


文章写的比较粗糙,有问题欢迎交流学习!

标签:CI,v2rayreporter,kubernetes,app,Gitlab,DevOps,io,镜像,name
From: https://blog.csdn.net/Matthewmq/article/details/141887777

相关文章

  • Linux-devops
    云原生时代:以Devops、SRE框架为指导,Docker/K8S/微服务为基础,用分布式方式加上Python和Go语言,构建一套云技术产品体系,以及进行高级管理工具的二次开发,实现属于公司自己的自动化运维体系以及云技术体系的自动化产品。使用的自动化运维产品,可以用rancherargoCDtecktonClgit......
  • 设计模式-离线并发模式-隐含锁(Implicit Lock)
    作用允许框架或层超类型代码来获取离线锁锁机制应该由应用隐含的完成,而不是由开发人员编写代码完成,这样可以避免编写锁代码的疏忽而造成的数据不一致等情况。实现机制实现隐含锁就是要分解代码,在应用程序框架中完成那些无法逾越的锁机制。在悲观离线锁的任务中,会出现两......
  • C++ explicit关键字
    explicit关键字在C++中,explicit关键字用于控制某些类型转换的隐式性。它主要与构造函数和转换操作符相关联,下面详细介绍explicit关键字的使用和作用。explicit构造函数当构造函数被声明为explicit时,它指示的这个构造函数只能使用显式构造对象,不能用于隐式类型转换。这有助于防......
  • 【SCI复现】基于纳什博弈和ADMM的多微网主体能源共享研究(Matlab代码实现)
    ......
  • 观测云核心技术解密:eBPF Tracing 实现原理
    前言eBPF是一种强大的内核技术,允许在内核中安全地执行自定义代码。通过eBPF,开发者可以在不修改内核源码的情况下,对内核功能进行扩展和监控。eBPFTracing利用这一技术,对系统调用、内核函数等进行跟踪,从而实现对应用行为的深入洞察。与传统的监控方式相比,eBPFTracing具有以下......
  • Python教程(十七):协程、 asyncio与 aiohttp【异步IO】
    文章目录专栏列表1.异步IO的基本概念1.1同步与异步1.2协程1.3asyncio1.4aiohttp2.携程2.1定义协程2.2运行协程3.asyncio3.1事件循环解释3.2获取文件示例3.2并发获取文件示例4.aiohttp:异步HTTP客户端/服务器4.1安装aiohttp4.2异步HTTP请求4.3异......
  • 基于 Zynq-7 的高性能 PCIe 载板
    基于Zynq-7的高性能PCIe载板是一款高性能PCIe2.0X8的载板,板载1个HPC形式的FMC连接器。主控芯片采用Xilinx公司Zynq-7系列SoC家族中的XC7Z100-2FFG900I(兼容XC7Z045-2FFG900和XC7Z035-2FFG900)。其PS搭配2颗16bit-1866的512MBDDR3SDRAM和一片256Mb......
  • 如何查看极狐GitLab 的组件状态?
    本文分享使用gitlab-ctl命令来对极狐GitLab的组件进行状态查询和关闭与重启等操作。极狐GitLab是一个多组件系统,主要组件包括:GitalyGitLabexporterNginxRedisSidekiqPostgreSQLPumaWorkhorseRegistrygitlab-ctl可以对上述组件的状态进行查询,以及关闭、重启等。......
  • Project 1: Specification for Automail
    Project1:SpecificationforAutomailBackground:AutomailDeliveringSolutionsInc.(DS)hasrecentlydevelopedandprovidedaRoboticMailDeliverysystemcalledAutomailtothemarket.Automailisanautomatedmailsortinganddeliverysystemdesigned......
  • POLIR-Documents-EnglishLeaening - Recite the America's Founding Documents : The
    https://www.archives.gov/founding-docs/declaration-transcriptTheDeclarationofIndependenceNote:ThefollowingtextisatranscriptionoftheStoneEngravingoftheparchmentDeclarationofIndependence(thedocumentondisplayintheRotundaattheN......