首页 > 后端开发 > Golang > 正文

使用 Gitops 和 Kubernetes 在 Golang Web 应用程序上进行 DevOps 管道

Patricia Arquette
发布: 2024-10-24 02:44:29
原创
320 人浏览过

在这篇博文中,我将引导您通过 CI/CD 管道并使用 Gitops 方法在 golang 中自动部署 Web 应用程序。

我们将通过容器化我们的应用程序将其部署在 kubernetes 上,然后使用 ArgoCD 进行部署。

要求

  1. kubernetes 集群 您可以使用 kubernetes 云提供商提供的任何托管服务,或者如果您的系统有足够的资源来配置 kubernetes 集群,您可以使用 Minikube/kind 设置本地 kubernetes 集群
  2. 一个 github 帐户 一个免费帐户就足够了,因为我们将使用 Github Actions 进行持续集成 (CI)
  3. 一个 dockerhub 帐户 我们将使用 dockerhub 来拉取容器镜像
  4. 渴望学习
  5. 不放弃 这是您将面临的重要问题,您应该能够排除并解决它们。在我完成这个项目之前,我必须排除很多次故障。

开始吧

使用多阶段 docker 构建对应用程序进行容器化

为了让 Web 应用程序在所有机器上可用,我们必须将其容器化,而容器化这个词比 docker 更好。
我创建了一个 Dockerfile 来运行该应用程序,但我使用了多阶段格式

为什么要进行多阶段构建?

原因很简单,如果我在单个阶段中创建图像,它将消耗更多的机器空间,而通过使用多阶段构建,我们可以通过分离构建和运行时环境来优化图像的最终大小,并减少攻击我们图像的表面以获得更好的安全性

具体方法如下

  1. 创建一个 dockerfile
  2. 在构建阶段编译应用程序
  3. 将编译后的二进制文件复制到最小的基础映像
  4. 构建镜像并将其推送到 dockerhub,以便 CI 中的 Github Actions 使用该镜像
# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]
登录后复制
登录后复制
登录后复制

现在我们有了 dockerfile,让我们构建它并将其部署到 dockerhub

docker build -t pankaj892/webapp:v1 .

我们尝试检查应用程序是否在本地计算机上按预期运行
docker run -p 8080:8080 pankaj892-webapp:v1

让我们将其推送到 dockerhub
docker Push pankaj892/webapp:v1 .

Kubernetes集群创建

您可以使用 mininkube/kind 在本地创建集群,也可以使用云上的任何一种托管解决方案。我将使用 AWS 的 Elastic Kubernetes Service(EKS)。

您可以使用控制台或命令行在 EKS 中启动集群。我将使用命令行

eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code> 
登录后复制
登录后复制

这将仅选择具有 2 个 vCPU 和 4GB 内存的节点组的机器类型

Helm 图表创建和配置

我们可以一一部署所有资源,但随着规模的扩大,管理它们会很困难,这就是 Helm 的用武之地,它充当包管理器,使用图表来管理我们的所有资源

创建舵图

# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]
登录后复制
登录后复制
登录后复制

Helm 将创建供我们使用的文件,但我们的项目不需要其中的大部分文件。

创建以下文件并添加到helm目录

部署

eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code> 
登录后复制
登录后复制

服务

helm create web-app
登录后复制

入口

# This is a sample deployment manifest file for a simple web application.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        ports:
        - containerPort: 8080
登录后复制

将值文件更新为此

# Service for the application
apiVersion: v1
kind: Service
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: web-app
  type: ClusterIP
登录后复制

Helm 部分现已完成,让我们继续部署我们的 CI

与 Github Actions 的持续集成 (CI)

Github Actions 允许我们根据仓库中的一些事件(如推、拉)自动构建应用程序。

让我们创建管道文件
工作流程文件存储在(.github/workflows/cicd.yml)

# Ingress resource for the application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: web-app.local
    http:
      paths: 
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app
            port:
              number: 80
登录后复制

这个工作流程文件首先从 dockerfile 构建我们的镜像,然后将其推送到 dockerhub,然后在 helm 的 Charts.yaml 文件中更新镜像的标签。

设置 ArgoCD 进行持续交付

我们将使用 argocd 作为我们的 Cd 管道,因为 argocd 将能够从我们的 git 存储库中获取更改并在应用程序中更新它们。

让我们在集群上安装 argocd

kubectl 创建命名空间 argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

要访问 argocd 服务器,我们需要将服务更改为负载均衡器类型

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

对于 Windows,这将是
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

如果它不起作用,只需通过 kubectl 编辑服务并将类型更改为 LoadBalancer 它应该可以工作

现在获取服务的IP

kubectl get svc argocd-server -n argocd

我们获得了 IP,但需要密码才能登录 argocd

kubectl 获取秘密 argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --解码

此命令将获取密码并解码密码,因为密码以 Base64 格式编码

登录后点击“新建项目”>;添加您的项目名称>添加存储库,以便 argocd 可以同步存储库 argocd 将自动查找值文件并在单击提交后选择该文件

Devops pipeline on a Golang Web App with Gitops and Kubernetes

入口和 DNS 映射

我们构建了管道,但我们如何访问我们的应用程序,您不能每次都从 EKS 中输入集群 URL 来访问它,我们需要为此使用入口

我正在使用来自 AWS 的 Nginx Ingress,以便我可以访问该应用程序

在我们的集群上部署入口

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/aws/deploy.yaml

现在 Ingress 已部署,我们需要将来自 EKS 的集群 IP 添加到本地主机文件(对于 Linux,其为 /etc/hosts),对于 Windows,它位于 C:WindowsSystem32etchosts

# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]
登录后复制
登录后复制
登录后复制

现在我们可以在 web-app.local 上访问我们的应用程序

我们已经完成了所有步骤,让我们测试我们的应用程序

Devops pipeline on a Golang Web App with Gitops and Kubernetes

如您所见,顶部的 url 是我们在主机文件中定义的

Devops pipeline on a Golang Web App with Gitops and Kubernetes

我们已经运行了应用程序,让我们添加一些内容并提交到我们的存储库,以便 argocd 可以获取该更改并部署到应用程序

我对我的存储库进行了更改,这应该会触发管道

Devops pipeline on a Golang Web App with Gitops and Kubernetes

管道已启动,完成后让我们看看 argocd 是否接受该更改

Devops pipeline on a Golang Web App with Gitops and Kubernetes

是的,我们看到应用程序发生了变化,argocd 确实拾取了更改并将我们的应用程序与最新更改同步

如果你做到了这一步那么恭喜!!!

这个项目对我来说是一次很棒的学习经历,从在 AWS 上部署 Kubernetes 到创建管道和部署以及对其进行故障排除。这个项目帮助我为 Go 应用程序创建了一个端到端的 DevOps 管道,并且它可以根据需求进行扩展。我计划进行更多探索,例如使用 terraform 或 cloudformation 堆栈部署 eks clutser 并进行更多改进。

如果你遇到困难,可以参考这个仓库

请在评论中告诉我您构建此管道的体验如何。

以上是使用 Gitops 和 Kubernetes 在 Golang Web 应用程序上进行 DevOps 管道的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!