51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

使用GitHub Actions实现CI/CD流水线

关于GitHub Actions和Terraform {#%E5%85%B3%E4%BA%8Egithub-actions%E5%92%8Cterraform}

GitHub Actions 是 GitHub 提供的一个强大而灵活的自动化工具,能够帮助开发者实现持续集成(CI)和持续交付/部署(CD)流水线。它能够让开发者在代码库的不同阶段(如代码提交、拉取请求、发布等)自动触发构建、测试、部署等任务。借助 GitHub Actions,开发者可以通过自定义的 YAML 文件定义工作流,实现从代码提交到应用发布的全自动化过程。
Terraform是目前最热门的基础设施即代码工具,它能够以脚本的形式定义基础设施配置,这极大地增强了基础设施的可复用性,并且可以更好的同CI/CD流水线集成。

GitHub Actions的优势 {#github-actions%E7%9A%84%E4%BC%98%E5%8A%BF}

深度集成:GitHub Actions 与 GitHub 仓库无缝集成,可以根据事件自动触发工作流,适用于各类开发项目。
灵活性高:支持高度自定义的工作流,开发者可以根据不同的项目需求,灵活地配置不同的任务、条件和依赖
生态系统丰富:GitHub Marketplace 提供了数千个现成的 Actions(如容器部署、测试工具、CI/CD 任务等),开发者可以方便地复用已有组件,减少重复工作。
并行化任务执行:GitHub Actions 可以让多个任务并行运行,提升 CI/CD 的效率,适应大型项目的复杂需求。
可扩展性强: GitHub actions可以与主流云计算平台相结合,实现无缝的云部署。
实践:通过GitHub Actions实现自动化构建docker镜像并部署到Azure Kubernetes上

项目链接: GitHub - chunyiw8080/sit722-part5 Contribute to chunyiw8080/sit722-part5 development by creating an account on GitHub. GitHub chunyiw8080

使用Terraform创建Azure Kubernetes集群和Container Registry镜像存储库 {#%E4%BD%BF%E7%94%A8terraform%E5%88%9B%E5%BB%BAazure-kubernetes%E9%9B%86%E7%BE%A4%E5%92%8Ccontainer-registry%E9%95%9C%E5%83%8F%E5%AD%98%E5%82%A8%E5%BA%93}

Terraform脚本可以参照之前的这篇文章,需要将variables中设置的默认值清空 使用Terraform部署Azure Kubernetes和Container Regsitry 基础设施即代码(Infrastructure as Code,简称 IaC)是一种通过代码管理和自动化部署基础设施的方法。随着云计算的发展,手动配置和管理资源的复杂性与日俱增,IaC 通过将基础设施的配置与应用代码一样进行版本控制和自动化部署,大大提高了部署效率、可靠性和可重复性。 Terraform是目前最流行的 IaC 工具之一,它能通过定义"计划文件"来描述云资源,用户可以用它来管理各种基础设施,包括虚拟机、网络、存储、容器服务等。它的优势在于对多种云平台的支持,无论是 AWS、Azure、Google Cloud,还是本地的私有云,Terraform 都能够帮助用户自动化部署复杂的云环境。 本文将讨论如何使用 Terraform 在 Azure 平台上自动化部署 Kubernetes 集群和镜像存储库(如 Azure Container Registry)。通过将 Terraform 与 Azure 云平台结合,可以轻松实现 FreelyTomorrow FreelyTomorrow

编写Shell脚本 {#%E7%BC%96%E5%86%99shell%E8%84%9A%E6%9C%AC}

GitHub Actions会使用Linux环境执行Workflow中的操作,因此将所有涉及到的命令拆分为多个Shell脚本效率更高,也更便于修改。

构建镜像脚本 {#%E6%9E%84%E5%BB%BA%E9%95%9C%E5%83%8F%E8%84%9A%E6%9C%AC}

                  
                    set -u
: $CONTAINER_REGISTRY
: $VERSION

docker build -t $CONTAINER_REGISTRY/book-catalog:$VERSION --file ./book_catalog/Dockerfile .
docker build -t $CONTAINER_REGISTRY/inventory:$VERSION --file ./inventory_management/Dockerfile .


                  </code>
                </pre>



 
#### 推送镜像脚本 {#%E6%8E%A8%E9%80%81%E9%95%9C%E5%83%8F%E8%84%9A%E6%9C%AC}


 
`````````bash
                  
                    set -u
: "$CONTAINER_REGISTRY"
: "$VERSION"
: "$REGISTRY_UN"
: "$REGISTRY_PW"

echo $REGISTRY_PW \| docker login $CONTAINER_REGISTRY --username $REGISTRY_UN --password-stdin
docker push $CONTAINER_REGISTRY/book-catalog:$VERSION
docker push $CONTAINER_REGISTRY/inventory:$VERSION


                  </code>
                </pre>



 
#### 部署脚本 {#%E9%83%A8%E7%BD%B2%E8%84%9A%E6%9C%AC}


 
````````bash
                  
                    set -u
: "$CONTAINER_REGISTRY"
: "$VERSION"
: "$DB_URL"

envsubst \< ./scripts/kubernetes/configmap.yaml \| kubectl apply -f -
envsubst \< ./scripts/kubernetes/service.yaml \| kubectl apply -f -
envsubst \< ./scripts/kubernetes/deployment.yaml \| kubectl apply -f -


                  </code>
                </pre>



 
其中 ` envsubst ` 命令能将后面文件中的环境变量占位符替换为当前环境中的实际值。

 
#### 删除脚本 {#%E5%88%A0%E9%99%A4%E8%84%9A%E6%9C%AC}


 
```````bash
                  
                    set -u
: "$CONTAINER_REGISTRY"
: "$VERSION"
: "$DB_URL"

envsubst \< ./scripts/kubernetes/deployment.yaml \| kubectl delete -f -
envsubst \< ./scripts/kubernetes/service.yaml \| kubectl delete -f -
envsubst \< ./scripts/kubernetes/configmap.yaml \| kubectl delete -f -


                  </code>
                </pre>



 
### 编写GitHub workflow配置 {#%E7%BC%96%E5%86%99github-workflow%E9%85%8D%E7%BD%AE}


 
#### Apply terraform yaml {#apply-terraform-yaml}


 
在编写配置之前,需要做一些准备工作

 
         

  
          
* 创建Azure服务主体 
   Azure服务主体包含了一些数据,如CLIENT_ID,CLIENT_SECRET和TENANT_ID,这些数据可以用来免交互登录Azure。使用如下命令:

 
         

 
``````bash
                  
                    az ad sp create-for-rbac --name <服务主体名称> --role Owner --scopes /subscriptions/<你的subscriptions ID> --sdk-auth

                  </code>
                </pre>



 
该命令执行成功后会生成一个Json文件,保存好该文件

 
           

  
            
* 为GitHub账户创建Personal access tokens 
   该字符可以让GitHub Actions执行器访问GitHub仓库中的secrets并设置。

 
           

 
           
  https://github.com/settings/tokens?ref=blog.freelytomorrow.com
 
           
 
           

  
            
* 编写Workflow配置

 
           

 
`````yaml
                  
                    name: Terraform Apply
# 仅限手动构建,如果使用branches关键字,可以指定当代码被推送到对应分支是触发自动构建
on:
  workflow_dispatch:

jobs:
terraform:
name: Terraform apply
runs-on: ubuntu-latest


    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Set up Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.6
        # 使用之前生成的服务主体数据
      - name: Azure Login
        run: az login --service-principal -u ${{ secrets.CLIENT_ID }} -p ${{ secrets.CLIENT_SECRET }} --tenant ${{ secrets.TENANT_ID }}

      - name: Terraform Init
        working-directory: ./scripts/terraform
        run: terraform init
        # ${{ vars.AZURE_RESOURCE_NAME }}等变量保存在GitHub仓库中的Repository variables列表下,由于这些内容并非机密数据,因此不必设置为secrets
        # 这些变量指定的Terraform资源所使用的资源组名,位置,K8s集群和容器注册表名称以及K8s版本
      - name: Terraform Apply
        working-directory: ./scripts/terraform
        run: terraform apply -auto-approve -var "resource_group_name=${{ vars.AZURE_RESOURCE_NAME }}" -var "location=${{ vars.AZURE_RESOURCE_LOCATION }}" -var "app_name=${{ vars.APP_NAME }}" -var "kubernetes_version=${{ vars.AZURE_AKS_VERSION }}"
        continue-on-error: true

        # 安装后续操作所需的依赖,其中gh为GitHub-Cli,jq用来过滤Json数据
      - name: Install dependencies
        run: |
          sudo apt install gh -y
          sudo apt install jq -y

        # 这里的Token是先前创建的Personal access tokens
      - name: GitHub-Cli login
        run: |
          echo "${{ secrets.TOKEN }}" | gh auth login --with-token

        # 刷新Terraform状态
      - name: Refresh terraform state
        run: terraform refresh

        # 通过gh命令设置Secrets
      - name: Set Secrets
        run: |
          acr_name=$(az acr list | jq -r '.[0].loginServer')
          gh secret set CONTAINER_REGISTRY --body "$acr_name"

          az acr credential show --name "$acr_name" --query "{username:username, passwords:passwords[0].value}" --output json &gt; credentials.json
          gh secret set REGISTRY_UN --body "$(cat credentials.json | jq -r '.username')"
          gh secret set REGISTRY_PW --body "$(cat credentials.json | jq -r '.passwords')"

          az aks get-credentials --resource-group ${{ vars.AZURE_RESOURCE_NAME }} --name ${{ vars.APP_NAME }}  
          gh secret set KUBE_CONFIG --body "$(cat ~/.kube/config | base64 -w 0)"

                  </code>
                </pre>



 
#### Deploy Microservice yaml {#deploy-microservice-yaml}


 
````yaml
                  
                    name: Deploy microservice
on:
  workflow_dispatch:

将要运行的任务
=======



jobs:
deploy:
runs-on: ubuntu-latest
# 环境变量,这些变量在仓库的secrets中声明和配置
env:
VERSION: ${{ github.sha }}
CONTAINER_REGISTRY: ${{ secrets.CONTAINER_REGISTRY }}
REGISTRY_UN: ${{ secrets.REGISTRY_UN }}
REGISTRY_PW: ${{ secrets.REGISTRY_PW  }}
DB_URL: ${{ secrets.DB_URL }}
# 具体的任务步骤
steps:
# actions/checkout:GitHub 官方提供的一个标准 Action,用来将代码库的当前版本拉取到虚拟机或容器中。
- uses: actions/checkout@v3
- name: Build images
run: bash ./scripts/build-image.sh
- name: Push image
run: bash ./scripts/push-image.sh
# tale/kubectl-action:一个第三方 Action,用于在 GitHub Actions 工作流中执行 kubectl 命令,管理 Kubernetes 集群
- uses: tale/kubectl-action@v1
with:
# 经过 base64 编码的 Kubernetes 配置文件
base64-kube-config: ${{ secrets.KUBE_CONFIG }}
# 指定 kubectl 的版本号
kubectl-version: v1.30.3
- name: Deploy
run: bash ./scripts/deploy.sh


                  </code>
                </pre>



 
#### Delete Microservice yaml {#delete-microservice-yaml}


 
和Deploy差不多,只不过在关键的地方使用 ` delete.sh ` 脚本触发kubectl delete操作。

 
```yaml
                  
                    name: Delete microservice

on:
workflow_dispatch:


jobs:


deploy:
runs-on: ubuntu-latest


    env:
      VERSION: ${{ github.sha }}
      CONTAINER_REGISTRY: ${{ secrets.CONTAINER_REGISTRY }}
      REGISTRY_UN: ${{ secrets.REGISTRY_UN }}
      REGISTRY_PW: ${{ secrets.REGISTRY_PW  }}
      DB_URL: ${{ secrets.DB_URL }}

    steps:
      - uses: actions/checkout@v3
      - uses: tale/kubectl-action@v1
        with:
          base64-kube-config: ${{ secrets.KUBE_CONFIG }}
          kubectl-version: v1.30.3
      - name: delete
        run: ./scripts/delete.sh

                  </code>
                </pre>



 
### 在仓库的secrets中声明和配置变量 {#%E5%9C%A8%E4%BB%93%E5%BA%93%E7%9A%84secrets%E4%B8%AD%E5%A3%B0%E6%98%8E%E5%92%8C%E9%85%8D%E7%BD%AE%E5%8F%98%E9%87%8F}


 
需要将azure登录凭据和gh登录凭据存储到secrets中,其他的secrets会通过gh命令在执行Actions自动设置。

 
### 触发构建 {#%E8%A7%A6%E5%8F%91%E6%9E%84%E5%BB%BA}


 
在GitHub仓库中点击 ` Actions ` ,在workflow中找到 ` Deploy microservice ` ,然后点击 ` Run workflow ` 就可以触发构建。

 
当右上角出现对号图标,意味着构建成功。 
 值得注意的是,GitHub Actions构建成功不一定代表部署成功,比如如果Kubernetes配置文件中存在错误,除非是会导致 ` exit code 1 ` 的语法错误,否则是不会提示错误的。

 
同理,要想删除部署,只需要点击 ` Delete microservice ` 并运行构建。


```


````


`````


``````


```````


````````


`````````

赞(0)
未经允许不得转载:工具盒子 » 使用GitHub Actions实现CI/CD流水线