Update master.yml
This commit is contained in:
parent
f7d6ce64ec
commit
f77dc90773
178
.github/workflows/master.yml
vendored
178
.github/workflows/master.yml
vendored
@ -1,11 +1,27 @@
|
|||||||
# 复制到 itfx: .github/workflows/deploy.yml
|
# 复制到 itfx 仓库: .github/workflows/deploy.yml
|
||||||
# Secrets: SSH_HOST(42), SSH_USERNAME, SSH_PASSWORD
|
#
|
||||||
# 集群: ./scripts/16-setup-kaniko.sh
|
# 集群一次性准备(在 42 上):
|
||||||
|
# GIT_TOKEN=... TCR_USERNAME=... TCR_PASSWORD=... ./scripts/16-setup-kaniko.sh
|
||||||
|
#
|
||||||
|
# GitHub Secrets(本仓 Settings → Secrets):
|
||||||
|
# SSH_K3S_HOST — 42 公网 IP
|
||||||
|
# SSH_K3S_USERNAME — 一般 root
|
||||||
|
# SSH_K3S_PASSWORD — SSH 密码
|
||||||
|
#
|
||||||
|
# 排障:看哪个 step 红了
|
||||||
|
# 1 print-info — 仅输出变量,几乎不会挂
|
||||||
|
# 2 check-cluster — SSH / kubeconfig / 节点不通
|
||||||
|
# 3 check-secrets — 未跑 16-setup-kaniko,或 Secret 名不对
|
||||||
|
# 4 kaniko-build — 拉代码 / Dockerfile / 推 TCR(看 Job 日志)
|
||||||
|
# 5 set-image — Deployment 名或容器名不对
|
||||||
|
# 6 rollout — 镜像拉不下来 / 探针失败 / 资源不够
|
||||||
|
#
|
||||||
name: Build and Deploy
|
name: Build and Deploy
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [master]
|
branches: [master]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GIT_URL: https://github.com/xiaoliutral/itfx.git
|
GIT_URL: https://github.com/xiaoliutral/itfx.git
|
||||||
@ -15,31 +31,167 @@ env:
|
|||||||
CONTAINER_NAME: interfaceforward-api
|
CONTAINER_NAME: interfaceforward-api
|
||||||
TCR_REGISTRY: ccr.ccs.tencentyun.com
|
TCR_REGISTRY: ccr.ccs.tencentyun.com
|
||||||
TCR_NAMESPACE: ideship
|
TCR_NAMESPACE: ideship
|
||||||
|
K3S_DIR: /data/k3s
|
||||||
|
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
||||||
|
NAMESPACE: prod
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Kaniko build + deploy
|
# ── 0. 本机算出 TAG / 完整镜像名(不 SSH)────────────────
|
||||||
|
- name: "0. print build info"
|
||||||
|
id: info
|
||||||
|
run: |
|
||||||
|
TAG="${{ github.sha }}"
|
||||||
|
IMG="${{ env.TCR_REGISTRY }}/${{ env.TCR_NAMESPACE }}/${{ env.IMAGE_NAME }}:${TAG}"
|
||||||
|
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "image=${IMG}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "======= build info ======="
|
||||||
|
echo "repo = ${{ github.repository }}"
|
||||||
|
echo "ref = ${{ github.ref_name }}"
|
||||||
|
echo "sha = ${TAG}"
|
||||||
|
echo "git_url = ${{ env.GIT_URL }}"
|
||||||
|
echo "dockerfile = ${{ env.DOCKERFILE }}"
|
||||||
|
echo "image = ${IMG}"
|
||||||
|
echo "deploy = ${{ env.NAMESPACE }}/deploy/${{ env.DEPLOY_NAME }}"
|
||||||
|
echo "=========================="
|
||||||
|
|
||||||
|
# ── 1. SSH + 集群是否通 ─────────────────────────────────
|
||||||
|
- name: "1. check cluster (SSH + kubectl)"
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.SSH_K3S_HOST }}
|
host: ${{ secrets.SSH_K3S_HOST }}
|
||||||
username: ${{ secrets.SSH_K3S_HOST }}
|
username: ${{ secrets.SSH_K3S_USERNAME }}
|
||||||
password: ${{ secrets.SSH_K3S_HOST }}
|
password: ${{ secrets.SSH_K3S_PASSWORD }}
|
||||||
|
script_stop: true
|
||||||
script: |
|
script: |
|
||||||
set -e
|
set -euo pipefail
|
||||||
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
|
export KUBECONFIG="${{ env.KUBECONFIG }}"
|
||||||
cd /data/k3s
|
echo "==> whoami: $(whoami) @ $(hostname)"
|
||||||
TAG="${{ github.sha }}"
|
echo "==> kubeconfig: ${KUBECONFIG}"
|
||||||
IMG="${{ env.TCR_REGISTRY }}/${{ env.TCR_NAMESPACE }}/${{ env.IMAGE_NAME }}:${TAG}"
|
test -f "${KUBECONFIG}" || { echo "FAIL: 找不到 ${KUBECONFIG}"; exit 1; }
|
||||||
|
test -d "${{ env.K3S_DIR }}" || { echo "FAIL: 找不到 ${{ env.K3S_DIR }},请把 k3s 清单同步到该目录"; exit 1; }
|
||||||
|
test -x "${{ env.K3S_DIR }}/scripts/ci-kaniko-build.sh" || {
|
||||||
|
echo "FAIL: 缺少可执行脚本 ${{ env.K3S_DIR }}/scripts/ci-kaniko-build.sh"
|
||||||
|
ls -la "${{ env.K3S_DIR }}/scripts/" || true
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
echo "==> nodes:"
|
||||||
|
kubectl get nodes -o wide
|
||||||
|
echo "==> namespace ${{ env.NAMESPACE }}:"
|
||||||
|
kubectl get ns "${{ env.NAMESPACE }}"
|
||||||
|
echo "==> deploy/${{ env.DEPLOY_NAME }}:"
|
||||||
|
kubectl -n "${{ env.NAMESPACE }}" get deploy "${{ env.DEPLOY_NAME }}" -o wide
|
||||||
|
|
||||||
|
# ── 2. Kaniko 凭据是否已创建 ────────────────────────────
|
||||||
|
- name: "2. check kaniko secrets"
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_K3S_HOST }}
|
||||||
|
username: ${{ secrets.SSH_K3S_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_K3S_PASSWORD }}
|
||||||
|
script_stop: true
|
||||||
|
script: |
|
||||||
|
set -euo pipefail
|
||||||
|
export KUBECONFIG="${{ env.KUBECONFIG }}"
|
||||||
|
NS="${{ env.NAMESPACE }}"
|
||||||
|
echo "==> 检查 Secret(由 16-setup-kaniko.sh 创建)"
|
||||||
|
kubectl -n "$NS" get secret kaniko-git -o jsonpath='{.metadata.name}{" keys="}{.data}{"\n"}' >/dev/null \
|
||||||
|
&& echo "OK secret/kaniko-git" \
|
||||||
|
|| { echo "FAIL: 缺少 secret/kaniko-git — 在 42 执行: GIT_TOKEN=... ./scripts/16-setup-kaniko.sh"; exit 1; }
|
||||||
|
kubectl -n "$NS" get secret kaniko-docker-config >/dev/null \
|
||||||
|
&& echo "OK secret/kaniko-docker-config" \
|
||||||
|
|| { echo "FAIL: 缺少 secret/kaniko-docker-config — TCR 账号未写入"; exit 1; }
|
||||||
|
echo "==> build 节点:"
|
||||||
|
kubectl get nodes -l role=build -o wide
|
||||||
|
COUNT="$(kubectl get nodes -l role=build --no-headers 2>/dev/null | wc -l | tr -d ' ')"
|
||||||
|
if [[ "${COUNT}" == "0" ]]; then
|
||||||
|
echo "FAIL: 没有 role=build 节点,Kaniko Job 会 Pending"
|
||||||
|
kubectl get nodes --show-labels
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Kaniko 构建并推 TCR(最慢,失败看 Job 日志)─────
|
||||||
|
- name: "3. kaniko build & push"
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_K3S_HOST }}
|
||||||
|
username: ${{ secrets.SSH_K3S_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_K3S_PASSWORD }}
|
||||||
|
command_timeout: 50m
|
||||||
|
script_stop: true
|
||||||
|
script: |
|
||||||
|
set -euo pipefail
|
||||||
|
export KUBECONFIG="${{ env.KUBECONFIG }}"
|
||||||
|
cd "${{ env.K3S_DIR }}"
|
||||||
|
TAG="${{ steps.info.outputs.tag }}"
|
||||||
|
echo "==> 开始 Kaniko: ${{ env.IMAGE_NAME }}:${TAG}"
|
||||||
|
echo " 失败时在 42 执行:"
|
||||||
|
echo " kubectl -n ${{ env.NAMESPACE }} get job -l app=kaniko"
|
||||||
|
echo " kubectl -n ${{ env.NAMESPACE }} logs -l job-name=... -c git"
|
||||||
|
echo " kubectl -n ${{ env.NAMESPACE }} logs -l job-name=... -c kaniko"
|
||||||
./scripts/ci-kaniko-build.sh \
|
./scripts/ci-kaniko-build.sh \
|
||||||
"${{ env.GIT_URL }}" \
|
"${{ env.GIT_URL }}" \
|
||||||
"${{ env.DOCKERFILE }}" \
|
"${{ env.DOCKERFILE }}" \
|
||||||
"${{ env.IMAGE_NAME }}" \
|
"${{ env.IMAGE_NAME }}" \
|
||||||
"${TAG}" \
|
"${TAG}" \
|
||||||
"${TAG}"
|
"${TAG}"
|
||||||
|
echo "==> 镜像已推送: ${{ steps.info.outputs.image }}"
|
||||||
|
|
||||||
kubectl -n prod set image "deploy/${{ env.DEPLOY_NAME }}" \
|
# ── 4. 改 Deployment 镜像 ───────────────────────────────
|
||||||
|
- name: "4. set deployment image"
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_K3S_HOST }}
|
||||||
|
username: ${{ secrets.SSH_K3S_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_K3S_PASSWORD }}
|
||||||
|
script_stop: true
|
||||||
|
script: |
|
||||||
|
set -euo pipefail
|
||||||
|
export KUBECONFIG="${{ env.KUBECONFIG }}"
|
||||||
|
NS="${{ env.NAMESPACE }}"
|
||||||
|
IMG="${{ steps.info.outputs.image }}"
|
||||||
|
echo "==> 当前镜像:"
|
||||||
|
kubectl -n "$NS" get deploy "${{ env.DEPLOY_NAME }}" \
|
||||||
|
-o jsonpath='{.spec.template.spec.containers[?(@.name=="${{ env.CONTAINER_NAME }}")].image}{"\n"}'
|
||||||
|
echo "==> 设为: ${IMG}"
|
||||||
|
kubectl -n "$NS" set image "deploy/${{ env.DEPLOY_NAME }}" \
|
||||||
"${{ env.CONTAINER_NAME }}=${IMG}"
|
"${{ env.CONTAINER_NAME }}=${IMG}"
|
||||||
kubectl -n prod rollout status "deploy/${{ env.DEPLOY_NAME }}" --timeout=180s
|
echo "==> 已更新:"
|
||||||
|
kubectl -n "$NS" get deploy "${{ env.DEPLOY_NAME }}" \
|
||||||
|
-o jsonpath='{.spec.template.spec.containers[?(@.name=="${{ env.CONTAINER_NAME }}")].image}{"\n"}'
|
||||||
|
|
||||||
|
# ── 5. 等待滚动发布 ─────────────────────────────────────
|
||||||
|
- name: "5. wait rollout"
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_K3S_HOST }}
|
||||||
|
username: ${{ secrets.SSH_K3S_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_K3S_PASSWORD }}
|
||||||
|
command_timeout: 5m
|
||||||
|
script_stop: true
|
||||||
|
script: |
|
||||||
|
set -euo pipefail
|
||||||
|
export KUBECONFIG="${{ env.KUBECONFIG }}"
|
||||||
|
NS="${{ env.NAMESPACE }}"
|
||||||
|
DEP="${{ env.DEPLOY_NAME }}"
|
||||||
|
echo "==> rollout status..."
|
||||||
|
if ! kubectl -n "$NS" rollout status "deploy/${DEP}" --timeout=180s; then
|
||||||
|
echo "FAIL: rollout 超时/失败,诊断信息如下"
|
||||||
|
kubectl -n "$NS" get deploy,rs,pods -l app="${DEP}" -o wide || \
|
||||||
|
kubectl -n "$NS" get pods -o wide | grep -E "${DEP}|NAME" || true
|
||||||
|
kubectl -n "$NS" describe deploy "${DEP}" | tail -60 || true
|
||||||
|
POD="$(kubectl -n "$NS" get pods -l app="${DEP}" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)"
|
||||||
|
if [[ -n "${POD}" ]]; then
|
||||||
|
echo "==> events for ${POD}:"
|
||||||
|
kubectl -n "$NS" describe pod "${POD}" | tail -40 || true
|
||||||
|
echo "==> logs:"
|
||||||
|
kubectl -n "$NS" logs "${POD}" --tail=80 || true
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "==> pods:"
|
||||||
|
kubectl -n "$NS" get pods -o wide | grep -E "${DEP}|NAME" || \
|
||||||
|
kubectl -n "$NS" get pods -o wide
|
||||||
|
echo "OK deployed ${{ steps.info.outputs.image }}"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user