从 GitHub Actions 到 HTTPS:完整打通 Harbor + Kubernetes + ArgoCD 的 CI/CD 发布链路

前言

上一篇已经完成了 GitHub Actions 自托管 Runner 的接入,让 k8s-master 可以作为 GitHub Actions 的执行节点。

这样做的原因很简单:我的 Harbor 私有镜像仓库在内网,地址是:

172.16.11.142

GitHub 官方 Runner 无法直接访问这个内网地址,所以必须把 Runner 放到自己的服务器上执行。

这一篇继续完成剩下的部分:

GitHub Actions 自动构建镜像

推送到 Harbor

自动修改 GitOps 配置

ArgoCD 自动同步

Kubernetes 自动发布

Ingress 域名访问

HTTPS 访问

最终访问地址:

https://web.xoho.top
一、当前已有环境

目前已经完成的基础组件如下:

组件 状态
Harbor 私有镜像仓库 已完成
Kubernetes 集群 已完成
GitHub 仓库 已完成
ArgoCD 已完成
GitHub Actions Self-hosted Runner 已完成
Web 应用镜像 已推送 Harbor
NodePort 访问 已验证
Ingress Controller 已部署

当前核心地址:

Harbor:172.16.11.142
K8s Master:172.16.11.142
Ingress 节点:172.16.11.146
GitHub 仓库:YANYUE0721/kgale-web-gitops
域名:web.xoho.top
二、CI/CD 目标

这次要实现的目标是:

提交代码到 GitHub

GitHub Actions 自动触发

Self-hosted Runner 在 k8s-master 上执行任务

Docker build 构建镜像

Docker push 推送到 Harbor

自动更新 Kubernetes YAML 镜像版本

Git push 回 GitHub

ArgoCD 自动同步

Kubernetes 自动更新 Pod

通过域名和 HTTPS 访问新版本

简单说,就是把原来手动做的事情自动化。

三、创建 Web 页面源码

在 GitHub 仓库目录中添加一个简单页面:

cd ~/kgale-web-gitops

cat > index.html <<'EOF'



Kgale CI/CD Demo

Harbor + Kubernetes + GitHub Actions + ArgoCD + ChatGPT 部署成功!

这是通过 CI/CD 自动构建并发布的页面。

镜像来自 Harbor 私有镜像仓库。



EOF

这个页面后面会被打包进 Nginx 镜像中。

四、创建 Dockerfile

创建 Dockerfile:

cat > Dockerfile <<'EOF' FROM nginx:latest COPY index.html /usr/share/nginx/html/index.html EOF 这个 Dockerfile 的作用很简单: 使用 nginx 作为基础镜像 把 index.html 放到 nginx 默认网页目录 五、创建 GitHub Actions 工作流 创建目录: mkdir -p .github/workflows 创建工作流文件: cat > .github/workflows/build-and-deploy.yaml <<'EOF' name: Build and Deploy to Harbor on: push: branches: - main permissions: contents: write jobs: build-and-deploy: if: "!contains(github.event.head_commit.message, '[skip ci]')" runs-on: self-hosted steps: - name: Checkout code uses: actions/checkout@v4 - name: Set image tag run: | echo "IMAGE_TAG=v${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
echo “IMAGE_NAME=172.16.11.142/library/kgale-web:v${GITHUB_RUN_NUMBER}” >> $GITHUB_ENV

– name: Build Docker image
run: |
docker build -t ${IMAGE_NAME} .

– name: Push Docker image to Harbor
run: |
docker push ${IMAGE_NAME}

– name: Update Kubernetes YAML image
run: |
sed -i “s#^[[:space:]]*image: 172.16.11.142/library/kgale-web:.*# image: ${IMAGE_NAME}#g” kgale-web-gitops.yaml

– name: Commit and push updated YAML
run: |
git config user.name “github-actions”
git config user.email “github-actions@github.com”
git add kgale-web-gitops.yaml
git commit -m “update image to ${IMAGE_TAG} [skip ci]” || echo “No changes to commit”
git push
EOF

这里需要注意两点。

第一,使用的是:

runs-on: self-hosted

这表示任务不是在 GitHub 官方服务器上执行,而是在自己的 k8s-master 上执行。

第二,提交信息里加了:

[skip ci]

这是为了避免循环触发。
因为 Workflow 会自动修改 YAML 并 push 回 GitHub,如果不跳过 CI,就会形成无限循环。

六、提交并推送工作流
git add .
git commit -m “add github actions ci workflow”
git push

这里遇到了一个 GitHub 权限问题:

refusing to allow a Personal Access Token to create or update workflow

原因是 Token 没有 workflow 权限。

解决方式是重新生成 GitHub Token,并勾选:

repo
workflow

重新推送后成功。

七、第一次运行失败:sed 命令问题

GitHub Actions 第一次运行失败,失败点在:

Update Kubernetes YAML image

报错:

sed: unknown option to `s’

原因是原来的 sed 命令里使用了 # 作为分隔符,同时替换内容里也带了 # Harbor… 注释,导致 sed 解析混乱。

错误写法类似:

sed -i “s#image: 172.16.11.142/library/kgale-web:.*#image: ${IMAGE_NAME} # Harbor 镜像#g” kgale-web-gitops.yaml

修复后改成:

sed -i “s#^[[:space:]]*image: 172.16.11.142/library/kgale-web:.*# image: ${IMAGE_NAME}#g” kgale-web-gitops.yaml

重新提交:

git add .github/workflows/build-and-deploy.yaml
git commit -m “fix ci workflow sed command”
git push
八、GitHub Actions 成功运行

修复后,Runner 终端显示:

Running job: build-and-deploy
Job build-and-deploy completed with result: Succeeded

这说明 GitHub Actions 已经成功完成:

拉取代码
构建 Docker 镜像
推送镜像到 Harbor
修改 Kubernetes YAML
推送回 GitHub

查看页面后,已经变成了:

Harbor + Kubernetes + GitHub Actions + ArgoCD + ChatGPT 部署成功!

这一步说明 CI/CD 主链路已经跑通。

九、当前完整 CI/CD 链路

此时链路已经变成:

GitHub 提交代码

GitHub Actions 触发

Self-hosted Runner 执行任务

Docker build 构建镜像

Docker push 推送到 Harbor

GitHub Actions 修改 GitOps YAML

Git push 回 GitHub

ArgoCD 检测配置变化

Kubernetes 更新 Deployment

Pod 使用新镜像运行

浏览器访问新页面

这就是完整的 CI/CD 闭环。

十、添加域名解析

为了让服务不再通过 IP 和端口访问,我给域名添加了 DNS 记录。

在 Cloudflare 中添加 A 记录:

类型:A
名称:web
内容:172.16.11.146
代理状态:仅 DNS
TTL:自动

也就是:

web.xoho.top → 172.16.11.146

Windows 上测试:

nslookup web.xoho.top

返回:

Name: web.xoho.top
Address: 172.16.11.146

说明 DNS 已经生效。

十一、创建 Ingress 入口

接下来让访问流量通过 Ingress Controller 进入 Kubernetes。

创建 Ingress 配置:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kgale-web-ingress
namespace: default
spec:
ingressClassName: nginx
rules:
– host: web.xoho.top
http:
paths:
– path: /
pathType: Prefix
backend:
service:
name: kgale-web-gitops-svc
port:
number: 80

提交到 GitHub 后,ArgoCD 自动同步创建 Ingress。

查看状态:

kubectl get ingress

输出:

NAME CLASS HOSTS ADDRESS PORTS AGE
kgale-web-ingress nginx web.xoho.top 172.16.11.146 80 20m

访问:

http://web.xoho.top

成功打开 CI/CD 页面。

至此,HTTP 无端口访问完成。

十二、为什么一开始会有端口?

最开始访问是:

http://web.xoho.top:30084

因为应用是通过 NodePort 暴露的:

80:30084/TCP

浏览器访问非标准端口时,必须写端口号。

后来通过 Ingress Controller 接管 80 端口后,就可以直接访问:

http://web.xoho.top

浏览器默认 HTTP 端口就是 80,所以不需要显示端口。

这一步和常见生产环境的访问方式更接近。

十三、启用 HTTPS

HTTP 成功后,继续做 HTTPS。

先生成自签名证书:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout web.xoho.top.key \
-out web.xoho.top.crt \
-subj “/CN=web.xoho.top/O=kgale”

创建 Kubernetes TLS Secret:

kubectl create secret tls web-xoho-top-tls \
–cert=web.xoho.top.crt \
–key=web.xoho.top.key \
-n default

查看 Secret:

kubectl get secret web-xoho-top-tls

输出:

NAME TYPE DATA AGE
web-xoho-top-tls kubernetes.io/tls 2 4s

说明证书已经写入 Kubernetes。

十四、给 Ingress 添加 TLS

给 Ingress 添加 TLS 配置:

kubectl patch ingress kgale-web-ingress -n default –type=’merge’ -p \
‘{“spec”:{“tls”:[{“hosts”:[“web.xoho.top”],”secretName”:”web-xoho-top-tls”}]}}’

查看 Ingress:

kubectl get ingress

输出:

NAME CLASS HOSTS ADDRESS PORTS AGE
kgale-web-ingress nginx web.xoho.top 172.16.11.146 80, 443 29m

查看 TLS:

kubectl describe ingress kgale-web-ingress | grep -A6 TLS

输出:

TLS:
web-xoho-top-tls terminates web.xoho.top

这说明 HTTPS 已经挂到 Ingress 上。

十五、验证 HTTPS

在服务器上测试:

curl -kI https://web.xoho.top

返回:

HTTP/2 200
content-type: text/html
content-length: 383
strict-transport-security: max-age=31536000; includeSubDomains

这说明 HTTPS 已经成功。

浏览器访问:

https://web.xoho.top

如果浏览器提示证书不安全,这是正常的,因为当前使用的是自签名证书。
自签名证书可以验证 HTTPS 功能,但不会被浏览器默认信任。

十六、最终效果

最终页面显示:

Harbor + Kubernetes + GitHub Actions + ArgoCD + ChatGPT 部署成功!

当前完整访问链路:

https://web.xoho.top

DNS 解析到 172.16.11.146

Ingress Controller 443 端口

TLS Secret 处理 HTTPS

Ingress 规则匹配 web.xoho.top

Service 转发到后端 Pod

Pod 运行 Harbor 中的镜像
十七、最终完成内容

这次完整完成了:

1. GitHub Actions 工作流创建
2. Self-hosted Runner 执行 CI 任务
3. Docker 镜像自动构建
4. 镜像自动推送 Harbor
5. Kubernetes YAML 自动更新镜像版本
6. GitHub 自动保存 GitOps 配置
7. ArgoCD 自动同步配置
8. Kubernetes 自动滚动更新 Pod
9. Ingress 域名入口配置
10. HTTP 无端口访问
11. HTTPS 自签名证书访问

完整组件如下:

组件 作用
GitHub 保存代码和 Kubernetes 配置
GitHub Actions 触发 CI 自动化流程
Self-hosted Runner 在内网执行构建和推送
Docker 构建镜像
Harbor 保存私有镜像
ArgoCD 自动同步 GitOps 配置
Kubernetes 运行应用
Ingress Controller 提供统一访问入口
TLS Secret 提供 HTTPS 证书
十八、总结

这次实验从 CI/CD 自动发布继续往后推进,最终补齐了域名入口和 HTTPS。

现在的整体效果已经比较完整:

开发提交代码

GitHub Actions 自动构建

镜像推送 Harbor

GitOps 配置自动更新

ArgoCD 自动同步

Kubernetes 自动发布

Ingress 提供域名访问

HTTPS 提供加密访问

这套链路已经不是简单的 Kubernetes 部署实验,而是一套完整的 DevOps / GitOps 发布流程。

当前还能继续优化的地方有两个:

1. 把自签名证书换成 Let’s Encrypt 正式证书
2. 把临时 patch 的 HTTPS 配置完全纳入 GitHub 仓库,由 ArgoCD 永久管理

但从功能上看,现在已经完成了完整闭环:

GitHub Actions + Harbor + ArgoCD + Kubernetes + Ingress + HTTPS

至此,本阶段实验完成。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇