diff --git a/k8s/config b/k8s/config new file mode 100644 index 0000000..0805b11 --- /dev/null +++ b/k8s/config @@ -0,0 +1,31 @@ +# base64 -w 0 ~/kube.config +apiVersion: v1 +clusters: +- cluster: + insecure-skip-tls-verify: true + server: https://light.xiongxiao.me:6443 + name: dev-cluster +- cluster: + insecure-skip-tls-verify: true + server: https://kevisual.cn:6443 + name: kevisual-cluster +contexts: +- context: + cluster: dev-cluster + user: dev-user + name: dev-context +- context: + cluster: kevisual-cluster + user: kevisual-user + name: kevisual-context +current-context: kevisual-context +kind: Config +users: +- name: dev-user + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrVENDQVRlZ0F3SUJBZ0lJSDdGcGRsb2tnMm93Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOelkwTVRJek9UVTNNQjRYRFRJMU1URXlOakF5TWpVMU4xb1hEVEkyTVRFeQpOakF5TWpVMU4xb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJOd3JxcWtlTnV6bVdjWEMKd2pVdi9nOUkyTnE5MmZDcGpGYzRLVjVSMFltMzNIZUZtUEZiaC9KLzM1djJGWG9OSWZBVjRrSlo0RzZSVFZjYgpXZnRiRWhtalNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCVGRsNkplTEN3YXdyRWtMSkt2ZnZ4NnpRQW4wVEFLQmdncWhrak9QUVFEQWdOSUFEQkYKQWlCNkE4SXZocWRYL2N4VWs1Y1lMMGxOeWkxejl1YUk1R245RGRDTmd0clpRUUloQU56USs4TkUxbVdURDVTdAo4SGxJaXBJcG1NMXZpSGZZcW50MmVtbnJ0QktHCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkakNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTmpReE1qTTVOVGN3SGhjTk1qVXhNVEkyTURJeU5UVTNXaGNOTXpVeE1USTBNREl5TlRVMwpXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTmpReE1qTTVOVGN3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFUVUY4L3c5aU1oVzNNQnBXTjJRS1NYRHpGVE1CYXNRaFBqZm5BSEJCeVgKeEFsbktWMjhyN2Z4Y1ZiY3hNVGVsOExUZW05RXNncEYwaEFCTGpnQnlHaVhvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVTNaZWlYaXdzR3NLeEpDeVNyMzc4CmVzMEFKOUV3Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnQmNpcjUwTk9yeXdBeUNSNkw1dFBnZHIxVGo5MGtFVE0KS1g0emQxcTZCeVFDSUhscWd3ZXdKS2YzYzFxQWZnUkFVZmlSR1lSNXBYQ2o2aE5jdjJwUDdrM3kKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + client-key-data: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU9oSHRlUFV1WnN6UHRTWU9XbkMrTVEybWZnYU9TaHhBNTdQc2VpQUZFck5vQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFM0N1cXFSNDI3T1paeGNMQ05TLytEMGpZMnIzWjhLbU1WemdwWGxIUmliZmNkNFdZOFZ1SAo4bi9mbS9ZVmVnMGg4QlhpUWxuZ2JwRk5WeHRaKzFzU0dRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo= +- name: kevisual-user + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrVENDQVRlZ0F3SUJBZ0lJYUV1WVVManBtV0F3Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOelkwT1RJMk5qWTFNQjRYRFRJMU1USXdOVEE1TWpReU5Wb1hEVEkyTVRJdwpOVEE1TWpReU5Wb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJDMmJGcG5HVGJYRUwxS00KcG5ERkxuQjJ3czd3NTBMSnpqeTZLaDloSnZmYVVtL1RxOVEvYnF6c1RMSWhLQkg0Mlp4ZUFsTTRIWTFGdnVrTwphME40Z2dHalNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCUVFzYUxiNFpudllkbUtxQjFjT2M5dUZTVVB0akFLQmdncWhrak9QUVFEQWdOSUFEQkYKQWlBeERocitWTHJVMm5lSml4bU5tM1luQ1FPdS8vYnZZRG9vai96endGT2JlUUloQUxZcXhXVlQ4NW9qVUlWcApHSTZTK2sydkZ3Ny9Pb0lOVmVmSTJ1bTl1WHJNCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkakNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTmpRNU1qWTJOalV3SGhjTk1qVXhNakExTURreU5ESTFXaGNOTXpVeE1qQXpNRGt5TkRJMQpXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTmpRNU1qWTJOalV3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFReENHZE9kSVBtZmRkSTVPUzNqdUtQTGlacSs4MlVsME1TRUJENjRITUIKc3ZNbUxXbzUwK1dwcHllYTV2dlorOHF5TUdaQmx5VVNTUWtoQkxTZDZWemZvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUVMR2kyK0daNzJIWmlxZ2RYRG5QCmJoVWxEN1l3Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnWW42NVZmbXVLNjgzeUhBZ3NRZFlwdmZxbDZxNlY5NTAKSE9laGpyTWhZdzRDSUdXZ05oVEg2NmN5dXlsUk93YjlQbmZnR1JqY2l4UmFoV0pwdWlDbjJuUHgKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + client-key-data: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJWV0xHSnZ0S3Rlb3JKdkpFZ3g1VDNiMHVqczdBMnJuZUY0L1RyVG01d2hvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFTFpzV21jWk50Y1F2VW95bWNNVXVjSGJDenZEblFzbk9QTG9xSDJFbTk5cFNiOU9yMUQ5dQpyT3hNc2lFb0VmalpuRjRDVXpnZGpVVys2UTVyUTNpQ0FRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo= \ No newline at end of file diff --git a/k8s/copy.sh b/k8s/copy.sh new file mode 100644 index 0000000..d19b7a6 --- /dev/null +++ b/k8s/copy.sh @@ -0,0 +1,3 @@ +# mkdir ~/.kube + +cp ./config ~/.kube/config \ No newline at end of file diff --git a/k8s/kevisual.cn/README.md b/k8s/kevisual.cn/README.md index a389475..7ee7908 100644 --- a/k8s/kevisual.cn/README.md +++ b/k8s/kevisual.cn/README.md @@ -1,12 +1,12 @@ -## 安装k3s + calico 网络插件 -### 安装k3s 同时禁用默认的traefik和flannel +## 安装k3s 网络插件 +### 安装k3s 同时禁用默认的traefik ```sh curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \ INSTALL_K3S_MIRROR=cn \ K3S_KUBECONFIG_MODE="644" \ -INSTALL_K3S_EXEC="server --disable=traefik --flannel-backend=none" \ +INSTALL_K3S_EXEC="server --disable=traefik " \ sh - ``` # 编辑服务文件 @@ -18,11 +18,6 @@ journalctl -u k3s.service -f ### 安装有问题 https://chat.xiongxiao.me/s/10b9aefa-5ba5-45d6-ba2c-b80c638468f3 -### 安装Calico - -```sh -curl -sfL https://docs.projectcalico.org/manifests/calico.yaml | kubectl apply -f - -``` ### 获取token @@ -38,4 +33,45 @@ sudo vim /etc/rancher/k3s/registries.yaml ```sh kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +``` + +## let + +# 将访问宿主机 80 端口的流量转发到 30080 +```sh +sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 30080 +sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 30443 + +# 别忘了保存规则(Ubuntu 下) +sudo apt install iptables-persistent +sudo netfilter-persistent save +``` + +## let 2 + +```sh +#回路 +iptables -t nat -L PREROUTING -vn --line-numbers +### 删除 +sudo iptables -t nat -D PREROUTING 1 2>/dev/null +sudo iptables -t nat -I PREROUTING 1 -p tcp --dport 443 -j DNAT --to-destination 118.196.32.29:30443 + + +#去路(根据数据包判断顺序) +sudo iptables -t nat -L POSTROUTING -vn --line-numbers +## 删除 +sudo iptables -t nat -D POSTROUTING 1 +sudo iptables -t nat -A POSTROUTING -d 118.196.32.29 -p tcp --dport 30443 -j MASQUERADE + + +#强制刷新权限 +sudo iptables -I FORWARD 1 -j ACCEPT +sudo netfilter-persistent save +``` + + +``` +CLUSTER_IP=$(kubectl get svc traefik -n traefik -o jsonpath='{.spec.clusterIP}') +echo "Traefik 的固定 ClusterIP 是: $CLUSTER_IP" +Traefik 的固定 ClusterIP 是: 10.43.131.173 ``` \ No newline at end of file diff --git a/k8s/kevisual.cn/apps/convex/api-convex.yaml b/k8s/kevisual.cn/apps/convex/api-convex.yaml new file mode 100644 index 0000000..24e4222 --- /dev/null +++ b/k8s/kevisual.cn/apps/convex/api-convex.yaml @@ -0,0 +1,45 @@ +--- +# Api-Convex - api-convex.kevisual.cn +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: api-convex-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`api-convex.kevisual.cn`) + kind: Rule + services: + - name: api-convex-external + port: 3211 + tls: + certResolver: letsencrypt + +--- +# Api-Convex 服务 (端口 3211, 本地) +apiVersion: v1 +kind: Service +metadata: + name: api-convex-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 3211 + targetPort: 3211 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: api-convex-external + namespace: default +subsets: +- addresses: + - ip: 118.196.32.29 + ports: + - port: 3211 + name: http diff --git a/k8s/kevisual.cn/apps/convex/convex.yaml b/k8s/kevisual.cn/apps/convex/convex.yaml new file mode 100644 index 0000000..2687d8d --- /dev/null +++ b/k8s/kevisual.cn/apps/convex/convex.yaml @@ -0,0 +1,45 @@ +--- +# Convex - convex.kevisual.cn +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: convex-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`convex.kevisual.cn`) + kind: Rule + services: + - name: convex-external + port: 3210 + tls: + certResolver: letsencrypt + +--- +# Convex 服务 (端口 3210, 本地) +apiVersion: v1 +kind: Service +metadata: + name: convex-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 3210 + targetPort: 3210 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: convex-external + namespace: default +subsets: +- addresses: + - ip: 118.196.32.29 + ports: + - port: 3210 + name: http diff --git a/k8s/kevisual.cn/apps/cors/app.yaml b/k8s/kevisual.cn/apps/cors/app.yaml new file mode 100644 index 0000000..1d80cb2 --- /dev/null +++ b/k8s/kevisual.cn/apps/cors/app.yaml @@ -0,0 +1,45 @@ +--- +# CORS - cors.kevisual.cn +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: cors-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`cors.kevisual.cn`) + kind: Rule + services: + - name: cors-external + port: 11111 + tls: + certResolver: letsencrypt + +--- +# CORS 服务 (端口 11111, 本地) +apiVersion: v1 +kind: Service +metadata: + name: cors-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 11111 + targetPort: 11111 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: cors-external + namespace: default +subsets: +- addresses: + - ip: 118.196.32.29 + ports: + - port: 11111 + name: http diff --git a/k8s/kevisual.cn/apps/esm.yaml b/k8s/kevisual.cn/apps/esm.yaml index 07cbc19..423dab3 100644 --- a/k8s/kevisual.cn/apps/esm.yaml +++ b/k8s/kevisual.cn/apps/esm.yaml @@ -1,9 +1,7 @@ -# kubectl create namespace kevisual apiVersion: apps/v1 kind: Deployment metadata: name: esm - namespace: kevisual labels: app: esm spec: @@ -18,7 +16,7 @@ spec: spec: containers: - name: esm - image: ghcr.io/esm-dev/esm.sh:v136_1 + image: docker.cnb.cool/kevisual/dev-env/esm.sh:v137 ports: - containerPort: 12000 protocol: TCP @@ -29,7 +27,7 @@ spec: volumes: - name: esm-data hostPath: - path: /opt/docker/esm/data + path: /root/kevisual/k8s/esm/data type: Directory nodeSelector: machine: "kevisual" @@ -39,7 +37,6 @@ apiVersion: v1 kind: Service metadata: name: esm - namespace: kevisual labels: app: esm spec: @@ -57,7 +54,6 @@ apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: esm-https - namespace: kevisual spec: entryPoints: - websecure diff --git a/k8s/kevisual.cn/apps/esm/config.json b/k8s/kevisual.cn/apps/esm/config.json new file mode 100644 index 0000000..11ca8af --- /dev/null +++ b/k8s/kevisual.cn/apps/esm/config.json @@ -0,0 +1,13 @@ +{ + "port": 12000, + "npmRegistry": "https://registry.npmmirror.com/", + "logLevel": "info", + "accessLog": true, + "storageS3": { + "type": "s3", + "endpoint": "https://tos-s3-cn-shanghai.ivolces.com", + "region": "cn-shanghai", + "accessKeyID": "AKLTOWNhNmJkNDJmNzFkNGI3MDlmMWQzYTA2ZjBkYTc2YTg", + "secretAccessKey": "TWpjME9EVm1OVFJtTkROaE5ESXlaR0ptWlRnd1lqVm1Nems0TW1Ka1pUZw==" + } +} \ No newline at end of file diff --git a/k8s/kevisual.cn/apps/external/meilisearch.yaml b/k8s/kevisual.cn/apps/external/meilisearch.yaml new file mode 100644 index 0000000..ffcf5fe --- /dev/null +++ b/k8s/kevisual.cn/apps/external/meilisearch.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Service +metadata: + name: meilisearch-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 7700 + targetPort: 7700 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: meilisearch-external + namespace: default +subsets: +- addresses: + - ip: "118.196.32.29" + ports: + - name: http + port: 7700 + protocol: TCP +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: meilisearch-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`ms.kevisual.cn`) + kind: Rule + services: + - name: meilisearch-external + port: 7700 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/kevisual.cn/apps/external/new-api.yaml b/k8s/kevisual.cn/apps/external/new-api.yaml index 17f17ea..1375b36 100644 --- a/k8s/kevisual.cn/apps/external/new-api.yaml +++ b/k8s/kevisual.cn/apps/external/new-api.yaml @@ -23,16 +23,6 @@ subsets: - name: http port: 3000 protocol: TCP -metadata: - name: minio-external - namespace: default -subsets: -- addresses: - - ip: "118.196.32.29" - ports: - - name: http - port: 9000 - protocol: TCP --- # Kevisual - newapi.kevisual.cn (支持 WebSocket) apiVersion: traefik.io/v1alpha1 diff --git a/k8s/kevisual.cn/apps/external/pocketbase.yaml b/k8s/kevisual.cn/apps/external/pocketbase.yaml new file mode 100644 index 0000000..d1e5202 --- /dev/null +++ b/k8s/kevisual.cn/apps/external/pocketbase.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Service +metadata: + name: pocketbase-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 8090 + targetPort: 8090 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: pocketbase-external + namespace: default +subsets: +- addresses: + - ip: "118.196.32.29" + ports: + - name: http + port: 8090 + protocol: TCP +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: pocketbase-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`pb.kevisual.cn`) + kind: Rule + services: + - name: pocketbase-external + port: 8090 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/kevisual.cn/apps/external/yjs.yaml b/k8s/kevisual.cn/apps/external/yjs.yaml new file mode 100644 index 0000000..36e6ca9 --- /dev/null +++ b/k8s/kevisual.cn/apps/external/yjs.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Service +metadata: + name: yjs-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 4444 + targetPort: 4444 + protocol: TCP + name: websocket +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: yjs-external + namespace: default +subsets: +- addresses: + - ip: "118.196.32.29" + ports: + - name: websocket + port: 4444 + protocol: TCP +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: yjs-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`yjs.kevisual.cn`) + kind: Rule + services: + - name: yjs-external + port: 4444 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/kevisual.cn/apps/jimeng-api/app.yaml b/k8s/kevisual.cn/apps/jimeng-api/app.yaml new file mode 100644 index 0000000..f0fe119 --- /dev/null +++ b/k8s/kevisual.cn/apps/jimeng-api/app.yaml @@ -0,0 +1,72 @@ +# jimeng-api Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jimeng-api + namespace: default + labels: + app: jimeng-api +spec: + replicas: 1 + selector: + matchLabels: + app: jimeng-api + template: + metadata: + labels: + app: jimeng-api + spec: + containers: + - name: jimeng-api + image: docker.cnb.cool/kevisual/dev-env/jimeng-api:v1.9.5 + imagePullPolicy: Always + ports: + - containerPort: 5100 + protocol: TCP + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + nodeSelector: + machine: "kevisual" +--- +# jimeng-api Service +apiVersion: v1 +kind: Service +metadata: + name: jimeng-api + namespace: default + labels: + app: jimeng-api +spec: + type: ClusterIP + ports: + - name: http + protocol: TCP + port: 5100 + targetPort: 5100 + selector: + app: jimeng-api + + +--- +# jimeng-api Ingress (Traefik) +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: jimeng-api-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`jimeng-api.kevisual.cn`) + kind: Rule + services: + - name: jimeng-api + port: 5100 + tls: + certResolver: letsencrypt diff --git a/k8s/kevisual.cn/apps/nocodb.yaml b/k8s/kevisual.cn/apps/nocodb.yaml index 752c99a..7ae7c73 100644 --- a/k8s/kevisual.cn/apps/nocodb.yaml +++ b/k8s/kevisual.cn/apps/nocodb.yaml @@ -1,43 +1,10 @@ --- -apiVersion: v1 -kind: Namespace -metadata: - name: nocodb ---- -# PostgreSQL Persistent Volume Claim -apiVersion: v1 -kind: PersistentVolume -metadata: - name: postgres-pv - namespace: nocodb -spec: - capacity: - storage: 1Gi - accessModes: - - ReadWriteOnce - storageClassName: local-path - hostPath: - path: /opt/docker/nocodb/postgres_data ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: postgres-pvc - namespace: nocodb -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - volumeName: postgres-pv ---- # PostgreSQL Deployment apiVersion: apps/v1 kind: Deployment metadata: name: root-db - namespace: nocodb + namespace: default labels: app: root-db spec: @@ -52,7 +19,7 @@ spec: spec: containers: - name: postgres - image: postgres:17.6 + image: docker.cnb.cool/kevisual/dev-env/postgres:17.6 ports: - containerPort: 5432 env: @@ -90,16 +57,18 @@ spec: periodSeconds: 5 timeoutSeconds: 3 volumes: - - name: postgres-storage - persistentVolumeClaim: - claimName: postgres-pvc + - name: postgres-storage + hostPath: + path: /root/kevisual/k8s/nocodb/postgres_data + type: Directory + nodeSelector: + machine: "kevisual" --- # PostgreSQL Service (ClusterIP, internal access) apiVersion: v1 kind: Service metadata: name: root-db - namespace: nocodb labels: app: root-db spec: @@ -111,40 +80,11 @@ spec: targetPort: 5432 type: ClusterIP --- -# NocoDB Persistent Volume Claim -apiVersion: v1 -kind: PersistentVolume -metadata: - name: nc-data-pv - namespace: nocodb -spec: - capacity: - storage: 1Gi - accessModes: - - ReadWriteOnce - storageClassName: local-path - hostPath: - path: /opt/docker/nocodb/nc_data ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: nc-data-pvc - namespace: nocodb -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - volumeName: nc-data-pv ---- # NocoDB Deployment apiVersion: apps/v1 kind: Deployment metadata: name: nocodb - namespace: nocodb labels: app: nocodb spec: @@ -159,12 +99,12 @@ spec: spec: containers: - name: nocodb - image: nocodb/nocodb:latest + image: docker.cnb.cool/kevisual/dev-env/nocodb:0.301.3 ports: - containerPort: 8080 env: - name: NC_DB - value: "pg://root-db.nocodb.svc.cluster.local:5432?u=postgres&p=abearxiong&d=postgres" + value: "pg://root-db:5432?u=postgres&p=abearxiong&d=postgres" - name: NC_AUTH_JWT_SECRET value: "MaCpbZugRlwFWUfpAUNAd7p64V4Yj7Xx" # openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32 volumeMounts: @@ -179,16 +119,18 @@ spec: periodSeconds: 10 timeoutSeconds: 5 volumes: - - name: nc-data-storage - persistentVolumeClaim: - claimName: nc-data-pvc + - name: nc-data-storage + hostPath: + path: /root/kevisual/k8s/nocodb/nc_data + type: Directory + nodeSelector: + machine: "kevisual" --- # NocoDB Service (NodePort to expose on host:8080) apiVersion: v1 kind: Service metadata: name: nocodb - namespace: nocodb labels: app: nocodb spec: @@ -206,7 +148,6 @@ apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: nocodb-https - namespace: nocodb spec: entryPoints: - websecure diff --git a/k8s/kevisual.cn/apps/openlist/docker/compose.yml b/k8s/kevisual.cn/apps/openlist/docker/compose.yml new file mode 100644 index 0000000..5016a00 --- /dev/null +++ b/k8s/kevisual.cn/apps/openlist/docker/compose.yml @@ -0,0 +1,13 @@ +# docker-compose.yml +services: + openlist: + image: 'openlistteam/openlist:latest' + container_name: openlist + user: '0:0' # Please replace `0:0` with the actual user ID and group ID you want to use to run OpenList. + volumes: + - './data:/opt/openlist/data' + ports: + - '5244:5244' + environment: + - UMASK=022 + restart: unless-stopped \ No newline at end of file diff --git a/k8s/kevisual.cn/apps/openlist/openlist.yaml b/k8s/kevisual.cn/apps/openlist/openlist.yaml new file mode 100644 index 0000000..ea1abd4 --- /dev/null +++ b/k8s/kevisual.cn/apps/openlist/openlist.yaml @@ -0,0 +1,71 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: openlist + labels: + app: openlist +spec: + replicas: 1 + selector: + matchLabels: + app: openlist + template: + metadata: + labels: + app: openlist + spec: + containers: + - name: openlist + image: docker.cnb.cool/kevisual/dev-env/openlist:v4.1.10 + securityContext: + runAsUser: 0 + ports: + - containerPort: 5244 + protocol: TCP + env: + - name: UMASK + value: "022" + volumeMounts: + - name: openlist-data + mountPath: /opt/openlist/data + volumes: + - name: openlist-data + hostPath: + path: /root/kevisual/k8s/openlist/data + type: DirectoryOrCreate + nodeSelector: + machine: "kevisual" + +--- +apiVersion: v1 +kind: Service +metadata: + name: openlist + labels: + app: openlist +spec: + type: ClusterIP + ports: + - port: 5244 + targetPort: 5244 + protocol: TCP + name: http + selector: + app: openlist + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: openlist-https +spec: + entryPoints: + - websecure + routes: + - match: Host(`openlist.kevisual.cn`) + kind: Rule + services: + - name: openlist + port: 5244 + tls: + certResolver: letsencrypt diff --git a/k8s/kevisual.cn/apps/root/app.yaml b/k8s/kevisual.cn/apps/root/app.yaml new file mode 100644 index 0000000..b3c4f99 --- /dev/null +++ b/k8s/kevisual.cn/apps/root/app.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Service +metadata: + name: root-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 51515 + targetPort: 51515 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: root-external + namespace: default +subsets: +- addresses: + - ip: "118.196.32.29" + ports: + - name: http + port: 51515 + protocol: TCP +--- +# Kevisual - root.kevisual.cn (支持 WebSocket) +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: root-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`root.kevisual.cn`) + kind: Rule + services: + - name: root-external + port: 51515 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/kevisual.cn/config/master-token.md b/k8s/kevisual.cn/config/master-token.md index e6e2c48..c9d0c07 100644 --- a/k8s/kevisual.cn/config/master-token.md +++ b/k8s/kevisual.cn/config/master-token.md @@ -1,10 +1,10 @@ -K106e5eb70f699db4a043873e452b636cd50be9a5794ff1a912a7b96f22268eb204::server:afa9aade36b27a6eec44d47983441d59 +K109668b353a17ff6ea9d68535255f880cf583c5c83c357d181ac5f963505033af4::server:f95b219abcfe507760f04ff88be52ccd # Agent 节点安装命令 ```sh -curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://kevisual.cn:6443 K3S_TOKEN=K106e5eb70f699db4a043873e452b636cd50be9a5794ff1a912a7b96f22268eb204::server:afa9aade36b27a6eec44d47983441d59 sh - +curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://kevisual.cn:6443 K3S_TOKEN=K109668b353a17ff6ea9d68535255f880cf583c5c83c357d181ac5f963505033af4::server:f95b219abcfe507760f04ff88be52ccd sh -s -- --pause-image=docker.cnb.cool/kevisual/dev-env/mirrored-pause:3.9 ``` 会输出类似 diff --git a/k8s/kevisual.cn/docs/02-查看启动.md b/k8s/kevisual.cn/docs/02-查看启动.md new file mode 100644 index 0000000..e45d8e6 --- /dev/null +++ b/k8s/kevisual.cn/docs/02-查看启动.md @@ -0,0 +1,6 @@ + +```sh + +kubectl logs openlist-869ffbc74f-kjmbs + +``` \ No newline at end of file diff --git a/k8s/kevisual.cn/ingress/apps-ingressroute.yaml b/k8s/kevisual.cn/ingress/apps-ingressroute.yaml index d66dc30..05ead58 100644 --- a/k8s/kevisual.cn/ingress/apps-ingressroute.yaml +++ b/k8s/kevisual.cn/ingress/apps-ingressroute.yaml @@ -1,4 +1,34 @@ # Kevisual - kevisual.cn (支持 WebSocket) +--- +# WebSocket 支持中间件 - 完整头部配置 +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: websocket-headers + namespace: default +spec: + headers: + customRequestHeaders: + X-Forwarded-Proto: "https" + X-Real-IP: "" + X-Forwarded-For: "" + X-Forwarded-Host: "" +--- +# ServersTransport 配置 - 支持长连接 +apiVersion: traefik.io/v1alpha1 +kind: ServersTransport +metadata: + name: websocket-transport + namespace: default +spec: + serverName: "" + insecureSkipVerify: true + maxIdleConnsPerHost: 100 + forwardingTimeouts: + dialTimeout: 30s + responseHeaderTimeout: 30s + idleConnTimeout: 90s +--- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: @@ -13,9 +43,12 @@ spec: services: - name: kevisual-external port: 3005 + serversTransport: websocket-transport + middlewares: + - name: websocket-headers tls: certResolver: letsencrypt - +--- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: @@ -30,5 +63,29 @@ spec: services: - name: kevisual-external port: 3005 + serversTransport: websocket-transport + middlewares: + - name: websocket-headers tls: - certResolver: letsencrypt \ No newline at end of file + certResolver: letsencrypt +--- +# 通配符子域名支持 *.kevisual.cn (兜底规则) +# apiVersion: traefik.io/v1alpha1 +# kind: IngressRoute +# metadata: +# name: wildcard-kevisual-https +# namespace: default +# spec: +# entryPoints: +# - websecure +# routes: +# - match: HostRegexp(`^[a-zA-Z0-9-]+\.kevisual\.cn$`) +# kind: Rule +# services: +# - name: kevisual-external +# port: 3005 +# serversTransport: websocket-transport +# middlewares: +# - name: websocket-headers +# tls: +# certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/kevisual.cn/ingress/match-kevisual.yaml b/k8s/kevisual.cn/ingress/match-kevisual.yaml new file mode 100644 index 0000000..9db22a4 --- /dev/null +++ b/k8s/kevisual.cn/ingress/match-kevisual.yaml @@ -0,0 +1,20 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: nfc-kevisual-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`nfc.kevisual.cn`) + kind: Rule + services: + - name: kevisual-external + port: 3005 + serversTransport: websocket-transport + middlewares: + - name: websocket-headers + tls: + certResolver: letsencrypt +--- \ No newline at end of file diff --git a/k8s/kevisual.cn/kevisual-apps/app.yaml b/k8s/kevisual.cn/kevisual-apps/app.yaml new file mode 100644 index 0000000..4a49d2a --- /dev/null +++ b/k8s/kevisual.cn/kevisual-apps/app.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: cnb-kevisual-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`cnb.kevisual.cn`) + kind: Rule + services: + - name: kevisual-external + port: 3005 + serversTransport: websocket-transport + middlewares: + - name: websocket-headers + tls: + certResolver: letsencrypt +--- \ No newline at end of file diff --git a/k8s/kevisual.cn/must.sh b/k8s/kevisual.cn/must.sh new file mode 100644 index 0000000..aba8fb5 --- /dev/null +++ b/k8s/kevisual.cn/must.sh @@ -0,0 +1 @@ +echo "/dev/vdb1 /root/kevisual ext4 defaults 0 0" >> /etc/fstab \ No newline at end of file diff --git a/k8s/kevisual.cn/pro/index.md b/k8s/kevisual.cn/pro/index.md new file mode 100644 index 0000000..eae4520 --- /dev/null +++ b/k8s/kevisual.cn/pro/index.md @@ -0,0 +1,31 @@ + +```sh +# cat /etc/rancher/k3s/registries.yaml +mirrors: + docker.io: + endpoint: + - "https://docker.m.daocloud.io" + - "https://dockerproxy.net/" + - "https://docker.cnb.cool/kevisual/dev-env" +``` + +```sh +#cat config.toml +disabled_plugins = ["cri"] + +[plugins."io.containerd.grpc.v1.cri".registry] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] + endpoint = [ + "https://docker.1ms.run", + "https://docker.m.daocloud.io", + "https://dockerproxy.net/", + ] + + +# [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"] +# endpoint = [ +# "https://k8s.m.daocloud.io" +# "https://docker.m.daocloud.io", +# ] +``` \ No newline at end of file diff --git a/k8s/kevisual.cn/services/external-services.yaml b/k8s/kevisual.cn/services/external-services.yaml index 43fb8a3..958016f 100644 --- a/k8s/kevisual.cn/services/external-services.yaml +++ b/k8s/kevisual.cn/services/external-services.yaml @@ -4,25 +4,22 @@ metadata: name: kevisual-external namespace: default spec: - type: ClusterIP + clusterIP: None ports: - port: 3005 targetPort: 3005 protocol: TCP name: http --- -apiVersion: discovery.k8s.io/v1 -kind: EndpointSlice +apiVersion: v1 +kind: Endpoints metadata: name: kevisual-external namespace: default - labels: - kubernetes.io/service-name: kevisual-external -addressType: IPv4 -ports: -- name: http - protocol: TCP - port: 3005 -endpoints: +subsets: - addresses: - - "118.196.32.29" \ No newline at end of file + - ip: 118.196.32.29 + ports: + - port: 3005 + name: http + protocol: TCP \ No newline at end of file diff --git a/k8s/kevisual.cn/sh/debug-www-kevisual.sh b/k8s/kevisual.cn/sh/debug-www-kevisual.sh new file mode 100755 index 0000000..a55ad8c --- /dev/null +++ b/k8s/kevisual.cn/sh/debug-www-kevisual.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# 诊断 www.kevisual.cn 访问问题 +# tags: debug, troubleshooting, traefik, ingress +# description: 诊断 www.kevisual.cn 无法访问的问题 +# title: www.kevisual.cn 诊断脚本 +# createdAt: 2025-12-05 + +echo "========================================" +echo "1. 检查 Traefik CRD 是否存在" +echo "========================================" +kubectl api-resources | grep ingressroute + +echo "" +echo "========================================" +echo "2. 检查 IngressRoute 资源" +echo "========================================" +kubectl get ingressroute -n default + +echo "" +echo "========================================" +echo "3. 检查 kevisual-external 服务" +echo "========================================" +kubectl get svc kevisual-external -n default + +echo "" +echo "========================================" +echo "4. 检查 EndpointSlice" +echo "========================================" +kubectl get endpointslice -n default | grep kevisual + +echo "" +echo "========================================" +echo "5. 检查 Traefik Pod 状态" +echo "========================================" +kubectl get pod -n traefik + +echo "" +echo "========================================" +echo "6. 检查 Traefik 服务" +echo "========================================" +kubectl get svc -n traefik + +echo "" +echo "========================================" +echo "7. 描述 www-kevisual-https IngressRoute" +echo "========================================" +kubectl describe ingressroute www-kevisual-https -n default 2>&1 + +echo "" +echo "========================================" +echo "8. 检查 Traefik 日志(最近50行)" +echo "========================================" +kubectl logs -n traefik -l app.kubernetes.io/name=traefik --tail=50 2>&1 | grep -i "kevisual\|www.kevisual\|error" || echo "未找到相关日志" + +echo "" +echo "========================================" +echo "9. 测试访问 www.kevisual.cn" +echo "========================================" +curl -I https://www.kevisual.cn 2>&1 | head -10 + +echo "" +echo "========================================" +echo "10. 测试访问 kevisual.cn" +echo "========================================" +curl -I https://kevisual.cn 2>&1 | head -10 diff --git a/k8s/kevisual.cn/sh/log/delete.sh b/k8s/kevisual.cn/sh/log/delete.sh new file mode 100644 index 0000000..080a07a --- /dev/null +++ b/k8s/kevisual.cn/sh/log/delete.sh @@ -0,0 +1,11 @@ +# kubectl delete -f ./app.yaml --force --grace-period=0 + +# log + +kubectl logs jimeng-api-cfd7c9578-dkqps + +kubectl describe pod jimeng-api-cfd7c9578-dkqps + +# kubectl rollout restart deployment jimeng-api -n default + +# kubectl get pods -l app=jimeng-api -w \ No newline at end of file diff --git a/k8s/kevisual.cn/sh/log/traefik.sh b/k8s/kevisual.cn/sh/log/traefik.sh new file mode 100644 index 0000000..539deb2 --- /dev/null +++ b/k8s/kevisual.cn/sh/log/traefik.sh @@ -0,0 +1,9 @@ +# !/bin/bash + +# 查看 traefik 日志中包含 jimeng 关键词的内容,以及错误信息 +kubectl logs -n traefik $(kubectl get pods -n traefik -o name | head +-1) --tail=100 | grep -E "(jimeng|error|Error|ERROR)" -A 2 -B 2 +kubectl get svc -n traefik + +# 查看 traefik pod 的倒数 100 行日志 +kubectl logs -n traefik $(kubectl get pods -n traefik -o name | head -1) --tail=100 \ No newline at end of file diff --git a/k8s/kevisual.cn/sh/mirror/proxy-base.sh b/k8s/kevisual.cn/sh/mirror/proxy-base.sh new file mode 100644 index 0000000..3ab8763 --- /dev/null +++ b/k8s/kevisual.cn/sh/mirror/proxy-base.sh @@ -0,0 +1,15 @@ +## k3s ctr 直接下载不了镜像,用其他的方式下载然后导入 +# sudo k3s ctr images pull docker.io/rancher/mirrored-pause:3.6 + + +# 1. 使用 Docker pull 镜像 +docker pull docker.cnb.cool/kevisual/dev-env/mirrored-pause:3.6/rancher/mirrored-pause:3.6 + +# 2. 将 Docker 镜像保存为 tar 文件 +docker save docker.cnb.cool/kevisual/dev-env/mirrored-pause:3.6/rancher/mirrored-pause:3.6 -o mirrored-pause-3.6.tar + +# 3. 使用 K3s 的 ctr 导入镜像 +sudo k3s ctr images import mirrored-pause-3.6.tar + +# 4. 验证镜像是否导入成功 +sudo k3s ctr images ls | grep pause \ No newline at end of file diff --git a/k8s/kevisual.cn/traefik.yaml b/k8s/kevisual.cn/traefik.yaml index 66bbcd2..790d0a0 100644 --- a/k8s/kevisual.cn/traefik.yaml +++ b/k8s/kevisual.cn/traefik.yaml @@ -6,6 +6,11 @@ # description: Traefik 反向代理完整配置,部署在 master 节点,包含自动 SSL 证书支持(Let's Encrypt) # title: Traefik 完整部署配置 - 含 SSL 证书(Master 节点部署) # createdAt: 2025-11-26 +# Error from server (NotFound): error when creating "traefik.yaml": the server could not find the requested resource (post ingressroutes.traefik.io) +# 注意: 需要先安装 Traefik CRD 资源定义, +## +# kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +## --- # PersistentVolume 用于存储 ACME 证书数据 apiVersion: v1 @@ -132,12 +137,19 @@ spec: labels: app: traefik spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet serviceAccountName: traefik nodeSelector: kubernetes.io/hostname: kevisual # 节点主机名是 kevisual containers: - name: traefik - image: traefik:latest + image: docker.cnb.cool/kevisual/dev-env/traefik:v3.6.9 + # env: + # - name: HTTP_PROXY + # value: "http://kevisual.cn:7890" + # - name: HTTPS_PROXY + # value: "http://kevisual.cn:7890" args: - --api.insecure=true - --providers.kubernetescrd @@ -154,10 +166,13 @@ spec: ports: - name: web containerPort: 80 + hostPort: 80 - name: websecure containerPort: 443 + hostPort: 443 - name: admin containerPort: 8080 + hostPort: 8080 volumeMounts: - name: acme-storage mountPath: /acme @@ -173,23 +188,23 @@ metadata: namespace: traefik spec: type: NodePort + externalIPs: + - 118.196.32.29 selector: app: traefik ports: - name: web port: 80 targetPort: 80 - nodePort: 30080 # 外部通过 30080 访问 HTTP - # nodePort: 80 + nodePort: 30080 - name: websecure port: 443 targetPort: 443 - nodePort: 30443 # 外部通过 30443 访问 HTTPS - # nodePort: 443 + nodePort: 30443 - name: admin port: 8080 targetPort: 8080 - nodePort: 30808 # Dashboard + nodePort: 30808 --- apiVersion: networking.k8s.io/v1 kind: IngressClass @@ -214,4 +229,16 @@ spec: - name: api@internal kind: TraefikService tls: - certResolver: letsencrypt \ No newline at end of file + certResolver: letsencrypt + +--- +# 处理443 端口被占用问题,将 Traefik Service 的 NodePort 修改为 30443,并添加 externalIPs +# kubectl edit svc traefik -n traefik +# spec: +# externalIPs: +# - 118.196.32.29 +# ports: +# - name: websecure +# port: 443 +# targetPort: 443 +# nodePort: 30443 \ No newline at end of file diff --git a/k8s/readme.md b/k8s/readme.md new file mode 100644 index 0000000..c0e3387 --- /dev/null +++ b/k8s/readme.md @@ -0,0 +1,25 @@ +# 安装kubectl + +```sh +curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" +chmod +x kubectl +sudo mv kubectl /usr/local/bin/kubectl +kubectl version --client +``` +配置自动补全 +```sh +source <(kubectl completion bash) # 临时生效 +echo "source <(kubectl completion bash)" >> ~/.bashrc # 永久生效 +``` + +# 设置默认 context +```sh +kubectl config use-context + + +kubectl config use-context dev-context +``` + +# 查看节点信息 +```sh +kubectl get nodes -o wide \ No newline at end of file diff --git a/k8s/scripts/cleanup-bad-pods.sh b/k8s/scripts/cleanup-bad-pods.sh new file mode 100644 index 0000000..098dd9d --- /dev/null +++ b/k8s/scripts/cleanup-bad-pods.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# 一键清理集群中常见异常状态的 Pod +# 会删除以下 STATUS 的 Pod: +# - Evicted +# - Error +# - ImagePullBackOff +# - ContainerStatusUnknown + +set -euo pipefail + +STATUSES=("Evicted" "Error" "ImagePullBackOff" "ContainerStatusUnknown") + +echo "======================================" +echo "Kubernetes 异常 Pod 清理脚本" +echo "======================================" +echo + +for status in "${STATUSES[@]}"; do + # 过滤出该状态的 Pod(NAMESPACE NAME READY STATUS ...) + MAPFILE -t pods < <(kubectl get pods -A 2>/dev/null | awk -v s="$status" '$4==s {print $1" "$2}') + + if [[ ${#pods[@]} -eq 0 ]]; then + echo "[${status}] 无需清理" + continue + fi + + echo "[${status}] 发现 ${#pods[@]} 个 Pod:" + for line in "${pods[@]}"; do + echo " $line" + done + + for line in "${pods[@]}"; do + ns=$(awk '{print $1}' <<<"$line") + name=$(awk '{print $2}' <<<"$line") + if [[ -z "$ns" || -z "$name" ]]; then + continue + fi + echo "删除 $ns/$name ..." + kubectl delete pod -n "$ns" "$name" --grace-period=0 --force || true + done + + echo +done + +echo "======================================" +echo "清理完成" +echo "======================================" +echo "提示:Deployment/StatefulSet/DaemonSet 会自动重建对应 Pod(如果存在)" diff --git a/k8s/xiongxiao.me/README.md b/k8s/xiongxiao.me/README.md index 02b9b0c..c7612df 100644 --- a/k8s/xiongxiao.me/README.md +++ b/k8s/xiongxiao.me/README.md @@ -28,4 +28,20 @@ kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/con kubectl config use-context dev-context # ls context kubectl config use-context kevisual-context -``` \ No newline at end of file +``` +## dns fix + + +```bash + +resolvectl status +echo "nameserver 1.1.1.1" > /etc/resolv.conf + +kubectl rollout restart deployment/coredns -n kube-system +``` + +## log traefik pod + +```bash +kubectl logs -n traefik deploy/traefik -f +``` diff --git a/k8s/xiongxiao.me/apps/blog/app.yaml b/k8s/xiongxiao.me/apps/blog/app.yaml new file mode 100644 index 0000000..c677f53 --- /dev/null +++ b/k8s/xiongxiao.me/apps/blog/app.yaml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: blog + labels: + app: blog +spec: + replicas: 1 + selector: + matchLabels: + app: blog + template: + metadata: + labels: + app: blog + spec: + containers: + - name: blog + image: docker.cnb.cool/abearxiong/blog:latest + ports: + - containerPort: 80 + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "256Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 +--- +apiVersion: v1 +kind: Service +metadata: + name: blog + labels: + app: blog +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + app: blog +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: blog-https +spec: + entryPoints: + - websecure + routes: + - match: Host(`blog.xiongxiao.me`) + kind: Rule + services: + - name: blog + port: 80 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/xiongxiao.me/apps/blog/compose.yml b/k8s/xiongxiao.me/apps/blog/compose.yml new file mode 100644 index 0000000..2ec91dd --- /dev/null +++ b/k8s/xiongxiao.me/apps/blog/compose.yml @@ -0,0 +1,7 @@ +services: + blog: + image: docker.cnb.cool/abearxiong/blog:latest + container_name: blog + restart: unless-stopped + ports: + - "80:80" \ No newline at end of file diff --git a/k8s/xiongxiao.me/apps/blog/log.sh b/k8s/xiongxiao.me/apps/blog/log.sh new file mode 100644 index 0000000..7957708 --- /dev/null +++ b/k8s/xiongxiao.me/apps/blog/log.sh @@ -0,0 +1,4 @@ +# kubectl logs openlist-869ffbc74f-kjmbs + +# uplate +kubectl rollout restart deployment blog \ No newline at end of file diff --git a/k8s/xiongxiao.me/apps/clash/clash.yaml b/k8s/xiongxiao.me/apps/clash/clash.yaml new file mode 100644 index 0000000..7c37d55 --- /dev/null +++ b/k8s/xiongxiao.me/apps/clash/clash.yaml @@ -0,0 +1,45 @@ +--- +# clash - clash.xiongxiao.me (支持 WebSocket) +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: clash-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`clash.xiongxiao.me`) + kind: Rule + services: + - name: clash-external + port: 9090 + tls: + certResolver: letsencrypt + +--- +# clash 服务 (端口 9090, 本地) +apiVersion: v1 +kind: Service +metadata: + name: clash-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 9090 + targetPort: 9090 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: clash-external + namespace: default +subsets: +- addresses: + - ip: 121.4.112.18 + ports: + - port: 9090 + name: http diff --git a/k8s/xiongxiao.me/apps/convex/convex.yaml b/k8s/xiongxiao.me/apps/convex/convex.yaml new file mode 100644 index 0000000..447aaa9 --- /dev/null +++ b/k8s/xiongxiao.me/apps/convex/convex.yaml @@ -0,0 +1,45 @@ +--- +# Convex - convex.xiongxiao.me +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: convex-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`convex.xiongxiao.me`) + kind: Rule + services: + - name: convex-external + port: 3210 + tls: + certResolver: letsencrypt + +--- +# Convex 服务 (端口 3210, 本地) +apiVersion: v1 +kind: Service +metadata: + name: convex-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 3210 + targetPort: 3210 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: convex-external + namespace: default +subsets: +- addresses: + - ip: 121.4.112.18 + ports: + - port: 3210 + name: http diff --git a/k8s/xiongxiao.me/apps/convex/dash.yaml b/k8s/xiongxiao.me/apps/convex/dash.yaml new file mode 100644 index 0000000..6519ae4 --- /dev/null +++ b/k8s/xiongxiao.me/apps/convex/dash.yaml @@ -0,0 +1,45 @@ +--- +# Dash Convex - dash-convex.xiongxiao.me +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: dash-convex-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`dash-convex.xiongxiao.me`) + kind: Rule + services: + - name: dash-convex-external + port: 6791 + tls: + certResolver: letsencrypt + +--- +# Dash Convex 服务 (端口 6791, 本地) +apiVersion: v1 +kind: Service +metadata: + name: dash-convex-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 6791 + targetPort: 6791 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: dash-convex-external + namespace: default +subsets: +- addresses: + - ip: 121.4.112.18 + ports: + - port: 6791 + name: http diff --git a/k8s/xiongxiao.me/apps/convex/readme.md b/k8s/xiongxiao.me/apps/convex/readme.md new file mode 100644 index 0000000..14a5f9c --- /dev/null +++ b/k8s/xiongxiao.me/apps/convex/readme.md @@ -0,0 +1,3 @@ +dashboard: http://127.0.0.1:6791 +backend: http://127.0.0.1:3210 + \ No newline at end of file diff --git a/k8s/xiongxiao.me/apps/my-secrets.yaml b/k8s/xiongxiao.me/apps/my-secrets.yaml new file mode 100644 index 0000000..df5124c --- /dev/null +++ b/k8s/xiongxiao.me/apps/my-secrets.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +metadata: + name: my-secrets + namespace: default +type: Opaque +data: + # Base64 编码的值 + # Ov23littcejmbA5iKrhK -> T3YyM2xpdHRjZWptYUE1aUtyaEs= + # af67c4cdbc37367a69258d798e06641e51445315 -> YWY2N2M0Y2RiYzM3MzY3YTY5MjU4ZDc5OGUwNjY0MWU1MTQ0NTMxNQ== + # abc123 ->YWJjMTIz + g-client-id: T3YyM2xpdHRjZWptYkE1aUtyaEs= + g-client-secret: YWY2N2M0Y2RiYzM3MzY3YTY5MjU4ZDc5OGUwNjY0MWU1MTQ0NTMxNQ== + jwt-secret: YWJjMTIz \ No newline at end of file diff --git a/k8s/xiongxiao.me/apps/newsnow.yaml b/k8s/xiongxiao.me/apps/newsnow.yaml new file mode 100644 index 0000000..e27874b --- /dev/null +++ b/k8s/xiongxiao.me/apps/newsnow.yaml @@ -0,0 +1,110 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: newsnow + labels: + app: newsnow +spec: + replicas: 1 + selector: + matchLabels: + app: newsnow + template: + metadata: + labels: + app: newsnow + spec: + containers: + - name: newsnow + image: ghcr.io/ourongxing/newsnow:latest + ports: + - containerPort: 4444 + env: + - name: HOST + value: "0.0.0.0" + - name: PORT + value: "4444" + - name: NODE_ENV + value: "production" + - name: G_CLIENT_ID + valueFrom: + secretKeyRef: + name: my-secrets + key: g-client-id + - name: G_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: my-secrets + key: g-client-secret + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: my-secrets + key: jwt-secret + - name: INIT_TABLE + value: "true" + - name: ENABLE_CACHE + value: "true" + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + livenessProbe: + httpGet: + path: / + port: 4444 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: / + port: 4444 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + volumeMounts: + - name: data-volume + mountPath: /usr/app/.data + volumes: + - name: data-volume + hostPath: + path: /opt/docker/newsnow/data + type: DirectoryOrCreate +--- +apiVersion: v1 +kind: Service +metadata: + name: newsnow + labels: + app: newsnow +spec: + type: ClusterIP + ports: + - port: 4444 + targetPort: 4444 + protocol: TCP + name: http + selector: + app: newsnow +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: newsnow-https +spec: + entryPoints: + - websecure + routes: + - match: Host(`newsnow.xiongxiao.me`) + kind: Rule + services: + - name: newsnow + port: 4444 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/xiongxiao.me/apps/rsshub/app.yaml b/k8s/xiongxiao.me/apps/rsshub/app.yaml new file mode 100644 index 0000000..1f48d18 --- /dev/null +++ b/k8s/xiongxiao.me/apps/rsshub/app.yaml @@ -0,0 +1,45 @@ +--- +# RSSHub - rsshub.xiongxiao.me (端口 1200) +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: rsshub-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`rsshub.xiongxiao.me`) + kind: Rule + services: + - name: rsshub-external + port: 1200 + tls: + certResolver: letsencrypt + +--- +# RSSHub 服务 (端口 1200, 本地) +apiVersion: v1 +kind: Service +metadata: + name: rsshub-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 1200 + targetPort: 1200 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: rsshub-external + namespace: default +subsets: +- addresses: + - ip: 121.4.112.18 + ports: + - port: 1200 + name: http diff --git a/k8s/xiongxiao.me/apps/umami/app.yaml b/k8s/xiongxiao.me/apps/umami/app.yaml new file mode 100644 index 0000000..1ae7197 --- /dev/null +++ b/k8s/xiongxiao.me/apps/umami/app.yaml @@ -0,0 +1,45 @@ +--- +# Umami - umami.xiongxiao.me +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: umami-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`umami.xiongxiao.me`) + kind: Rule + services: + - name: umami-external + port: 3001 + tls: + certResolver: letsencrypt + +--- +# Umami 服务 (端口 3001, 本地) +apiVersion: v1 +kind: Service +metadata: + name: umami-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 3001 + targetPort: 3001 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: umami-external + namespace: default +subsets: +- addresses: + - ip: 121.4.112.18 + ports: + - port: 3001 + name: http diff --git a/k8s/xiongxiao.me/apps/uptime-kuma/app.yml b/k8s/xiongxiao.me/apps/uptime-kuma/app.yml new file mode 100644 index 0000000..7055199 --- /dev/null +++ b/k8s/xiongxiao.me/apps/uptime-kuma/app.yml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: uptime-kuma + labels: + app: uptime-kuma +spec: + replicas: 1 + selector: + matchLabels: + app: uptime-kuma + template: + metadata: + labels: + app: uptime-kuma + spec: + nodeSelector: + machine: "on" + containers: + - name: uptime-kuma + image: louislam/uptime-kuma:2 + ports: + - containerPort: 3001 + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + livenessProbe: + httpGet: + path: / + port: 3001 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: / + port: 3001 + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + volumeMounts: + - name: data-volume + mountPath: /app/data + volumes: + - name: data-volume + hostPath: + path: /opt/docker/uptime-kuma + type: DirectoryOrCreate +--- +apiVersion: v1 +kind: Service +metadata: + name: uptime-kuma + labels: + app: uptime-kuma +spec: + type: ClusterIP + ports: + - port: 3001 + targetPort: 3001 + protocol: TCP + name: http + selector: + app: uptime-kuma +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: uptime-kuma-https +spec: + entryPoints: + - websecure + routes: + - match: Host(`uptime.xiongxiao.me`) + kind: Rule + services: + - name: uptime-kuma + port: 3001 + tls: + certResolver: letsencrypt diff --git a/k8s/xiongxiao.me/apps/uptime-kuma/compose.yml b/k8s/xiongxiao.me/apps/uptime-kuma/compose.yml new file mode 100644 index 0000000..6bffe15 --- /dev/null +++ b/k8s/xiongxiao.me/apps/uptime-kuma/compose.yml @@ -0,0 +1,9 @@ +services: + uptime-kuma: + image: louislam/uptime-kuma:2 + restart: unless-stopped + volumes: + - ./data:/app/data + ports: + # : + - "3001:3001" \ No newline at end of file diff --git a/k8s/xiongxiao.me/apps/waline/app.yaml b/k8s/xiongxiao.me/apps/waline/app.yaml new file mode 100644 index 0000000..c5b3268 --- /dev/null +++ b/k8s/xiongxiao.me/apps/waline/app.yaml @@ -0,0 +1,45 @@ +--- +# Waline - waline.xiongxiao.me +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: waline-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`waline.xiongxiao.me`) + kind: Rule + services: + - name: waline-external + port: 8360 + tls: + certResolver: letsencrypt + +--- +# Waline 服务 (端口 8360, 本地) +apiVersion: v1 +kind: Service +metadata: + name: waline-external + namespace: default +spec: + type: ClusterIP + ports: + - port: 8360 + targetPort: 8360 + protocol: TCP + name: http +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: waline-external + namespace: default +subsets: +- addresses: + - ip: 121.4.112.18 + ports: + - port: 8360 + name: http diff --git a/k8s/xiongxiao.me/config/env.md b/k8s/xiongxiao.me/config/env.md new file mode 100644 index 0000000..8a349c6 --- /dev/null +++ b/k8s/xiongxiao.me/config/env.md @@ -0,0 +1,3 @@ +```sh +cat /etc/systemd/system/k3s.service.env +``` \ No newline at end of file diff --git a/k8s/xiongxiao.me/config/master-token.md b/k8s/xiongxiao.me/config/master-token.md index 48cc184..593a37d 100644 --- a/k8s/xiongxiao.me/config/master-token.md +++ b/k8s/xiongxiao.me/config/master-token.md @@ -13,15 +13,43 @@ Created symlink /etc/systemd/system/multi-user.target.wants/k3s-agent.service ## 设置label -kubectl label nodes vm-32-6-ubuntu machine=library --overwrite + +kubectl label nodes library machine=library --overwrite 删除label kubectl label nodes vm-32-6-ubuntu machine- --overwrite ### on -kubectl label nodes vm-16-2-ubuntu machine=on --overwrite - +kubectl label nodes on machine=on --overwrite ### light -kubectl label nodes vm-12-6-ubuntu machine=light --overwrite \ No newline at end of file +kubectl label nodes light machine=light --overwrite + + +## 关于非内网需要设置实际ip地址 + +```sh +# aliyun, ip: 121.199.37.154 +curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_NODE_IP=121.199.37.154 K3S_NODE_EXTERNAL_IP=121.199.37.154 K3S_URL=https://light.xiongxiao.me:6443 K3S_TOKEN=K1035ea36d4925cfd0a7f7938fb3eff1225e458c1aee4fb99bda40bb95f529913bf::server:03e3ef7d17dadc2471b0f2369248250d sh - +-- --pause-image=docker.1ms.run/rancher/mirrored-pause:3.9 + + +kubectl label nodes aliyun machine=aliyun --overwrite + +``` + +手动创建配置文件 +```sh +# 停止 k3s-agent 服务 +sudo systemctl stop k3s-agent + +# 编辑配置文件 +sudo vim /etc/systemd/system/k3s-agent.service.env + +# 重新加载 systemd 配置 +sudo systemctl daemon-reload + +# 启动服务 +sudo systemctl start k3s-agent +``` \ No newline at end of file diff --git a/k8s/xiongxiao.me/docs/00-master.md b/k8s/xiongxiao.me/docs/00-master.md index 5272afc..2cdea87 100644 --- a/k8s/xiongxiao.me/docs/00-master.md +++ b/k8s/xiongxiao.me/docs/00-master.md @@ -10,7 +10,9 @@ sudo cat /var/lib/rancher/k3s/server/node-token ## 2. 安装 node ```sh -curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh - +curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | + INSTALL_K3S_MIRROR=cn K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh - - \ + --system-default-registry=registry.cn-hangzhou.aliyuncs.com ``` ## 3. 删除 diff --git a/k8s/xiongxiao.me/kevisual-ingress/apps.yaml b/k8s/xiongxiao.me/kevisual-ingress/apps.yaml new file mode 100644 index 0000000..160ad96 --- /dev/null +++ b/k8s/xiongxiao.me/kevisual-ingress/apps.yaml @@ -0,0 +1,19 @@ +# services全使用kevisual-external服务 + +# Kevisual - tale-theme.xiongxiao.me (支持 WebSocket) +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: tale-theme-https + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`tale-theme.xiongxiao.me`) + kind: Rule + services: + - name: kevisual-external + port: 3005 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/k8s/xiongxiao.me/test/hello/hello.yaml b/k8s/xiongxiao.me/test/hello/hello.yaml new file mode 100644 index 0000000..6803122 --- /dev/null +++ b/k8s/xiongxiao.me/test/hello/hello.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hello-world + labels: + app: hello-world +spec: + selector: + matchLabels: + app: hello-world + template: + metadata: + labels: + app: hello-world + spec: + nodeSelector: + machine: aliyun + containers: + - name: hello + image: docker.cnb.cool/kevisual/hello + ports: + - containerPort: 80 + protocol: TCP +--- +apiVersion: v1 +kind: Service +metadata: + name: hello-world + labels: + app: hello-world +spec: + selector: + app: hello-world + ports: + - protocol: TCP + port: 80 + targetPort: 80 + nodePort: 30081 + type: NodePort + +# http://121.199.37.154:30081/ + +# 1.查看 Deployment 状态: +# kubectl get deployment hello-world +# kubectl logs deployment/hello-world +# 2. 查看 Pod 状态: +# kubectl get pods -l app=hello-world + +# 3.查看 Pod 详细信息(包括事件): +# kubectl describe pod -l app=hello-world + +# 4. delete all +# kubectl delete -f hello.yaml + +# 5. delete pod +# kubectl delete pod -l app=hello-world + +# 6. rollupdate +# kubectl set image deployment/hello-world hello=docker.cnb.cool/kevisual/hello:latest + +# 7. 进入 Pod +# kubectl exec -it deployment/hello-world -- /bin/sh \ No newline at end of file diff --git a/k8s/xiongxiao.me/traefik/traefik-complete.yaml b/k8s/xiongxiao.me/traefik/traefik-complete.yaml index 03ed5b6..bbef49b 100644 --- a/k8s/xiongxiao.me/traefik/traefik-complete.yaml +++ b/k8s/xiongxiao.me/traefik/traefik-complete.yaml @@ -145,7 +145,7 @@ spec: effect: NoSchedule containers: - name: traefik - image: traefik:latest + image: docker.1ms.run/library/traefik:v3.6.7 args: - --api.insecure=true - --providers.kubernetescrd diff --git a/k8s/xiongxiao.me/update/rancher/update.md b/k8s/xiongxiao.me/update/rancher/update.md new file mode 100644 index 0000000..a93132c --- /dev/null +++ b/k8s/xiongxiao.me/update/rancher/update.md @@ -0,0 +1,67 @@ +# Rancher 更新指南 + +当前版本 2.13.0 最新版本2.13.1 + +## 1. 备份当前 Rancher + +```bash +# 备份 Rancher Deployment 配置 +kubectl get deployment rancher -n cattle-system -o yaml > rancher-backup.yaml + +# 备份重要数据 (如果是 PVC 存储) +kubectl get pvc -n cattle-system +``` + +## 2. 添加/更新 Rancher Helm 仓库 + +```bash +# 添加 Rancher Helm 仓库 +helm repo add rancher-latest https://releases.rancher.com/server-charts/latest + +# 更新 Helm 仓库 +helm repo update + +# 查看可用的 Rancher 版本 +helm search repo rancher-latest/rancher -l | head -20 +``` + +## 3. 执行更新 + +```bash +# 执行更新 (将 v2.x.x 替换为目标版本) +helm upgrade rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.xiongxiao.me \ + --set replicas=3 \ + --set bootstrapPassword="your-secure-password" + +# 如果有自定义 values.yaml 文件 +# helm upgrade rancher rancher-latest/rancher -f values.yaml --namespace cattle-system +``` + +## 4. 验证更新状态 + +```bash +# 监控 Pod 状态 +kubectl get pods -n cattle-system -w + +# 检查 Deployment 滚动更新状态 +kubectl rollout status deployment/rancher -n cattle-system + +# 查看日志确认正常启动 +kubectl logs -f deploy/rancher -n cattle-system +``` + +## 5. 验证 Rancher 功能 + +- 访问 https://rancher.xiongxiao.me +- 检查集群状态 +- 检查用户、角色、设置是否正常 + +## 注意事项 + +- **版本兼容性**: 确保新版本与 Kubernetes 集群版本兼容 +- **升级路径**: Rancher 升级需要按版本逐步升级 (如 2.6 → 2.7 → 2.8) +- **备份**: 升级前务必备份 Rancher 数据 +- **自定义配置**: 使用自定义 values.yaml 时确保包含所有必要配置 +- **回滚**: 如遇到问题,可使用 `helm rollback rancher --namespace cattle-system`