摆脱Jenkins - 使用google cloudbuild 部署 java service 到 compute engine VM

news2024/11/23 13:33:46

在之前 介绍 cloud build 的文章中

初探 Google 云原生的CICD - CloudBuild

已经介绍过, 用cloud build 去部署1个 spring boot service 到 cloud run 是很简单的, 因为部署cloud run 无非就是用gcloud 去部署1个 GAR 上的docker image 到cloud run 容器
yaml file 例子:

steps:
  - id: check maven and jdk version
    name: maven:3.9.6-sapmachine-17 # https://hub.docker.com/_/maven
    entrypoint: mvn
    args: ['--version']

  - id: run maven test
    name: maven:3.9.6-sapmachine-17 # https://hub.docker.com/_/maven
    entrypoint: mvn
    args: ['test']

  - id: run maven package
    name: maven:3.9.6-sapmachine-17 # https://hub.docker.com/_/maven
    entrypoint: mvn
    args: ['package', '-Dmaven.test.skip=true']

  # https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values
  - id: build docker image
    name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/demo-cloud-user', '.']

  - id: upload docker image to GAR
    name: 'gcr.io/cloud-builders/docker'
    args: [ 'push', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/demo-cloud-user']

  # deploy to Cloud run
  - id: deploy image to cloud run
    name: 'gcr.io/cloud-builders/gcloud'
    args: ['run', 'deploy', 'demo-cloud-user',
           '--image=europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/demo-cloud-user',
           '--port=8080',
           '--platform=managed',
           '--region=europe-west2',
           '--no-allow-unauthenticated',
           '--service-account=vm-common@jason-hsbc.iam.gserviceaccount.com',
           '--key=projects/$PROJECT_ID/locations/europe-west2/keyRings/mykeyring/cryptoKeys/mycmek']
# https://stackoverflow.com/questions/68779751/error-publishing-source-code-from-cloud-build-to-a-bucket-using-triggers
logsBucket: gs://jason-hsbc_cloudbuild/logs/
options: # https://cloud.google.com/cloud-build/docs/build-config#options
  logging: GCS_ONLY # or CLOUD_LOGGING_ONLY https://cloud.google.com/cloud-build/docs/build-config#logging



部署到GCE的问题

但是cloud build 本身是1个non-vpc product, 是无法直接通过 GCE vm的subnet ip address 去连接vm的.

但是
gcloud compute ssh 本身是可以直接用 ssh key file 验证的
而且
gcloud compute ssh 后面可以带 – 参数执行1段 指定的命令

所以实际上不同过内网ip 连接. 那就是讲用cloud build 部署service 到 vm的方案是可行的




部署到GCE的思路

  1. 首先 准备1对ssh key pair, 并把public key安装在对应的vm中, 确保可以用private key登陆

  2. 把这对key pari 放在 google security manager 中

  3. 在 cloudbuild yaml 中把 这对key pari 引入, 虽然理论上只需要私钥就可以, 但是cloudbuild 也需要校验public key 奇怪了

  4. 编写cloudbuild yaml

    a. mvn build
    b. build docker image
    c. push docker image to GAR
    d. 利用 gcloud compute ssh 连接vm
    	执行:
    	1. docker stop current container
    	2. docker pull latest image
    	3. docker run container
    
  5. 创建1个cloud build trigger, 当有新的代码push 到指定branch的时候自动出发cloud build, 有1个前提, 这个 code repository 必须是github, github Enterprise, GitLab, BitBucket 之一, 国内的一些代码仓库就算了



实现



1. 准备一对key pair

具体步骤忽略
确保可以用ssh key 登陆 对应的vm

[gateman@manjaro-x13 keys]$ gcloud compute ssh tf-vpc0-subnet0-vm0 --ssh-key-file=/home/gateman/.ssh/id_rsa
No zone specified. Using zone [europe-west2-c] for instance: [tf-vpc0-subnet0-vm0].
External IP address was not found; defaulting to using IAP tunneling.
WARNING: 

To increase the performance of the tunnel, consider installing NumPy. For instructions,
please see https://cloud.google.com/iap/docs/using-tcp-forwarding#increasing_the_tcp_upload_bandwidth

Linux tf-vpc0-subnet0-vm0 5.10.0-30-cloud-amd64 #1 SMP Debian 5.10.218-1 (2024-06-01) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Jun  8 16:15:23 2024 from 35.235.242.17
gateman@tf-vpc0-subnet0-vm0:~$ 



2. 把这对key pari 放在 google security manager 中

key pair 是敏感数据, 建议不要用terraform, 避免敏感数据check in 到代码仓库
在这里插入图片描述



3. 编写cloudbuild.yaml

在这里插入图片描述

注意这里的第一个步是多余的并不起作用, 因为在
deploy image to GCE 这个step中

会利用gcloud 命令重新下载key file pairs
只是简单介绍下引入 secret manager item的方法

至于为何不用第一步的方法, 因为遇到了1个奇怪的错误, prviate key format is not valid.
我已经raised 1个ticket 给google support, 等下文

在这里插入图片描述

cloudbuild-gce.yaml:

steps:

  # to prepare ssh private key file
  - id: prepare ssh private key file
    name: 'ubuntu'
    entrypoint: bash
    args:
      - '-c'
      - |
        echo $$SSH_PRIVATE_KEY | cut -c 1-30
        echo $$SSH_PRIVATE_KEY > /workspace/ssh_key_file
        echo $$SSH_PUBLIC_KEY > /workspace/ssh_key_file.pub
        chmod 600 /workspace/ssh_key_file
        chmod 600 /workspace/ssh_key_file.pub
    secretEnv:
      - 'SSH_PRIVATE_KEY'
      - 'SSH_PUBLIC_KEY'



  - id: run maven package
    name: maven:3.9.6-sapmachine-17 # https://hub.docker.com/_/maven
    entrypoint: mvn
    args: [ 'package' ]

  # https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values
  # i guess I should combine the two steps into one
  - id: build docker image
    name: 'gcr.io/cloud-builders/docker'
    args: [ 'build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}', '.' ]

  - id: upload docker image to GAR
    name: 'gcr.io/cloud-builders/docker'
    args: [ 'push', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}' ]


  - id: deploy image to GCE
    name: 'gcr.io/cloud-builders/gcloud'
    entrypoint: bash
    args:
      - '-c'
      - |
        whoami
        set -x
        mkdir -p /root/.ssh
        gcloud secrets versions access latest --secret=gateman-private-ssh-key > /root/.ssh/id_rsa
        gcloud secrets versions access latest --secret=gateman-public-ssh-key > /root/.ssh/id_rsa.pub
        chmod 600 /root/.ssh/id_rsa
        chmod 600 /root/.ssh/id_rsa.pub
        gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "whoami" 
        gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker container prune -f; sudo docker ps -a"  
        gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker stop ${_APP_NAME} && sudo docker rm ${_APP_NAME}" 
        gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker pull europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}:${_APP_TAG}"
        gcloud compute ssh gateman@${_VM_HOST} --zone=europe-west2-c --quiet --ssh-key-file=/root/.ssh/id_rsa -- "sudo docker run -d -p ${_PORT}:8080 --name ${_APP_NAME} europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/${_APP_NAME}:${_APP_TAG}"
        echo ok
        
 
logsBucket: gs://jason-hsbc_cloudbuild/logs/
options: # https://cloud.google.com/cloud-build/docs/build-config#options
  logging: GCS_ONLY # or CLOUD_LOGGING_ONLY https://cloud.google.com/cloud-build/docs/build-config#logging

# to define
availableSecrets:
  secretManager:
    - versionName: projects/$PROJECT_ID/secrets/gateman-private-ssh-key/versions/latest
      env: 'SSH_PRIVATE_KEY'
    - versionName: projects/$PROJECT_ID/secrets/gateman-public-ssh-key/versions/latest
      env: 'SSH_PUBLIC_KEY'

substitutions:
  _APP_NAME: demo-cloud-user
  _APP_TAG: latest
  _PORT: "8081"
4. 创建1个cloudbuild trigger

# difference between data and resource: data is read only, resource is read and write
data google_service_account "cloudbuild_sa" {
  project = var.project_id
  account_id = "terraform"
}


# referring https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloudbuild_trigger
resource "google_cloudbuild_trigger" "demo_cloud_user-gce-trigger" {
  name = "demo-cloud-user-gce-trigger" # could not contains underscore

  location = var.region_id

  # when use github then should use trigger_template
  github {
    name = "demo_cloud_user"
    owner = "nvd11"
    push {
      branch = "main"
      invert_regex = false # means trigger on branch
    }
  }

  # the
  substitutions = {
    _VM_HOST = "tf-vpc0-subnet0-vm0"
  }

  filename = "cloudbuild-gce.yaml"
  # projects/jason-hsbc/serviceAccounts/terraform@jason-hsbc.iam.gserviceaccount.com
  service_account = data.google_service_account.cloudbuild_sa.id 
}



测试

创建1个commit 并push 到github 的main branch

测试通过, 耗时2分钟多点

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1804385.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GUI编程-01

组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 Java提供了丰富的图形用户界面(Graphics User Interface,GUI)的类库,基于这些类库可以编写窗口程序。 Java关于图形界面的类库主要放在…

【Redis学习笔记05】Jedis客户端(string、list、set)

Jedis客户端 1. 命令 1.1 String类型 1.1.1 常见命令 SET命令 语法:SET key value [EX seconds | PX milliseconds] [NX|XX] 说明:将string类型的value值设置到指定key中,如果之前该key存在,则会覆盖原先的值,原先…

数染色体 算法 python源码

效果图如下: 原图: 完整代码: import cv2 import numpy as np from skimage import measure import randomimage cv2.imread(113.jpg, cv2.IMREAD_GRAYSCALE)blurred_img cv2.GaussianBlur(image, (5, 5), 0)_, binary_image cv2.thresho…

LibreOffice电子表格如何实现快速筛选并将结果放到新的工作表

如果是在excel或者wps中,可能大家都习惯了自动筛选,然后复制到新的工作表或者删除掉复制内容的办法。但是在LibreOffice中,经测试,大数据表的删除或者复制是非常慢的。这也是很多人放弃LibreOffice的原因之一。那么我们如何快速筛…

Rust 实战丨SSE(Server-Sent Events)

📌 SSE(Server-Sent Events)是一种允许服务器向客户端浏览器推送信息的技术。它是 HTML5 的一部分,专门用于建立一个单向的从服务器到客户端的通信连接。SSE的使用场景非常广泛,包括实时消息推送、实时通知更新等。 S…

html+CSS+js部分基础运用18

1. 按键修饰符的应用。①姓名:按下回车键时调用方法输出“姓名-密码”;②密码:按下shift回车时调用方法输出“姓名密码” 图1 初始效果图 图2 按键修饰符效果图 2. 仿淘宝Tab栏切换,熟悉…

自动化您的Instagram帐户的程序InstaBot Pro 7.0.2

InstaBot Pro是一个自动化您的Instagram帐户的程序。InstaBot Pro允许您喜欢,搜索类似帐户上的新订阅者,并让真正的订阅者对您的内容感兴趣。InstaBot Pro还允许您向目标用户或帖子发送自动消息和评论。 InstaBot Pro具有简单方便的界面,您可…

CPU内部结构窥探·「3」

加法器的工作原理:从简单的逻辑到现代计算 我们在cpu内部结构窥探「1」中提到CPU内部ALU的核心部件就是运算器,今天就以加法器为例,来讲解我们ALU中算数逻辑运算的过程。 1.认识数字电路中的各种门电路 2. 什么是加法器? 加法器…

[Algorithm][动态规划][01背包问题][目标和][最后一块石头的重量Ⅱ]详细讲解

目录 1.目标和1.题目链接2.算法原理详解3.代码实现 2.最后一块石头的重量 II1.题目链接2.算法原理详解3.代码实现 1.目标和 1.题目链接 目标和 2.算法原理详解 问题转化:在数组中选择一些数,让这些数的和等于a,一共有多少种选法&#xff1f…

React实战(一)初始化项目、配置router、redux、axios

(一)初始化项目 1.安装项目 npx create-react-app 项目名 编译报错: 解决办法:安装最新的babel-preset-react-app npm install babel-preset-react-applatest 2.配置项目 (1)配置文件目录 (2)使用craco配置webpack.config npm install craco/crac…

HC05蓝牙模块与笔记本蓝牙连接

文章目录 1. 电脑和蓝牙模块连接 2. 串口软件调试 1. 电脑和蓝牙模块连接 HC05支持SPP协议,使用PC主机自带蓝牙,或者笔记本加蓝牙适配器。与HC05连接后,可在电脑端虚拟出串口,这样上位机软件就可以像操作串口一样与HC05通信。对…

什么,一不小心打造了一个基于大模型的操作系统

如果以大模型为Kernel, 形成一个新的操作系统,那么: 1. byzer-llm 是这个大模型操作系统的编程接口,有点类似Linux操作系统的C ABI。 2. byzer-retrieval 也被集成进 byzer- llm 接口里,算是大模型操作系统的文件系统&#xff0c…

风机5G智能制造工厂工业物联数字孪生平台,推进制造业数字化转型

风机5G智能制造工厂工业物联数字孪生平台,推进制造业数字化转型。在信息化、智能化的浪潮中,风机5G智能制造工厂工业物联数字孪生平台正以其独特的优势,推动制造业实现数字化转型。数字孪生平台不仅为风机制造业带来了前所未有的机遇&#xf…

2024年电子工程与自动化技术国际会议(ICEEAT 2024)

2024 International Conference on Electronic Engineering and Automation Technology 【1】大会信息 会议简称:ICEEAT 2024 大会地点:中国西安 审稿通知:投稿后2-3日内通知 【2】会议简介 2024年电子工程与自动化技术国际会议是聚焦电子…

【开发心得】三步本地化部署llama3大模型

目录 第一步:启动ollama 第二步:启动dify 第三步:配置模型(截图) 最近llama3很火,本文追击热点,做一个本地化部署的尝试,结果还成功了! 当然也是站在别人的肩膀上&…

vscode软件上安装 Fitten Code插件及使用

一. 简介 前面几篇文章学习了 Pycharm开发工具上安装 Fitten Code插件,以及 Fitten Code插件的使用。 Fitten Code插件是是一款由非十大模型驱动的 AI 编程助手,它可以自动生成代码,提升开发效率,帮您调试 Bug,节省…

FinalShell导出服务器配置信息密码password是加密的,如何解密?

本章教程,主要实现了一个小的功能,对FinalShell导出的配置信息,进行解密。 FinalShell导出之后,会产生一个json文件,例如下面这种json格式,里面记录了服务器的IP地址,端口和密码,里面的密码是经过加密处理的,本文主要利用java代码实现对这个password进行解密还原。 {&…

Java项目生成方法时序图(查看调用逻辑)

Java项目生成方法时序图(调用逻辑) 在IDEA中下载 SequenceDiagram 插件 右键需要查看的方法 就可以看到调用的时序图了

【栈】2751. 机器人碰撞

本文涉及知识点 栈 LeetCode2751. 机器人碰撞 现有 n 个机器人,编号从 1 开始,每个机器人包含在路线上的位置、健康度和移动方向。 给你下标从 0 开始的两个整数数组 positions、healths 和一个字符串 directions(directions[i] 为 ‘L’ …

test 判断字符串不为空

#!/bin/bash read -p "请输入参数:" name test -z $name if [ $? -eq 1 ]; then echo "入参:$name" else echo "入参为null" fi