From 6ea99f26e2348c497bbdb0759a281245a8453f8d Mon Sep 17 00:00:00 2001 From: offends Date: Fri, 19 Jul 2024 15:19:56 +0800 Subject: [PATCH] synchronization --- .drone-offends.yml | 112 ++++++++++++ .drone.yml | 162 ++++++++++++++++++ .gitignore | 28 +++ Dockerfile-hexo | 20 +++ Dockerfile-hexo-async | 9 + Dockerfile-hexo-async-offends | 12 ++ README.md | 22 +++ app/404.md | 3 + app/_config.async.yml | 282 +++++++++++++++++++++++++++++++ app/index.less | 16 ++ app/init.sh | 163 ++++++++++++++++++ app/languages.yml | 3 + app/links.yml | 8 + app/site.webmanifest | 20 +++ chart/.helmignore | 23 +++ chart/Chart.yaml | 24 +++ chart/README.md | 17 ++ chart/templates/NOTES.txt | 7 + chart/templates/_helpers.tpl | 17 ++ chart/templates/deployment.yaml | 87 ++++++++++ chart/templates/ingress.yaml | 36 ++++ chart/templates/pvc.yaml | 18 ++ chart/templates/service.yaml | 41 +++++ chart/templates/statefulset.yaml | 54 ++++++ chart/values.yaml | 86 ++++++++++ docker-compose.yaml | 50 ++++++ gateway/Dockerfile-docker | 16 ++ gateway/Dockerfile-kubernetes | 11 ++ gateway/default.conf.template | 20 +++ gateway/ssl.conf.template | 33 ++++ kubernetes/blog.yaml | 78 +++++++++ kubernetes/gateway.yaml | 59 +++++++ kubernetes/ingress-nginx.yaml | 30 ++++ kubernetes/ingress-traefik.yaml | 23 +++ kubernetes/namespace.yaml | 4 + kubernetes/twikoo.yaml | 63 +++++++ 36 files changed, 1657 insertions(+) create mode 100644 .drone-offends.yml create mode 100644 .drone.yml create mode 100644 .gitignore create mode 100644 Dockerfile-hexo create mode 100644 Dockerfile-hexo-async create mode 100644 Dockerfile-hexo-async-offends create mode 100644 README.md create mode 100644 app/404.md create mode 100644 app/_config.async.yml create mode 100644 app/index.less create mode 100755 app/init.sh create mode 100644 app/languages.yml create mode 100644 app/links.yml create mode 100644 app/site.webmanifest create mode 100644 chart/.helmignore create mode 100644 chart/Chart.yaml create mode 100644 chart/README.md create mode 100644 chart/templates/NOTES.txt create mode 100644 chart/templates/_helpers.tpl create mode 100644 chart/templates/deployment.yaml create mode 100644 chart/templates/ingress.yaml create mode 100644 chart/templates/pvc.yaml create mode 100644 chart/templates/service.yaml create mode 100644 chart/templates/statefulset.yaml create mode 100644 chart/values.yaml create mode 100644 docker-compose.yaml create mode 100644 gateway/Dockerfile-docker create mode 100644 gateway/Dockerfile-kubernetes create mode 100644 gateway/default.conf.template create mode 100644 gateway/ssl.conf.template create mode 100644 kubernetes/blog.yaml create mode 100644 kubernetes/gateway.yaml create mode 100644 kubernetes/ingress-nginx.yaml create mode 100644 kubernetes/ingress-traefik.yaml create mode 100644 kubernetes/namespace.yaml create mode 100644 kubernetes/twikoo.yaml diff --git a/.drone-offends.yml b/.drone-offends.yml new file mode 100644 index 0000000..fb28916 --- /dev/null +++ b/.drone-offends.yml @@ -0,0 +1,112 @@ +kind: pipeline +type: docker +name: Build Hexo-Async-Offends-Blog + +trigger: + event: + include: + - custom + +steps: +- name: Hexo-Async-Offends-Blog + image: docker:dind + volumes: + - name: dockersock + path: /var/run/docker.sock + - name: kubectl + path: /usr/local/bin/kubectl + - name: config + path: /root/.kube/config + environment: + DOCKER_USERNAME: + from_secret: DOCKER_USERNAME + DOCKER_PASSWORD: + from_secret: DOCKER_PASSWORD + REGISTRY: + from_secret: REGISTRY + REPO: + from_secret: REPO + BUILD: + from_secret: BUILD + commands: + - docker login $REGISTRY -u $DOCKER_USERNAME -p $DOCKER_PASSWORD + - | + if [ -z "$BUILD" ]; then + echo -e "\e[31m变量未指定,请检查Secret\e[0m" + exit 1 + else + if [ -n "$BUILD" ] && { [ "$BUILD" = Hexo-async-offends ] || [ "$BUILD" = "All" ]; }; then + echo -e "\033[32m开始构建\033[0m" + cd /drone/src/ \ + && docker build --build-arg IMAGENAME=registry.cn-hangzhou.aliyuncs.com/offends/hexo:hexo-async -t $REPO:hexo-async-offends -f Dockerfile-hexo-async-offends --no-cache . \ + && docker push $REPO:hexo-async-offends \ + && kubectl -n blog rollout restart deployment blog + else + echo -e "\033[33m不构建,跳过\033[0m" + fi + if [ -n "$BUILD" ] && { [ "$BUILD" = Gateway-kubernetes ] || [ "$BUILD" = "All" ]; }; then + echo -e "\033[32m开始构建\033[0m" + cd /drone/src/gateway \ + && docker build --build-arg IMAGENAME=registry.cn-hangzhou.aliyuncs.com/offends/hexo:nginx-alpine-slim -t $REPO:gateway-kubernetes -f Dockerfile-kubernetes --no-cache . \ + && docker push $REPO:gateway-kubernetes + else + echo -e "\033[33m不构建,跳过\033[0m" + fi + fi +volumes: +- name: dockersock + host: + path: /var/run/docker.sock +- name: kubectl + host: + path: /usr/local/bin/kubectl +- name: config + host: + path: /root/.kube/config +--- +kind: pipeline +type: docker +name: Build Gateway-docker + +trigger: + event: + include: + - custom + +steps: +- name: Gateway-docker + image: docker:dind + volumes: + - name: dockersock + path: /var/run/docker.sock + environment: + DOCKER_USERNAME: + from_secret: DOCKER_USERNAME + DOCKER_PASSWORD: + from_secret: DOCKER_PASSWORD + REGISTRY: + from_secret: REGISTRY + REPO: + from_secret: REPO + BUILD: + from_secret: BUILD + commands: + - | + if [ -z "$BUILD" ]; then + echo -e "\e[31m变量未指定,请检查Secret\e[0m" + exit 1 + else + if [ -n "$BUILD" ] && [ "$BUILD" = Gateway-docker ]; then + echo -e "\033[32m开始构建\033[0m" + cd /drone/src/gateway \ + && docker login $REGISTRY -u $DOCKER_USERNAME -p $DOCKER_PASSWORD \ + && docker build --build-arg IMAGENAME=registry.cn-hangzhou.aliyuncs.com/offends/hexo:nginx-alpine-slim -t $REPO:gateway-docker -f Dockerfile-docker --no-cache . \ + && docker push $REPO:gateway-docker + else + echo -e "\033[33m不构建,跳过\033[0m" + fi + fi +volumes: +- name: dockersock + host: + path: /var/run/docker.sock \ No newline at end of file diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..421a4f1 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,162 @@ +kind: pipeline +type: docker +name: Synchronization Nginx-Images + +trigger: + event: + include: + - custom + +node: + drone: abroad + +steps: +- name: 同步 Nginx-Images + image: docker:dind + volumes: + - name: dockersock + path: /var/run/docker.sock + environment: + DOCKER_USERNAME: + from_secret: DOCKER_USERNAME + DOCKER_PASSWORD: + from_secret: DOCKER_PASSWORD + REGISTRY: + from_secret: REGISTRY + REPO: + from_secret: REPO + BUILD: + from_secret: BUILD + commands: + - | + docker pull nginx:alpine-slim \ + && docker login $REGISTRY -u $DOCKER_USERNAME -p $DOCKER_PASSWORD \ + && docker tag nginx:alpine-slim $REPO:nginx-alpine-slim \ + && docker push $REPO:nginx-alpine-slim +volumes: +- name: dockersock + host: + path: /var/run/docker.sock +--- +kind: pipeline +type: docker +name: Synchronization Twikoo-Images + +trigger: + event: + include: + - custom + +steps: +- name: 同步 Twikoo-Images + image: docker:dind + volumes: + - name: dockersock + path: /var/run/docker.sock + environment: + DOCKER_USERNAME: + from_secret: DOCKER_USERNAME + DOCKER_PASSWORD: + from_secret: DOCKER_PASSWORD + REGISTRY: + from_secret: REGISTRY + REPO: + from_secret: REPO + BUILD: + from_secret: BUILD + commands: + - | + docker pull imaegoo/twikoo:latest \ + && docker login $REGISTRY -u $DOCKER_USERNAME -p $DOCKER_PASSWORD \ + && docker tag imaegoo/twikoo:latest $REPO:twikoo \ + && docker push $REPO:twikoo +volumes: +- name: dockersock + host: + path: /var/run/docker.sock +--- +kind: pipeline +type: docker +name: Build Hexo-Images + +trigger: + event: + include: + - custom + +steps: +- name: 同步 Node-Alpine-Image + image: docker:dind + volumes: + - name: dockersock + path: /var/run/docker.sock + environment: + DOCKER_USERNAME: + from_secret: DOCKER_USERNAME + DOCKER_PASSWORD: + from_secret: DOCKER_PASSWORD + REGISTRY: + from_secret: REGISTRY + REPO: + from_secret: REPO + BUILD: + from_secret: BUILD + commands: + - | + docker pull node:alpine \ + && docker login $REGISTRY -u $DOCKER_USERNAME -p $DOCKER_PASSWORD \ + && docker tag node:alpine $REPO:node-alpine \ + && docker push $REPO:node-alpine +- name: Build Hexo-Images + image: plugins/docker + # 仅当本地不存在该镜像时才拉取 + # pull: if-not-exists + settings: + registry: + from_secret: REGISTRY + username: + from_secret: DOCKER_USERNAME + password: + from_secret: DOCKER_PASSWORD + repo: + from_secret: REPO + # 是否禁止推送镜像 + dry_run: false + tags: + - hexo + context: ./ + dockerfile: ./Dockerfile-hexo + build_args: + - IMAGENAME=registry.cn-hangzhou.aliyuncs.com/offends/hexo:node-alpine + when: + branch: + - main +- name: Build Hexo-Async-Images + image: plugins/docker + # 仅当本地不存在该镜像时才拉取 + # pull: if-not-exists + settings: + registry: + from_secret: REGISTRY + username: + from_secret: DOCKER_USERNAME + password: + from_secret: DOCKER_PASSWORD + repo: + from_secret: REPO + # 是否禁止推送镜像 + dry_run: false + tags: + - hexo-async + context: ./ + dockerfile: ./Dockerfile-hexo-async + build_args: + - IMAGENAME=registry.cn-hangzhou.aliyuncs.com/offends/hexo:hexo + when: + branch: + - main + +volumes: + - name: dockersock + host: + path: /var/run/docker.sock \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4777d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# ---> macOS +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + diff --git a/Dockerfile-hexo b/Dockerfile-hexo new file mode 100644 index 0000000..bf28807 --- /dev/null +++ b/Dockerfile-hexo @@ -0,0 +1,20 @@ +ARG IMAGENAME=node:alpine + +FROM ${IMAGENAME} + +LABEL maintainer="Offends " + +# 开启国内加速 +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ + && apk update + +RUN npm install -g hexo-cli \ + && hexo init hexo \ + && npm install --prefix /hexo/ + +WORKDIR /hexo + +EXPOSE 4000 + +# CMD ["npm", "run", "server] +CMD ["hexo", "server"] diff --git a/Dockerfile-hexo-async b/Dockerfile-hexo-async new file mode 100644 index 0000000..05538b8 --- /dev/null +++ b/Dockerfile-hexo-async @@ -0,0 +1,9 @@ +ARG IMAGENAME + +FROM ${IMAGENAME} + +LABEL maintainer="Offends " + +RUN npm install --save hexo-renderer-less hexo-renderer-ejs \ + && npm i hexo-theme-async@latest \ + && sed -i 's/theme: landscape/theme: async/g' _config.yml \ No newline at end of file diff --git a/Dockerfile-hexo-async-offends b/Dockerfile-hexo-async-offends new file mode 100644 index 0000000..e5455d6 --- /dev/null +++ b/Dockerfile-hexo-async-offends @@ -0,0 +1,12 @@ +ARG IMAGENAME + +FROM ${IMAGENAME} + +LABEL maintainer="Offends " + +COPY . /app/* /app/ + +RUN apk update && apk add --no-cache --virtual .build-deps curl bash git \ + && bash /app/init.sh \ + && rm -rf /app \ + && apk del .build-deps \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0f204f5 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Hexo-Async-Offends + +## Drone构建变量 + +> Drone 设置 Configuration 为 `.drone-offends.yml` + +| 变量名 | 变量值 | 备注 | +| :-------------: | :---------------------------------------------------: | :------------: | +| DOCKER_USERNAME | | 镜像仓库账号 | +| DOCKER_PASSWORD | | 镜像仓库密码 | +| REGISTRY | registry.cn-hangzhou.aliyuncs.com | 镜像仓库地址 | +| REPO | registry.cn-hangzhou.aliyuncs.com/<命名空间>/<镜像名> | 镜像的仓库名称 | + +**使用 BUILD 变量控制构建** + +| 变量名 | 变量值 | 备注 | +| :----: | :----------------: | :-------------------------------: | +| BUILD | Hexo-async-offends | 构建 Async-Offends 初始化环境镜像 | +| BUILD | Gateway-kubernetes | 构建 kubernetes 网关镜像 | +| BUILD | Gateway-docker | 构建 docker 网关镜像 | +| BUILD | All | 构建跟博客有关所有构建 | + diff --git a/app/404.md b/app/404.md new file mode 100644 index 0000000..4c3966f --- /dev/null +++ b/app/404.md @@ -0,0 +1,3 @@ +--- +layout: 404 +--- \ No newline at end of file diff --git a/app/_config.async.yml b/app/_config.async.yml new file mode 100644 index 0000000..83e9a16 --- /dev/null +++ b/app/_config.async.yml @@ -0,0 +1,282 @@ +# 默认主题配置, 开启切换主题功能 +theme: + switch: true + default: style-light # style-light style-dark + +# 网站图标 Favicon +favicon: + logo: /img/favicon-16x16.png + icon16: /img/favicon-16x16.png + icon32: /img/favicon-32x32.png + appleTouchIcon: /img/favicon-16x16.png + webmanifest: /site.webmanifest + visibilitychange: true + hidden: /img/favicon-32x32.png + showText: 打咩~ + hideText: 咿呀哒~ + +# 字体图标 Icon +assets: + third_party_provider: https://npm.elemecdn.com + icons: + type: symbol + css: + js: //at.alicdn.com/t/c/font_3637590_i4hyyea14ur.js + +# 用户信息 User +user: + name: Offends + first_name: 辉 + last_name: 阿 + email: offends4@163.com + domain: https://blog.offends.cn + avatar: /img/avatar.png + describe: 现充爆炸吧 + ruleText: 尊重原创足矣。 + +# 导航栏 TopBars +top_bars: + - title: 首页 + url: / + - title: 分类 + url: /categories/ + # - title: 标签 + # url: /tags/ + - title: 其它 + url: '#' + children: + - title: 关于 + url: /about/ + - title: 留言 + url: /comment/ + - title: 友链 + url: /links/ + +# 侧栏 Sidebar +sidebar: + social: + - name: github + icon: icon-github + url: https://github.com/dinghui40 + - name: gitee + icon: icon-gitee + url: https://gitee.com/offends + +# 打字动画 + typedTextPrefix: [' '] + typedText: [ 'I`m Ding Hui','Welcome Back'] + info: + - key: 地址 + val: 银河系 + - key: 年龄 + val: 不清楚 + - key: 实力 + val: 上升期 + # - key:
+ +# 横幅 Banner +banner: + use_cover: false + default: + type: img + bgurl: /img/desktop.png + bannerText: + position: top + fit: cover + index: + bannerTitle: 业精于勤,荒于嬉。 + bannerText: + archive: + bannerTitle: 积土而为山,积水而为海。 + bannerText: + links: + bannerTitle: 渚寒烟淡,棹移人远,飘渺行舟如叶。 + bannerText: + comment: + bannerTitle: 天下兴亡,咱们有责,嘿嘿。 + bannerText: + about: + bannerTitle: 四顾山光接水光,
凭栏十里芰荷香。 + bannerText: + +# 页脚 Footer +footer: + # 起始年份 + copyrightYear: 2020 + # 显示框架 + powered: + enable: true + # 显示备案号 + beian: + enable: true + icp: 京ICP备2022021046号 + # 运行时间 + live_time: + enable: true + prefix: footer.tips + start_time: 01/3/2022 00:00:00 + # 其他信息 + custom_text: 京公网安备11010502052505号 + +# 打赏 Reward +reward: + enable: true + comment: I'm so cute. Please give me money. + methods: + - name: 支付宝 + path: /img/zfb.png + - name: 微信 + path: /img/wx.png + +# 文章目录 +toc: + enable: true + list_number: true + max_depth: 3 + min_depth: 1 + +# 图片懒加载 +lazyload: + enable: true + +# 归档页 +archive: + type: less + +# 版权信息 +creative_commons: + license: by-nc-sa + language: deed.zh + post: true + clipboard: false + +# 自定义封面图 +cover: + default: /img/block.png + type: img + +# 上下篇文章 +post_pagination: + enable: true + type: small + +# 文章过期提醒 +notice_outdate: + enable: false + style: flat + limit_day: 365 + position: top + +# 文章破图时默认图片 +error_img: + flink: /img/404.gif + post_page: /img/404.jpg + +# 分类卡片 +categorie_card: + enable: true + len: 2 + list: ["已完成", "待验证"] + +# 固定按钮块 +rightside: + readmode: true + aside: true + +# 日期格式化 Date Format +datetime_foramt: + post_card: + date: YY/MM/DD + time: HH:mm + post_info: + type: updated + date: MM/DD + time: HH:mm + archive: + date: MM/DD + time: HH:mm + +# 代码高亮 Highlight +highlight: + theme: true + title: mac + copy: true + lang: true + code_word_wrap: true + height_limit: 200 # 超出时,显示折叠按钮 + +# 自定义图标 Icon +icons: + # 主题切换图标 + sun: icon-sun + moon: icon-moon + # 首页视频播放 + play: icon-yunhang + # 邮箱 + email: icon-email + # 分类进入图标 + next: icon-arrow-right + # 文章详情 日期 + calendar: icon-rili + # 文章详情 时间 + clock: icon-shijian + # 文章详情 作者 + user: icon-yonghu + # 返回顶部 v1.1.3+ + back_top: icon-backtop + # 查询 v1.1.5+ + search: icon-chaxun + # 关闭 v1.1.5+ + close: icon-guanbi + # 打赏 v1.1.7+ + reward: icon-qiandai + # 用户信息和文章目录切换 v1.2.10+ + user_tag: icon-yonghu1 + toc_tag: icon-liebiao + # 右下角固定按钮 v1.2.11+ + read: icon-yuedu + arrows: icon-arrows-h + # 代码块 + double_arrows: icon-angle-double-down + copy: icon-copy + +# 关于 About +about: + insert: none # 插入规则 before(插入在内容前) | after(插入在内容后) | none(不插入) + title: 温故而知新,可以为师矣。 + introduction: 大家好,我是 Offends,很高兴您能在浩瀚如烟的互联网世界里发现这个博客,更感谢您能够饶有兴致地浏览这个页面。建立这个 Blog 是出于兴趣爱好,我将在此分会分享一些学习笔记,可能还会分享少许图片、视频以及其他有趣东西的链接。 + blog: +
    +
  • 程序:Hexo
  • +
  • 主题:Hexo-theme-async
  • +
+ privacy: 本网站不会追踪访客行为,且不要求访客提供任何敏感信息(比如真实姓名、身份证号码、手机号等),因而也不存在任何隐私泄漏问题。访客参与评论,必须遵守法律法规和基本道德规范,文明礼貌。严禁发布任何有关淫秽、反动、暴力、博彩、恐吓、低俗的内容或违法信息,在尊重言论自由的同时请保持和平与理性。请勿对他人采取不友好的评论或其它过激行为。 + +# 评论 Comment +comment: + twikoo: + enable: true + envId: https://blog.offends.cn/twikoo + +# 本地搜索 +search: + enable: true + type: local + +# 百度自动推送 +baidu_push: true + +# 字数统计 +wordcount: + enable: true + count: true + time: true + +# 数学公式 +katex: + copy_tex: true + global: false + options: {} + +# 渐入式应用 +sw: true \ No newline at end of file diff --git a/app/index.less b/app/index.less new file mode 100644 index 0000000..468f3ad --- /dev/null +++ b/app/index.less @@ -0,0 +1,16 @@ +.var-primary(@primary: #afb42b; @primary-weak: #c0ca33) { + --primary : @primary; + --primary-70 : fade(@primary, 70%); + --primary-50 : fade(@primary, 50%); + --primary-30 : fade(@primary, 30%); + --primary-weak : @primary-weak; + --primary-weak-50: fade(@primary-weak, 50%); +} + +:root { + .var-primary(#5a5df0, #697be2); + + &.dark { + .var-primary(#a4ce60, #82df7a); + } +} diff --git a/app/init.sh b/app/init.sh new file mode 100755 index 0000000..f7381ca --- /dev/null +++ b/app/init.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +############################################################################################# +# 用途: Hexo-Async-Deployer 项目初始化脚本 +# 作者: 丁辉 +# 编写日期: 2021-10-1 +# 更新日期: 2024-07-09 +############################################################################################# + +# 加载检测脚本 +source <(curl -sS https://gitee.com/offends/Linux/raw/main/File/Shell/Check_command.sh) + +# 初始化基础信息 +function INIT_BASE_INFO() { + # 修改基础模版 + sed -i "s#language: en#language: zh-Hans#g" /hexo/_config.yml + sed -i "s#author: John Doe#author: Offends#g" /hexo/_config.yml + + SEND_INFO "初始化基础信息" + # 本地搜索 + CHECK_COMMAND_NULL npm install hexo-generator-searchdb + # 数字统计 + CHECK_COMMAND_NULL npm install hexo-wordcount + # 初始化基础信息 + CHECK_COMMAND_NULL mv /app/_config.async.yml /hexo/_config.async.yml + CHECK_DIR /hexo/source/_data/ + CHECK_COMMAND_NULL mv /app/links.yml /hexo/source/_data/links.yml + CHECK_COMMAND_NULL mv /app/404.md /hexo/source/404.md + CHECK_COMMAND_NULL mv /app/site.webmanifest /hexo/source/site.webmanifest + CHECK_DIR /hexo/source/_data/style/ + CHECK_COMMAND_NULL mv /app/index.less /hexo/source/_data/style/index.less +} + +# 初始化页面 +function INIT_PAGE() { + # 分类 + CHECK_COMMAND_NULL npm install hexo-generator-category + # 页面名称 + PAGE_NAME=( + "categories" + "links" + "about" + "comment" + ) + # 循环创建页面 + for name in ${PAGE_NAME[@]}; do + # 创建页面 + CHECK_COMMAND_NULL hexo new page $name + if [ $? -eq 0 ]; then + # 创建页面成功 + SEND_INFO "创建页面 $name 成功" + else + # 创建页面失败 + SEND_WARN "创建页面 $name 失败" + fi + done + + # 修改页面内容 + # 友情链接 + sed -i 's#title: links#title: 友情链接#g' /hexo/source/links/index.md + sed -i '3a\layout: links' /hexo/source/links/index.md + # 关于 + sed -i 's#title: about#title: 关于#g' /hexo/source/about/index.md + sed -i '3a\layout: about' /hexo/source/about/index.md + sed -i '4a\single_column: false' /hexo/source/about/index.md + sed -i '5a\comments: false' /hexo/source/about/index.md + # 留言 + sed -i 's#title: comment#title: 留言#g' /hexo/source/comment/index.md + sed -i '3a\layout: comment' /hexo/source/comment/index.md + # 分类 + sed -i 's#title: categories#title: 分类#g' /hexo/source/categories/index.md + sed -i '3a\layout: category' /hexo/source/categories/index.md + sed -i '4a\single_column: true' /hexo/source/categories/index.md + sed -i '5a\comments: false' /hexo/source/categories/index.md +} + +# 初始化图片 +function INIT_IMAGE() { + # 存储地址 + MINIO_URL="https://minio.offends.cn:9000/offends/hexo-async" + IMAGE_NAME=( + "avatar.png" + "favicon-16x16.png" + "favicon-32x32.png" + "block.png" + "desktop.png" + "wx.png" + "zfb.png" + "demo.png" + "404.gif" + "404.jpg" + ) + CHECK_DIR /hexo/source/img + # 循环下载页面 + for name in ${IMAGE_NAME[@]}; do + # 下载图片 + CHECK_COMMAND_NULL curl -so /hexo/source/img/$name $MINIO_URL/$name + + done + + SEND_INFO "初始化图片成功" +} + +# 收录配置 +function INIT_BAIDU_SITEMAP() { + SEND_INFO "初始化收录配置" + ################################## 百度Sitemap 和 Google Sitemap ################################## + CHECK_COMMAND_NULL npm install hexo-generator-sitemap + CHECK_COMMAND_NULL npm install hexo-generator-baidu-sitemap + sed -i "s#url: http://example.com#url: https://blog.offends.cn#g" /hexo/_config.yml + sed -i '/^url:/ {N; s/\n/\nroot: \/\n/;}' /hexo/_config.yml + sed -i 's/permalink: :year\/:month\/:day\/:title\//permalink: :title.html/' /hexo/_config.yml + cat << EOF >> /hexo/_config.yml +sitemap: + path: sitemap.xml +baidusitemap: + path: baidusitemap.xml +EOF + sed -i '1i' /hexo/node_modules/hexo-theme-async/layout/_partial/head.ejs + sed -i '1i' /hexo/node_modules/hexo-theme-async/layout/_partial/head.ejs + ################################## 百度主动推送 ################################## + CHECK_COMMAND_NULL npm install hexo-baidu-url-submit + sed -i '/deploy:/!b;n;s/ type: \x27\x27/- type: baidu_url_submitter/' /hexo/_config.yml +cat << EOF >> /hexo/_config.yml +baidu_url_submit: + count: 200 + host: blog.offends.cn + token: CRBfMzmp8EjAnQCl + path: baidu_urls.txt +EOF +} + +# 添加看板娘 +function ADD_TOUCH_ICON() { + SEND_INFO "添加看板娘" + git clone https://githubfast.com/stevenjoezhang/live2d-widget.git /hexo/node_modules/hexo-theme-async/source/live2d-widget + sed -i '1i' /hexo/node_modules/hexo-theme-async/layout/_partial/head.ejs + sed -i '1i' /hexo/node_modules/hexo-theme-async/layout/_partial/head.ejs + sed -i '2s/^/\/\/ /; 3s/^\/\///' /hexo/node_modules/hexo-theme-async/source/live2d-widget/autoload.js + sed -i 's/z-index: 1;/z-index: 9999;/g' /hexo/node_modules/hexo-theme-async/source/live2d-widget/waifu.css + sed -i 's/e=1/e=5/g' /hexo/node_modules/hexo-theme-async/source/live2d-widget/waifu-tips.js +} + +# 音乐位置 : 符号去除 +# function INIT_MUSIC() { +# sed -i 's/<%- __(item.key) %>:/<%- __(item.key) %>/g' /hexo/node_modules/hexo-theme-async/layout/_partial/sidebar/card/info.ejs +# } + +# 执行全部初始化 +function INIT_ALL() { + # 初始化基础信息 + INIT_BASE_INFO + # 初始化页面 + INIT_PAGE + # 初始化图片 + INIT_IMAGE + # 收录配置 + INIT_BAIDU_SITEMAP + # 添加看板娘 + ADD_TOUCH_ICON +} + +INIT_ALL \ No newline at end of file diff --git a/app/languages.yml b/app/languages.yml new file mode 100644 index 0000000..f2c99a3 --- /dev/null +++ b/app/languages.yml @@ -0,0 +1,3 @@ +zh-Hans: + site: + title: 本站信息 \ No newline at end of file diff --git a/app/links.yml b/app/links.yml new file mode 100644 index 0000000..c62986e --- /dev/null +++ b/app/links.yml @@ -0,0 +1,8 @@ +- name: 31100Cafe + url: https://www.biuling.top + image: https://jsd.cdn.zzko.cn/gh/CheckingChen/image-hosting@master/avatar.6awsc8i38s80.webp + desc: Creativity,起飞! +- name: 白云苍狗 + url: https://www.imalun.com + image: https://www.imalun.com/images/avatar.jpg?v=1 + desc: 醒,亦在人间;梦,亦在人间。 \ No newline at end of file diff --git a/app/site.webmanifest b/app/site.webmanifest new file mode 100644 index 0000000..561da97 --- /dev/null +++ b/app/site.webmanifest @@ -0,0 +1,20 @@ +{ + "name": "Offends", + "short_name": "Offends", + "icons": [ + { + "src": "/img/favicon-16x16.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/img/favicon-32x32.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#fff", + "background_color": "#fff", + "display": "standalone", + "start_url": "/" +} \ No newline at end of file diff --git a/chart/.helmignore b/chart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/chart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000..f33fbe9 --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: blog-chart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/chart/README.md b/chart/README.md new file mode 100644 index 0000000..e623fec --- /dev/null +++ b/chart/README.md @@ -0,0 +1,17 @@ +> 本文作者:丁辉 + +# Helm部署 + +开始部署 + +```bash +helm install blog ./chart \ + --namespace blog --create-namespace +``` + +卸载 + +```bash +helm uninstall blog -n blog +``` + diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt new file mode 100644 index 0000000..df9099a --- /dev/null +++ b/chart/templates/NOTES.txt @@ -0,0 +1,7 @@ + + +Please visit this URL after startup: + +{{ if .Values.ingress.host }} + https://{{ .Values.ingress.host }} +{{ end }} \ No newline at end of file diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000..7c82dea --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,17 @@ +{{/* +Startup parameter +*/}} +{{- define "argument" -}} +progressDeadlineSeconds: 200 +replicas: 1 +revisionHistoryLimit: 1 +strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate +{{- end }} + +{{- define "imagePullPolicy" -}} +imagePullPolicy: IfNotPresent +{{- end }} \ No newline at end of file diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml new file mode 100644 index 0000000..a1f8b3d --- /dev/null +++ b/chart/templates/deployment.yaml @@ -0,0 +1,87 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.deployment.blog.name }} + labels: + app: {{ .Values.deployment.blog.labels.app }} +spec: + {{- include "argument" . | nindent 2 }} + selector: + matchLabels: + app: {{ .Values.deployment.blog.labels.app }} + template: + metadata: + labels: + app: {{ .Values.deployment.blog.labels.app }} + spec: + {{- if .Values.global.enabled }} + volumes: + - name: data + persistentVolumeClaim: + claimName: blog-pvc + {{- end }} + containers: + - name: {{ .Values.deployment.blog.name }} + image: {{ .Values.deployment.blog.image }}:{{ .Values.deployment.blog.tag }} + {{- include "imagePullPolicy" . | nindent 8 }} + ports: + - containerPort: {{ .Values.blog.targetPort }} + protocol: TCP + {{- if .Values.global.enabled }} + volumeMounts: + {{- range .Values.deployment.blog.volumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + {{- end }} + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + tcpSocket: + port: {{ .Values.blog.targetPort }} + timeoutSeconds: 10 + resources: + limits: + memory: {{ .Values.deployment.blog.limits.memory }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.deployment.blog_gateway.name }} + labels: + app: {{ .Values.deployment.blog_gateway.labels.app }} +spec: + {{- include "argument" . | nindent 2 }} + selector: + matchLabels: + app: {{ .Values.deployment.blog_gateway.labels.app }} + template: + metadata: + labels: + app: {{ .Values.deployment.blog_gateway.labels.app }} + spec: + containers: + - name: {{ .Values.deployment.blog_gateway.name }} + image: {{ .Values.deployment.blog_gateway.image }}:{{ .Values.deployment.blog_gateway.tag }} + {{- include "imagePullPolicy" . | nindent 8 }} + env: + {{- range .Values.deployment.blog_gateway.env }} + - name: {{ .name }} + value: {{ .value }} + {{- end }} + ports: + - containerPort: {{ .Values.blog_gateway.targetPort }} + protocol: TCP + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + tcpSocket: + port: {{ .Values.blog_gateway.targetPort }} + timeoutSeconds: 10 + resources: + limits: + memory: {{ .Values.deployment.blog_gateway.limits.memory }} \ No newline at end of file diff --git a/chart/templates/ingress.yaml b/chart/templates/ingress.yaml new file mode 100644 index 0000000..11f9502 --- /dev/null +++ b/chart/templates/ingress.yaml @@ -0,0 +1,36 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + {{- if .Values.ingress.redirection.enabled}} + annotations: + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/permanent-redirect-code: "301" + #kubernetes.io/ingress.class: "nginx" + ingress.kubernetes.io/ssl-redirect: "true" + ingress.kubernetes.io/secure-backends: "true" + ingress.kubernetes.io/force-ssl-redirect: "true" + {{- end }} + name: {{ .Values.ingress.name }} +spec: + ingressClassName: nginx + rules: + - host: {{ .Values.ingress.host }} + http: + paths: + - pathType: Prefix + backend: + service: + name: {{ .Values.ingress.service.name }} + port: + number: {{ .Values.ingress.service.port.number }} + path: / + {{- if .Values.ingress.tls.enabled}} + tls: + - hosts: + {{- range $.Values.ingress.tls.hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- end }} +{{- end }} diff --git a/chart/templates/pvc.yaml b/chart/templates/pvc.yaml new file mode 100644 index 0000000..f7a98d6 --- /dev/null +++ b/chart/templates/pvc.yaml @@ -0,0 +1,18 @@ +{{- if .Values.global.enabled -}} +apiVersion: v1 +kind: List +items: + {{- range .Values.global.pvcConfigs }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + spec: + accessModes: + - {{ .accessModes }} + storageClassName: {{ .storageClass }} + resources: + requests: + storage: {{ .storage }} + {{- end }} +{{- end }} diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml new file mode 100644 index 0000000..4940f89 --- /dev/null +++ b/chart/templates/service.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.deployment.blog.name }} +spec: + selector: + app: {{ .Values.deployment.blog.labels.app }} + ports: + - name: {{ .Values.deployment.blog.name }} + protocol: TCP + port: {{ .Values.blog.port }} + targetPort: {{ .Values.blog.targetPort }} + type: {{ .Values.blog.type }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.deployment.blog_gateway.name }} +spec: + selector: + app: {{ .Values.deployment.blog_gateway.labels.app }} + ports: + - name: {{ .Values.deployment.blog_gateway.name }} + protocol: TCP + port: {{ .Values.blog_gateway.port }} + targetPort: {{ .Values.blog_gateway.targetPort }} + type: {{ .Values.blog_gateway.type }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.statefulset.blog_twikoo.name }} +spec: + selector: + app: {{ .Values.statefulset.blog_twikoo.labels.app }} + ports: + - name: {{ .Values.statefulset.blog_twikoo.name }} + protocol: TCP + port: {{ .Values.blog_twikoo.port }} + targetPort: {{ .Values.blog_twikoo.targetPort }} + type: {{ .Values.blog_twikoo.type }} \ No newline at end of file diff --git a/chart/templates/statefulset.yaml b/chart/templates/statefulset.yaml new file mode 100644 index 0000000..f20ba60 --- /dev/null +++ b/chart/templates/statefulset.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Values.statefulset.blog_twikoo.name }} +spec: + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 0 + selector: + matchLabels: + app: {{ .Values.statefulset.blog_twikoo.labels.app }} + serviceName: {{ .Values.statefulset.blog_twikoo.name }} + minReadySeconds: 5 + template: + metadata: + labels: + app: {{ .Values.statefulset.blog_twikoo.labels.app }} + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: {{ .Values.statefulset.blog_twikoo.name }} + image: {{ .Values.statefulset.blog_twikoo.image }}:{{ .Values.statefulset.blog_twikoo.tag }} + env: + {{- range .Values.statefulset.blog_twikoo.env }} + - name: {{ .name }} + value: "{{ .value }}" + {{- end }} + ports: + - containerPort: {{ .Values.blog_twikoo.targetPort }} + protocol: TCP + resources: + limits: + memory: {{ .Values.statefulset.blog_twikoo.limits.memory }} + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + tcpSocket: + port: {{ .Values.blog_twikoo.targetPort }} + timeoutSeconds: 20 + {{- if .Values.global.enabled }} + volumeMounts: + {{- range .Values.statefulset.blog_twikoo.volumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + {{- end }} + {{- if .Values.global.enabled }} + volumes: + - name: data + persistentVolumeClaim: + claimName: twikoo-pvc + {{- end }} \ No newline at end of file diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000..6976c2e --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,86 @@ +# Default values for blog. +global: + enabled: true + pvcConfigs: + - name: blog-pvc + storageClass: "" # 指定存储卷, 不指定则需要集群内存在默认的存储卷 + storage: "10Gi" + accessModes: ReadWriteOnce + - name: twikoo-pvc + storageClass: "" # 指定存储卷, 不指定则需要集群内存在默认的存储卷 + storage: "10Gi" + accessModes: ReadWriteOnce + +deployment: + blog: + name: blog + labels: + app: blog + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo + tag: hexo-async-offends + limits: + memory: 512Mi + volumeMounts: + - name: data + mountPath: /hexo/source/_posts + + blog_gateway: + name: blog-gateway + labels: + app: blog-gateway + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo + tag: gateway-kubernetes + limits: + memory: 512Mi + env: + - name: localhost + value: "blog.offends.cn" + +statefulset: + blog_twikoo: + name: blog-twikoo + labels: + app: blog-twikoo + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo + tag: twikoo + limits: + memory: 128Mi + env: + - name: TWIKOO_THROTTLE + value: "1000" + volumeMounts: + - name: data + mountPath: /app/data + +blog: + port: 4000 + targetPort: 4000 + type: ClusterIP + +blog_gateway: + port: 80 + targetPort: 80 + type: ClusterIP + +blog_twikoo: + port: 8080 + targetPort: 8080 + type: ClusterIP + + # kubectl create secret tls blog-tls --key nginx.key --cert nginx.pem -n blog + +ingress: + enabled: true + name: blog-ingress + host: blog.offends.cn + service: + name: blog-gateway + port: + number: 80 + tls: + enabled: true + hosts: + - blog.offends.cn + secretName: blog-tls + redirection: #是否开启http重定向到https + enabled: true \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..c1dc74c --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,50 @@ +version: "3" + +networks: + blog_network: + driver: bridge + file_network: + driver: bridge + +services: + blog: + depends_on: + - blog-twikoo + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo:hexo-async-offends + container_name: blog + restart: always + volumes: + - /data/blog/data:/hexo/source/_posts + networks: + - blog_network + + blog-twikoo: + image: imaegoo/twikoo:latest + container_name: blog-twikoo + restart: always + volumes: + - /data/blog/twikoo:/app/data + environment: + - TWIKOO_THROTTLE=1000 + # - TWIKOO_PORT=4444 + networks: + - blog_network + + nginx-https: + depends_on: + - blog-twikoo + - blog + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo:gateway-docker + container_name: blog-nginx + restart: always + # network_mode: "host" + volumes: + - /data/blog/cert:/etc/nginx/conf.d/cert + environment: + - DOMAIN_NAME=blog.offends.cn + ports: + - "80:80" + - "443:443" + networks: + - blog_network + - file_network \ No newline at end of file diff --git a/gateway/Dockerfile-docker b/gateway/Dockerfile-docker new file mode 100644 index 0000000..a8fd595 --- /dev/null +++ b/gateway/Dockerfile-docker @@ -0,0 +1,16 @@ +ARG IMAGENAME=nginx:alpine-slim + +FROM ${IMAGENAME} + + +COPY ./ssl.conf.template /etc/nginx/conf.d/ssl.conf.template + +VOLUME ["/etc/nginx/conf.d/cert/"] + +EXPOSE 80 + +EXPOSE 443 + +ENV DOMAIN_NAME=default + +CMD /bin/sh -c "envsubst '\$DOMAIN_NAME' < /etc/nginx/conf.d/ssl.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" \ No newline at end of file diff --git a/gateway/Dockerfile-kubernetes b/gateway/Dockerfile-kubernetes new file mode 100644 index 0000000..2174d80 --- /dev/null +++ b/gateway/Dockerfile-kubernetes @@ -0,0 +1,11 @@ +ARG IMAGENAME=nginx:alpine-slim + +FROM ${IMAGENAME} + +COPY ./default.conf.template /etc/nginx/conf.d/default.conf.template + +EXPOSE 80 + +ENV localhost=default + +CMD /bin/sh -c "envsubst '\$localhost' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" \ No newline at end of file diff --git a/gateway/default.conf.template b/gateway/default.conf.template new file mode 100644 index 0000000..c4b1cf8 --- /dev/null +++ b/gateway/default.conf.template @@ -0,0 +1,20 @@ +server { + listen 80; + server_name ${localhost}; + + # rewrite ^(.*) https://${localhost}$1 permanent; + + location / { + proxy_set_header X-FORWARDED-FOR $remote_addr; + proxy_set_header X-FORWARDED-PROTO $scheme; + proxy_set_header Host $http_host; + proxy_pass http://blog:4000; + } + + location /twikoo { + proxy_pass http://blog-twikoo:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + +} \ No newline at end of file diff --git a/gateway/ssl.conf.template b/gateway/ssl.conf.template new file mode 100644 index 0000000..8285385 --- /dev/null +++ b/gateway/ssl.conf.template @@ -0,0 +1,33 @@ +server{ + listen 80; + + server_name ${DOMAIN_NAME}; + + #(第一种)把http的域名请求转成https + #return 301 https://$host$request_uri; + + #(第二种)强制将http的URL重写成https + rewrite ^(.*) https://$server_name$1 permanent; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + + ssl_certificate /etc/nginx/conf.d/cert/nginx.pem; + ssl_certificate_key /etc/nginx/conf.d/cert/nginx.key; + + location / { + proxy_set_header X-FORWARDED-FOR $remote_addr; + proxy_set_header X-FORWARDED-PROTO $scheme; + proxy_set_header Host $http_host; + proxy_pass http://blog:4000; + } + + location /twikoo { + proxy_pass http://blog-twikoo:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + +} \ No newline at end of file diff --git a/kubernetes/blog.yaml b/kubernetes/blog.yaml new file mode 100644 index 0000000..602a688 --- /dev/null +++ b/kubernetes/blog.yaml @@ -0,0 +1,78 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: blog-pvc + namespace: blog +spec: + accessModes: + - ReadWriteOnce + storageClassName: "" + resources: + requests: + storage: 10Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: blog + name: blog-deployment + labels: + app: blog +spec: + progressDeadlineSeconds: 200 + replicas: 1 + revisionHistoryLimit: 1 + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + selector: + matchLabels: + app: blog + template: + metadata: + labels: + app: blog + spec: + volumes: + - name: data + persistentVolumeClaim: + claimName: blog-pvc + containers: + - name: blog + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo:hexo-async-offends + imagePullPolicy: IfNotPresent + ports: + - containerPort: 4000 + protocol: TCP + volumeMounts: + - name: data + mountPath: /hexo/source/_posts + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + tcpSocket: + port: 4000 + timeoutSeconds: 10 + resources: + limits: + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + namespace: blog + name: blog +spec: + selector: + app: blog + ports: + - name: blog + protocol: TCP + port: 4000 + targetPort: 4000 + type: LoadBalancer + allocateLoadBalancerNodePorts: false diff --git a/kubernetes/gateway.yaml b/kubernetes/gateway.yaml new file mode 100644 index 0000000..8c073dd --- /dev/null +++ b/kubernetes/gateway.yaml @@ -0,0 +1,59 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: blog + name: blog-gateway + labels: + app: blog-gateway +spec: + progressDeadlineSeconds: 200 + replicas: 1 + revisionHistoryLimit: 1 + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + selector: + matchLabels: + app: blog-gateway + template: + metadata: + labels: + app: blog-gateway + spec: + containers: + - name: blog-gateway + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo:gateway-kubernetes + imagePullPolicy: IfNotPresent + env: + - name: localhost + value: "blog.offends.cn" + ports: + - containerPort: 80 + protocol: TCP + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + tcpSocket: + port: 80 + timeoutSeconds: 10 + resources: + limits: + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + namespace: blog + name: blog-gateway +spec: + selector: + app: blog-gateway + ports: + - name: blog-gateway + protocol: TCP + port: 80 + targetPort: 80 diff --git a/kubernetes/ingress-nginx.yaml b/kubernetes/ingress-nginx.yaml new file mode 100644 index 0000000..4210fbb --- /dev/null +++ b/kubernetes/ingress-nginx.yaml @@ -0,0 +1,30 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/permanent-redirect-code: "301" + kubernetes.io/ingress.class: "nginx" + ingress.kubernetes.io/ssl-redirect: "true" + ingress.kubernetes.io/secure-backends: "true" + ingress.kubernetes.io/force-ssl-redirect: "true" + name: blog-ingress + namespace: blog +spec: + ingressClassName: nginx + rules: + - host: blog.offends.cn + http: + paths: + - pathType: Prefix + backend: + service: + name: blog-gateway + port: + number: 80 + path: / + # 只有在启用 TLS 时才需要此部分 + tls: + - hosts: + - blog.offends.cn + secretName: blog-tls diff --git a/kubernetes/ingress-traefik.yaml b/kubernetes/ingress-traefik.yaml new file mode 100644 index 0000000..0470a8a --- /dev/null +++ b/kubernetes/ingress-traefik.yaml @@ -0,0 +1,23 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: blog-ingress + namespace: blog + annotations: + kubernetes.io/ingress.class: traefik +spec: + rules: + - host: blog.offends.cn + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: blog-gateway + port: + number: 80 + tls: + - hosts: + - blog.offends.cn + secretName: blog-tls \ No newline at end of file diff --git a/kubernetes/namespace.yaml b/kubernetes/namespace.yaml new file mode 100644 index 0000000..a98aecf --- /dev/null +++ b/kubernetes/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: blog \ No newline at end of file diff --git a/kubernetes/twikoo.yaml b/kubernetes/twikoo.yaml new file mode 100644 index 0000000..f7cf31d --- /dev/null +++ b/kubernetes/twikoo.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: blog + name: twikoo +spec: + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 0 + selector: + matchLabels: + app: twikoo + serviceName: blog-twikoo + minReadySeconds: 5 + template: + metadata: + labels: + app: twikoo + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: twikoo + image: registry.cn-hangzhou.aliyuncs.com/offends/hexo:twikoo + env: + - name: TWIKOO_THROTTLE + value: "1000" + # - name: TWIKOO_PORT + # value: "4444" + ports: + - containerPort: 8080 + protocol: TCP + resources: + limits: + memory: 128Mi + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + tcpSocket: + port: 8080 + timeoutSeconds: 20 + volumeMounts: + - name: host-path-volume + mountPath: /app/data + volumes: + - name: host-path-volume + hostPath: + path: /data/blog/twikoo +--- +apiVersion: v1 +kind: Service +metadata: + namespace: blog + name: blog-twikoo +spec: + selector: + app: twikoo + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + type: ClusterIP \ No newline at end of file