task-nodejs.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-node-project
spec:
workspaces:
- name: cache
mountPath: /root/.npm
- name: source
- name: output
params:
- name: imgTag
type: string
- name: run
type: string
- name: dir
type: string
steps:
- name: build
workingDir: "$(workspaces.source.path)/$(params.dir)"
image: "node:$(params.imgTag)"
script: |
rm -rf package-lock.json
npm install --registry=https://registry.npmmirror.com/
npm run $(params.run)
cp -r dist/* $(workspaces.output.path)/
taskrun.yaml
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
generateName: build-node-project-run-
generation: 1
namespace: cicd-services
spec:
params:
- name: dir
value: frontend
- name: imgTag
value: 21.6.2
- name: run
value: build
serviceAccountName: default
taskRef:
kind: Task
name: build-node-project
workspaces:
- name: cache
persistentVolumeClaim:
claimName: node-cache-pvc
- name: source
persistentVolumeClaim:
claimName: test-tekton-vue-pvc
- name: output
persistentVolumeClaim:
claimName: test-tekton-vue-output-pvc
运行之后会出现下面报错
TaskRunValidationFailed [User error] more than one PersistentVolumeClaim is bound
报错翻译TaskRunValidationFailed[用户错误]绑定了多个PersistentVolumeClaim
,很明确他允许绑定多个pvc,这个蛮离谱的,cicd的过程中用到多个存储应该是很正常的事,tekton却默认不支持绑定多个pvc。
修改tekton的配置把参数disable-affinity-assistant
修改为true
,即可
kubectl -n tekton-pipelines edit cm feature-flags
这个参数的作用如下
设置为 true 将阻止 Tekton 为共享了 workspace 的每个 TaskRun 创建 Affinity Assistant Pod。 这样就可以保证这些 pod 运行在同一个节点上,避免了跨节点访问 pvc 的问题。
还有就是这个功能在v0.60会被弃用,未来估计不会因为这个问题报这个错了。
ISSUE: https://github.com/tektoncd/pipeline/issues/6543
TektonDocs: https://github.com/tektoncd/pipeline/blob/main/docs/affinityassistants.md
配置参考: https://www.soulchild.cn/post/tekton-operator%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3/
我的K8s环境是宿主机的hyper-v虚拟出来的,如果要映射到外面则还需要再我的宿主机上面再做一层反代,我采用的是nginx,当ingress整好之后,我从我从我腾讯云上复制了一段nginx配置放到了我的宿主机,主要配置如下:
location /test/ {
proxy_pass http://kubernetes.boychai.xyz/test/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
为了防止传入的ip是代理主机的ip我这里设置了Host、X-Real-IP、REMOTE-HOST、X-Forwarded-For。经过测试之后发现使用宿主机配置的代理访问时返回404,在宿主机上直接却没问题。
我去查看了宿主机的nginx日志、ingress-nginx-controller日志、应用程序的日志,发现除了宿主机的nginx均没有日志记录,宿主机日志信息如下
111.180.204.54 - - [25/Aug/2023:22:12:21 +0800] "GET /test/ HTTP/1.1" 404 548 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
除了这一条之外其他的日志均无404。
看到日志之后有点懵,因为我的宿主机是可以直接访问ingress暴露出来的服务的,而且没有报错正常访问,我是用反代之后就报错404,我最开始以为这个404就是我宿主机报的,但是宿主机的404默认页面会返回nginx的版本,如下图
而我反代返回的404页面则是这样的
一想就是我ingress返回的页面,但是我去查看ingress-nginx-controller的日志并无404的报错,日志查看命令如下,访问时并无产生记录
[root@kubernetes ~]# kubectl -n ingress-nginx logs -f ingress-nginx-controller-kc5np
我这里去尝试修改宿主机的反代配置,配置如下
location /test/ {
proxy_pass http://kubernetes.boychai.xyz/test/;
}
发现这样是可以正常访问程序的,这就奇怪了,难不成还能是因为我设置了这几个header的问题?我挨个注释这些header的配置发现问题出在下面这段配置
proxy_set_header Host $host;
具体原因也没搞清楚但是取消使用这条配置就好了...
在Kubernetes的Ingress中,Host 头部用于根据不同的域名(或主机名)将请求路由到不同的服务。每个Ingress规则可以基于请求的 Host 头部将流量路由到不同的后端服务。我宿主机代理的域名和Ingress设置的域名不同,所以导致了这个问题,我外部代理的域名是tools.boychai.xyz
而我k8s设置Ingress的域名则是kubernetes.boychai.xyz
,当我在宿主机的代理设置了proxy_set_header Host $host;
这段配置之后,请求发到Ingress之后,Ingress拿到的路由请求域名则是tools.boychai.xyz
,而我又没有设置这个资源则就返回了404。
能够访问之后发现最终的应用拿不到真是访问的ip,这里通过nginx直接返回X-Forwarded-For头信息来查看问题出在什么位置,宿主机Nginx配置如下
location /aaa {
default_type text/html;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
return 200 "proxy_add_x_forwarded_for:$proxy_add_x_forwarded_for";
}
location /test/ {
# ingress暴露的地址`http://kubernetes.boychai.xyz/test/`
proxy_pass http://kubernetes.boychai.xyz/test/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
后端Nginx配置如下
location / {
default_type text/html;
return 200 "proxy_add_x_forwarded_for:$proxy_add_x_forwarded_for";
}
这样访问反代的/aaa
就是访问反代主机的ip,访问反代的/test
就会返回访问nginx的后端访问的ip,访问结果如下
访问/aaa
返回
proxy_add_x_forwarded_for:111.180.204.54
访问/test
返回
proxy_add_x_forwarded_for:192.16.1.1, 192.16.1.2
查看访问返回的信息发现直接访问代理的ip是没问题的,那就是Ingress的锅了,这里的1.1
和1.2
依次是反代的ip和k8s主机的ip,到ingress这层没有把x_forwarded_for
头加进来,这里我去官方翻了翻文档发现了三条和x_forwarded_for
有关系的配置,如下
data:
...
compute-full-forwarded-for: "true"
# 这一条可以不加也需要知道
# forwarded-for-header: "X-Forwarded-For"
use-forwarded-headers: "true"
给ingress的cm加上这两条配置即可解决问题,最终/test
返回的内容如下
proxy_add_x_forwarded_for:111.180.204.54, 192.16.1.1, 192.16.1.2
Ingress默认是没有配置传递真实IP功能的,需要配置,这三条配置和官网文档如下:
true
,则ingress-nginx会将传入的x-forward-*传递到上游,如果是Ingress上层还有一层ingress则需要配置这一条。如果他直接暴露在公网中或者它基于L3的网络负载后门则不需要管,因为它默认就是false。use-forwarded-headers
的话,会发现还是没能获取到客户端的真实IP,原因是当前X-Forwaded-Fox变量是从remote_addr获取的,每次都是拿上一层的代理ip,这段配置的作用是将客户端用户访问所经过的代理ip都追加到X-Forwaded-Fox.先说一下原理,连接上校园网设备之后只要不进行认证,大部分的流量只要是经过校园网设备都会拦截之后给客户端重定向到一个认证页面(本文封面),让其进行认证。不进行认证的小部分流量比如说是dhcp、dns都不会进行拦截重定向,dhcp要进行分配ip,刚连接的设备需要通过这个dhcp才可以拿到自己的ip地址,dns是域名解析服务也不会拦截。他们的端口分别是DHCP(UDP/67服务端、UDP/68客户端)、DNS(UDP/53),目前只发现了这两个服务的端口是不被拦截的。我们可以通过这些端口来绕过流量的拦截。例如使用虚拟专用网络、虚拟隧道等技术来实现绕过拦截。
本文服务端使用V2ray软件进行绕过,项目地址以及文档地址如下:
项目地址:https://github.com/v2fly/v2ray-core
客户端为了方便采用V2rayN和服务端进行链接,项目地址如下:
项目地址:https://github.com/2dust/v2rayN
我们在服务端部署一下v2ray,如何去下载这里不多讲解,部署方式如下
# 下载
[root@dj1 work]# wget https://github.com/v2fly/v2ray-core/releases/download/v5.3.0/v2ray-linux-64.zip
100%[==============================================================================================>] 11,706,579 3.22MB/s in 3.5s
# 解压
[root@dj1 work]# unzip v2ray-linux-64.zip
Archive: v2ray-linux-64.zip
inflating: config.json
inflating: geosite.dat
inflating: geoip-only-cn-private.dat
creating: systemd/
creating: systemd/system/
inflating: systemd/system/v2ray.service
inflating: systemd/system/v2ray@.service
inflating: vpoint_socks_vmess.json
inflating: geoip.dat
inflating: v2ray
inflating: vpoint_vmess_freedom.json
# 配置
[root@dj1 work]# mv config.json config.json.bak
[root@dj1 work]# vim config.json
# 配置如下
{
"inbounds": [
{
"port": 53, // 服务器监听端口
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "0297a6ed-9152-4ad1-a80a-b248a9c4d3ad"
}
]
},
"streamSettings": {
"network": "mkcp", //此处的 mkcp 也可写成 kcp,两种写法是起同样的效果
"kcpSettings": {
"uplinkCapacity": 5,
"downlinkCapacity": 100,
"congestion": true,
"header": {
"type": "none"
}
}
}
}
],
"outbounds": [
{
"protocol": "freedom"
}
]
}
# 运行v2ray,这里采用screen工具放在后台运行.
[root@dj1 work]# screen -S V2
[root@dj1 work]# ./v2ray run
V2Ray 5.3.0 (V2Fly, a community-driven edition of V2Ray.) Custom (go1.20 linux/amd64)
A unified platform for anti-censorship.
2023/03/17 13:02:30 Using default config: /root/work/config.json
2023/03/17 13:02:30 [Warning] V2Ray 5.3.0 started
# ctrl + a + d
[detached from 81853.V2]
这里就配置好了,我这里用的是V2ray的VMess协议端口用的是dns的53端口关于VMess的配置文档可以在V2ray的文档中找到这里不多做解释,clients中的id算是链接的token,需要记住,这个id不能随便写,需要通过特殊的算法生成可以直接使用v2rayn来生成 这里也多做讲解。
下载方式这里不细说了,去github中的版本列表中都有。下载好之后打开软件,在左上角服务器-》添加VMess服务器中配置,配置如下
地址填写自己的服务器地址,用户id这里可以直接生成,需要和服务端一样。协议选择kcp即可。
配置好之后"右键左下角的v2ray的图标选择路由-》全局"。之后再设置一下代理"右键右下角图标-》系统代理-》自动配置系统代理"。
连接上校园网之后就会发现不会再跳转到认证页面。实际上网的速度和服务器的网络规格挂钩。不是用校园网的时候建议关闭代理不然数据会一直走代理会出现限速的现象可以通过"右键右下角图标-》系统代理-》清除系统代理"来解决。
]]>本站用的服务器是腾讯云的轻量应用服务器,规格是2核4G8M的,前些日子开了一个游戏服务器和朋友联机,发现这个内存跑到3000左右的时候就会变的比较卡,到3500左右就会直接死机,当时就想着给服务器优化一下
当时我服务器运行了typecho、harbor、gogs、Jenkins、游戏服务器、还有一些我自己写的后端程序,都在docker上运行,其中typecho、gogs的数据库都是运行单独的mysql5.7,端口不往公网暴露,然后还有一个mysql8.0对外暴露给我自己用,一共是三个,当时就寻思把gogs和typecho的迁移到8.0里面
当开始迁移的时候我是直接使用DataGrip把老的数据库表拖拽到新数据表里面,修改好网站的数据地址之后基本没有任何问题,之后就没怎么在意。
当我想要发布一次文章的时候出现了报错。
找了好久的问题也没找到,当时就没想过是数据库的问题,重新部署了很多遍的typecho,一直是没有找到问题,一直到我打算重新部署一个数据库的时候我发现迁移之后的数据库他的主键自增索引什么的全都没有了,于是就开始第二次迁移。第二次我是使用mysqldump来进行导出,命令如下
mysqldump --defaults-extra-file=/etc/mysql/my.cnf Blog > blog.sql
然后用DataGrip导入的,导入之后数据库的表结构都回来了内容也都有但是前端对接好之后又出现了问题handsome的主题不能恢复备份,emoji表情全部变成问号"?"。
emoji加载不出来无非就是编码的问题,typecho之前是不支持emoji的,之前我做过数据库字符集的修改,第三次导出的时候还是用mysqldump的方式导出但是命令改成了这样,命令如下
mysqldump --defaults-extra-file=/etc/mysql/my.cnf --default-character-set=utf8mb4 Blog > blog.sql
mysqldump默认导出的字符集为utf8,emoji的字符集需要utf8mb4,使用DataGrip导入之后就没问题了,emoji显示了,handsome主题备份也能恢复了。
]]>