⚠️问题1:在海外部署应用时遇到,海外区域的镜像仓库没有SDK,无法通过内部发布平台推送
⚠️问题2:海外区域镜像仓库没有触发器功能

获取本地最新版本进行推送

内部发布系统构建镜像后,没有变量声明,在推送镜像步骤中无法获取刚打包的镜像版本进行推送。

镜像打包的规则是分支+时间戳,编写脚本通过版本号进行时间排序,拿到最新镜像,进行推送

app="nmk-base"
docker images |grep $app
# 获取镜像的最新版本号
version=`docker images --format "{{.Repository}}:{{.Tag}}" | grep $app | awk -F ':release-' '{print $2}' | sort -nr | head -n 1 | awk '{print "release-" $0}'`
# 登陆镜像仓库
docker login -u nmk-p 29bsd2131 test.nmkapp.com
# 打tag
docker tag $app:$version test.nmkapp.com/prod-app/$app:$version
# 配置代理进行推送到海外镜像仓库
HTTP_PROXY="http://10.8.0.1:8118" HTTPS_PROXY="http://10.8.0.1:8118" docker push test.nmkapp.com/prod-app/$app:$version
sleep 3
# 删除本地镜像
docker rmi $app:$version
docker rmi test.nmkapp.com/prod-app/$app:$version

通过curl请求服务更新镜像

让kimi帮我生成go的脚本,修改好的脚本main.go如下

package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os/exec"
"strings"
)

// RequestData 定义请求的 JSON 数据结构
type RequestData struct {
Image string `json:"image"`
Deployment string `json:"deployment"`
}

func main() {
// 启动 HTTP 服务,监听 8080 端口
http.HandleFunc("/update-image", handleUpdateImage)
fmt.Println("服务已启动,监听 8080 端口...")
log.Fatal(http.ListenAndServe(":8080", nil))
}

// handleUpdateImage 处理 HTTP POST 请求
func handleUpdateImage(w http.ResponseWriter, r *http.Request) {
// 检查请求方法是否为 POST
if r.Method != http.MethodPost {
http.Error(w, "仅支持 POST 请求", http.StatusMethodNotAllowed)
return
}

// 读取请求体
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "读取请求体失败", http.StatusBadRequest)
return
}
defer r.Body.Close()

// 解析 JSON 数据
var data RequestData
if err := json.Unmarshal(body, &data); err != nil {
http.Error(w, "解析 JSON 失败", http.StatusBadRequest)
return
}

// 验证请求数据
if data.Image == "" || data.Deployment == "" {
http.Error(w, "请求参数不完整", http.StatusBadRequest)
return
}

// 从 data.Image 中提取容器名称
imageParts := strings.Split(data.Image, ":")
imagePath := imageParts[0]
pathParts := strings.Split(imagePath, "/")
containerName := pathParts[len(pathParts)-1]

// 执行 kubectl set image 命令
cmd := exec.Command("kubectl", "set", "image", "deployment/"+data.Deployment, containerName+"="+data.Image)
output, err := cmd.CombinedOutput()
if err != nil {
// 如果命令执行失败,返回错误信息
http.Error(w, fmt.Sprintf("执行 kubectl 命令失败: %s", string(output)), http.StatusInternalServerError)
return
}

// 返回成功响应
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "镜像已更新为 %s,Deployment 名称: %s\n输出: %s", data.Image, data.Deployment, string(output))
}

下载相关依赖

go init update-image
go mod tidy

启动服务

go run main.go
服务已启动,监听 8080 端口...

本地测试请求服务

➜  ~ curl -X POST -H "Content-Type: application/json" -d '{"image":"test.nmkapp.com/prod-app/nginx:1.27","deployment":"nginx-deployment"}' http://localhost:8080/update-image
镜像已更新为 test.nmkapp.com/prod-app/nginx:1.27,Deployment 名称: nginx-deployment
输出: deployment.apps/nginx-deployment image updated

# 查看服务已经更新镜像
➜ ~ kubectl get deployments.apps -o yaml |grep image:
- image: test.nmkapp.com/prod-app/nginx:1.27

打包出linux脚本

GOOS=linux GOARCH=amd64 go build -o update-image

服务器端配置

# 安装Kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
mv -f kubectl /usr/local/bin
mkdir -p $HOME/.kube
# 配置kubeconfig
mv -f kubeconfig $HOME/.kube/config
kubectl config use-context internal

把打包出的update-image上传到服务器,启动服务

nohup ./update-image &

配置公网elb转发到服务器内,并设置白名单

本地请求服务

curl -X POST -H Content-Type: application/json -d {"image":"test.nmkapp.com/prod-app/nmk-base:release-20250331154728","deployment":"nmk-base"} http://181.71.101.211:8080/update-image
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 297 100 181 100 116 314 201 --:--:-- --:--:-- --:--:-- 314
镜像已更新为 test.nmkapp.com/prod-app/nmk-base:release-20250331154728,Deployment 名称: nmk-base
输出: deployment.apps/nmk-base image updated

查看是否更新完成