使用GitLab CI/CD部署应用到Kubernetes集群的方案

简介: 使用GitLab CI/CD部署应用到Kubernetes集群的方案

最近业余时间调研了一下在GitLab CI/CD中部署应用到Kubernetes的方案。这是一个老生常谈的话题,很多粉丝和读者问我如何部署应用到K8s中。其实思路是很清晰的,只是其中又很多点大家可能无法串起来。那么本篇文章就带领大家实践一下如何做CD的方案。

本方案的好处就是,读者不需要了解太多关K8s相关知识也可以实现该方案。

Kubernets的命令行工具是kubectl。就像我们使用docker命令来管理docker的镜像,容器一样。
k8s中的所有资源都可以使用kubectl 来进行管理。例如一下几个命令

查看命名空间

kubectl get ns

查看所有命名空间下的pod

kubectl get pods --all-namespaces

查看当前命名空间下的deploment

kubectl get deployment

查看当前命名空间下的service

kubectl get services

部署一个应用

# workload.yaml定义了部署应用的所有参数
kubectl apply -f workload.yaml

一个应用模板

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: ci-test
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx-deploy        
    spec:
      containers:
        - name: nginx-deploy
          imagePullPolicy: Always
          image: nginx
          env:
          - name: TZ
            value: Asia/Shanghai
  selector:
    matchLabels:
      app: nginx-deploy
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-deploy-ci-test
  namespace: ci-test
spec:
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 31594
  selector:
    app: nginx-deploy

kubectl是一个客户端,你可以在本地安装一个kubectl。配置好信息,就可以管理千里之外的k8s集群了。

在CI/CD中我们要部署应用到K8s集群中,也离不开它。
下面进入正题,
这个方案的架构是这样的。

GitLab Runner 是使用docker安装的,执行器为dokcer。(有很多同学不明白为什么在K8s里执行器还用docker啊。这是因为K8s执行器作者也不会啊🤣🤣,确切说,还没学到,实践到那一部分)。一般我都是"一个docker走天下" 能用dokcer装绝不要其他方式装。有条件的同学可以使用k8s作为执行器,动态伸缩还是很好用的。
在流水线中使用kubectl的容器来执行kubectl的命令
预设一个yaml模板来装载应用的部署信息
kubeconfig是存放在宿主机本地,通过挂载目录映射到kubectl的容器中

kubectl镜像的使用

kubectl 的容器我选用的是 bitnami/kubectl

使用方法是

# 获取kubectl的版本号
docker run --rm --name kubectl bitnami/kubectl:latest version

# 挂载目录配置kubectl
docker run --rm --name kubectl -v /path/to/your/kube/config:/.kube/config bitnami/kubectl:latest

特别注意,这个镜像其实是一个二进制文件,要执行命令必须在 docker run ... 的命令后,直接加命令。
注意不要有 kubectl。 比如你要执行 kubectl version 只需要这样写

# 获取kubectl的版本号
docker run --rm --name kubectl bitnami/kubectl:latest version

这也是二进制镜像与其他镜像不一致的地方。想要了解更多里看看 Docker中有关 entrypoint的文档。

kubectl镜像的配置

在安装了kubectl的机器上 输入以下命令可以查看kubectl的配置信息

# 获取kubectl的配置信息
kubectl config view

得到的内容大致是这样的。

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://1.2.3.4:6443
  name: kubernetes
- cluster:
    certificate-authority: C:\Users\fizz\.minikube\ca.crt
    server: https://172.19.226.148:8443
  name: minikube
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: k8s
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {
   }
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: minikube
  user:
    client-certificate: C:\Users\fizz\.minikube\profiles\minikube\client.crt
    client-key: C:\Users\fizz\.minikube\profiles\minikube\client.key

一个yaml格式的内容。
最主要的是clusters contexts users

clusters 是用于配置集群信息的,可以配置多个,每个集群需要集群的证书,服务地址,以及名称。这个集群名称会在下面的contexts(上下文),users(用户)中用到。

contexts是用于kubectl的上下文,有几个上下文,每个上下文都有一个名称,可以使用kubectl来切换上下文,以此来达到管理多个集群的目的。 current-context 表明当前的上下文。

users 是用于配置操作集群的用户。每个用户也都需要配置证书和秘钥。

如果你不知道这个东西怎么生成(其实我也不太清楚),也没关系。只需要知道在哪里拿到就行了。
比如我本地的集群 就在 这个路径下存着C:\Users\fizz\.kube在这里插入图片描述

如果是linux服务器上,那么可以在 ~/.kube/config中找到该文件。

有了这个东西,你就可以为所以为了。在集群想干嘛就干嘛。哈哈...

OK,现在有了配置文件,有了kubectl的镜像。那现在本地环境实验一把。
在本地运行kubectl的容器,挂载一个集群的配置文件,并打印出所有命名空间下的pod

docker run --rm --name kubectl -v /mnt/d/watch/config:/.kube/config bitnami/kubectl:latest get pods --all-namespaces

从下图可以看到,答案符合预期。
在这里插入图片描述

GitLab CI/CD中使用kubectl镜像

在本地验证了使用kubectl镜像管理集群的方案。下面就需要在GitLab CI/CD中来实践。
这里就有一个问题了。
由于kubectl是二进制镜像。在容器运行时必须要执行实质命令。否则会自动退出。那么在GitLab CI/CD该怎么操作那?
总不能在 关键词script中 执行 docker run bitnami/kubectl apply -f workload.yaml 吧。
其实这样应该是可以的,但是很不优雅。优雅的方式是使用 关键词image 指定镜像为 bitnami/kubectl 再进行操作。
但这样做有一个问题,就是无法在运行该容器的时候 执行kubectl的命令。

伟大的GitLab CI/CD开发人员已经想到了这个问题,并给出详细的文档。点击查看详情

在这里插入图片描述

用我二流的英语知识给大家解释一下这段英文的大致意思吧。

有些docker镜像已经定义好了入口,你在run的时候就会执行一些脚本。你要想运行你的命名就只能在run的命令 后加。那么如果我只是想把这个镜像当做基础镜像,真正的脚本定义在script中。
这个时候就使用关键词下image下的 entrypoint 配置项,重置该镜像的入口。覆盖容器运行时的脚本,并将 关键词,before_script, script, after_script三部分定义的脚本都合并起来当做容器运行时的脚本执行。

看懂了这段话,其实答案就呼之欲出了。
job就这样写就可以了

deploy_k8s:
  image:
    name: bitnami/kubectl
    entrypoint: [""]
  script:
    - kubectl version

这样应该就可以了。放到流水线里执行一下。

流水线日志如下,
在这里插入图片描述

答案与预期有些许差异。正确执行了kubectl version命令。但报了一个错。
The connection to the server localhost:8080 was refused - did you specify the right host or port?

聪明的读者一下就猜到了,这是因为kubectl没有配置文件导致的。
那么就给它配一个集群吧。

到这里就剩最后一步了。配置流水线中的kubectl镜像。
由于是流水线中的docker镜像,这里要使用挂载本地目录,将配置信息映射到容器中。我之前有写过一篇文章介绍这一配置。

做法就是
找到GitLab Runner的配置文件 config.toml。
找到对应的runner。
vim /srv/gitlab-runner/config/config.toml

在volumes中增加一个目录挂载。
"/srv/gitlab-runner/config/kubeconfig:/build/kubeconfig:rw"
如下图
在这里插入图片描述

我们需要把kubectl 的配置文件放在宿主机的 /srv/gitlab-runner/config/kubeconfig 目录里。
像这样,文件名为config 不能错。
在这里插入图片描述
配置完后,修改作业测试。

deploy_k8s:
  image:
    name: bitnami/kubectl:latest
    entrypoint: [""]
  before_script:
    - cp -rf /build/kubeconfig/config /.kube/config
  script: 
    - echo "deploy to k8s cluster..."
    - kubectl version
    - kubectl get pods --all-namespaces

编写完提交。 下面就是见证奇迹的时刻了。

在这里插入图片描述

答案诚如我所预期,打印出了集群中所有的命名空间下的pod数据。
你永远可以相信GitLab CI/CD,你永远可以相信我的探索能力。中国人不骗中国人。

如何部署到K8s集群那?
核心命令行就是下面这行。

kubectl apply -f workload.yaml

运行此命令会删除旧的部署,重新部署,即使你二次使用的docker镜像版本一致,内容不一致也能部署成功。apply 大法好。

workload.yaml 这个文件可以直接放在项目根目录,可以使用一些变量来定义镜像地址,镜像版本,部署端口。并在流水线中替换他们。这些都是常规操作。此外还可以加一下部署后的验证。打印一下调试日志。增加部署成功,部署失败的钉钉通知,邮件通知。这些都是附加项,之前也有介绍过。

本文到此就结束了,有关kubectl镜像的使用问题,以及在GitLab CI/CD中使用kubectl镜像的问题让我花了不少时间查阅资料。如果文章对你有帮助。请别忘记点赞。前端P6切图仔,擅长增删改查,略懂GitLab CI/CD。需要你的支持。谢谢。

最后感谢严奇同学提供的集群支持,能让我顺利完成k8s的CD实践,非常感谢。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2天前
|
Prometheus Kubernetes 监控
OpenAI故障复盘 - 阿里云容器服务与可观测产品如何保障大规模K8s集群稳定性
聚焦近日OpenAI的大规模K8s集群故障,介绍阿里云容器服务与可观测团队在大规模K8s场景下我们的建设与沉淀。以及分享对类似故障问题的应对方案:包括在K8s和Prometheus的高可用架构设计方面、事前事后的稳定性保障体系方面。
|
8天前
|
存储 Kubernetes 容器
K8S部署nexus
该配置文件定义了Nexus 3的Kubernetes部署,包括PersistentVolumeClaim、Deployment和服务。PVC请求20Gi存储,使用NFS存储类。Deployment配置了一个Nexus 3容器,内存限制为6G,CPU为1000m,并挂载数据卷。Service类型为NodePort,通过30520端口对外提供服务。所有资源位于`nexus`命名空间中。
|
5天前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
21 2
|
17天前
|
人工智能 Kubernetes 安全
赋能加速AI应用交付,F5 BIG-IP Next for Kubernetes方案解读
赋能加速AI应用交付,F5 BIG-IP Next for Kubernetes方案解读
57 13
|
17天前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
本文源自2024云栖大会苏雅诗的演讲,探讨了K8s集群业务为何需要灾备及其重要性。文中强调了集群与业务高可用配置对稳定性的重要性,并指出人为误操作等风险,建议实施周期性和特定情况下的灾备措施。针对容器化业务,提出了灾备的新特性与需求,包括工作负载为核心、云资源信息的备份,以及有状态应用的数据保护。介绍了ACK推出的备份中心解决方案,支持命名空间、标签、资源类型等维度的备份,并具备存储卷数据保护功能,能够满足GitOps流程企业的特定需求。此外,还详细描述了备份中心的使用流程、控制台展示、灾备难点及解决方案等内容,展示了备份中心如何有效应对K8s集群资源和存储卷数据的灾备挑战。
|
1月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
1月前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
74 1
|
1月前
|
Kubernetes 监控 安全
容器化技术:Docker与Kubernetes的实战应用
容器化技术:Docker与Kubernetes的实战应用
|
1月前
|
存储 Kubernetes Devops
Kubernetes集群管理和服务部署实战
Kubernetes集群管理和服务部署实战
59 0
|
1月前
|
Java Docker 微服务
利用Docker容器化部署Spring Boot应用
利用Docker容器化部署Spring Boot应用
52 0

热门文章

最新文章