test: flux local cluster setup with infra-devops post
这个提交包含在:
@@ -0,0 +1,42 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: cnpg17-cluster-hk
|
||||
namespace: infra-data
|
||||
spec:
|
||||
imageName: ghcr.io/cloudnative-pg/postgresql:17.4
|
||||
enableSuperuserAccess: true
|
||||
enablePDB: false
|
||||
instances: 1
|
||||
storage:
|
||||
size: 10Gi
|
||||
postgresql:
|
||||
parameters:
|
||||
archive_timeout: 30min
|
||||
env:
|
||||
- name: AWS_REQUEST_CHECKSUM_CALCULATION
|
||||
value: when_required
|
||||
- name: AWS_RESPONSE_CHECKSUM_VALIDATION
|
||||
value: when_required
|
||||
plugins:
|
||||
- name: barman-cloud.cloudnative-pg.io
|
||||
isWALArchiver: true
|
||||
parameters:
|
||||
barmanObjectName: cnpg17-objectstore-hw
|
||||
serverName: cnpg17-cluster-hk
|
||||
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: cnpg17-cluster-hk-backups
|
||||
namespace: infra-data
|
||||
spec:
|
||||
schedule: "0 0 0 * * *"
|
||||
immediate: true
|
||||
backupOwnerReference: self
|
||||
method: plugin
|
||||
pluginConfiguration:
|
||||
name: barman-cloud.cloudnative-pg.io
|
||||
cluster:
|
||||
name: cnpg17-cluster-hk
|
||||
@@ -0,0 +1,42 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: cnpg17-cluster-sh
|
||||
namespace: infra-data
|
||||
spec:
|
||||
imageName: ghcr.io/cloudnative-pg/postgresql:17.4
|
||||
enableSuperuserAccess: true
|
||||
enablePDB: false
|
||||
instances: 1
|
||||
storage:
|
||||
size: 10Gi
|
||||
postgresql:
|
||||
parameters:
|
||||
archive_timeout: 30min
|
||||
env:
|
||||
- name: AWS_REQUEST_CHECKSUM_CALCULATION
|
||||
value: when_required
|
||||
- name: AWS_RESPONSE_CHECKSUM_VALIDATION
|
||||
value: when_required
|
||||
plugins:
|
||||
- name: barman-cloud.cloudnative-pg.io
|
||||
isWALArchiver: true
|
||||
parameters:
|
||||
barmanObjectName: cnpg17-objectstore-hw
|
||||
serverName: cnpg17-cluster-sh
|
||||
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: cnpg17-cluster-sh-backups
|
||||
namespace: infra-data
|
||||
spec:
|
||||
schedule: "0 0 0 * * *"
|
||||
immediate: true
|
||||
backupOwnerReference: self
|
||||
method: plugin
|
||||
pluginConfiguration:
|
||||
name: barman-cloud.cloudnative-pg.io
|
||||
cluster:
|
||||
name: cnpg17-cluster-sh
|
||||
@@ -0,0 +1,20 @@
|
||||
apiVersion: barmancloud.cnpg.io/v1
|
||||
kind: ObjectStore
|
||||
metadata:
|
||||
name: cnpg17-objectstore-hw
|
||||
namespace: infra-data
|
||||
spec:
|
||||
retentionPolicy: "7d"
|
||||
configuration:
|
||||
destinationPath: s3://devcm/cnpg/
|
||||
endpointURL: https://obs.cn-east-3.myhuaweicloud.com
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: s3-devcm-hw
|
||||
key: ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: s3-devcm-hw
|
||||
key: ACCESS_SECRET_KEY
|
||||
wal:
|
||||
compression: gzip
|
||||
maxParallel: 8
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: cloudnative-pg-plugin-barman
|
||||
namespace: infra-data
|
||||
spec:
|
||||
interval: 30m
|
||||
dependsOn:
|
||||
- name: cloudnative-pg
|
||||
chart:
|
||||
spec:
|
||||
chart: plugin-barman-cloud
|
||||
version: 0.5.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: cloudnative-pg
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
@@ -0,0 +1,20 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: cloudnative-pg
|
||||
namespace: infra-data
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: cloudnative-pg
|
||||
version: 0.27.1
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: cloudnative-pg
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
install:
|
||||
crds: CreateReplace
|
||||
upgrade:
|
||||
crds: CreateReplace
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: valkey-cluster-sh
|
||||
namespace: infra-data
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: valkey-cluster
|
||||
version: 3.0.23
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bitnami
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
image:
|
||||
repository: bitnamilegacy/valkey-cluster
|
||||
cluster:
|
||||
nodes: 1
|
||||
replicas: 0
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- helmrelease-cloudnative-pg.yaml
|
||||
- helmrelease-barman-plugin.yaml
|
||||
- cnpg17-objectstore-hw.yaml
|
||||
- cnpg17-cluster-hk.yaml
|
||||
- cnpg17-cluster-sh.yaml
|
||||
- loadbalancer-hk.yaml
|
||||
- loadbalancer-sh.yaml
|
||||
- helmrelease-valkey-cluster.yaml
|
||||
- reflector-secret-annotations.yaml
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cnpg17-cluster-hk-lb
|
||||
namespace: infra-data
|
||||
spec:
|
||||
selector:
|
||||
cnpg.io/cluster: cnpg17-cluster-hk
|
||||
role: primary
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 65432
|
||||
targetPort: 5432
|
||||
type: LoadBalancer
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cnpg17-cluster-sh-lb
|
||||
namespace: infra-data
|
||||
spec:
|
||||
selector:
|
||||
cnpg.io/cluster: cnpg17-cluster-sh
|
||||
role: primary
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 65431
|
||||
targetPort: 5432
|
||||
type: LoadBalancer
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: infra-data
|
||||
@@ -0,0 +1,41 @@
|
||||
# 给CNPG和Valkey自动生成的secrets添加Reflector注解
|
||||
# 通过SSA force合并注解到已有secrets 使其自动复制到消费方命名空间
|
||||
#
|
||||
# cnpg17-cluster-hk-app → apps (halo), infra-net (crowdsec)
|
||||
# cnpg17-cluster-sh-app → infra-gitops (gitea), infra-monitor (grafana)
|
||||
# valkey-cluster-sh → infra-gitops (gitea)
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: cnpg17-cluster-hk-app
|
||||
namespace: infra-data
|
||||
annotations:
|
||||
kustomize.toolkit.fluxcd.io/prune: disabled
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "apps,infra-net"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "apps,infra-net"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: cnpg17-cluster-sh-app
|
||||
namespace: infra-data
|
||||
annotations:
|
||||
kustomize.toolkit.fluxcd.io/prune: disabled
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "infra-gitops,infra-monitor"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "infra-gitops,infra-monitor"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: valkey-cluster-sh
|
||||
namespace: infra-data
|
||||
annotations:
|
||||
kustomize.toolkit.fluxcd.io/prune: disabled
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "infra-gitops"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "infra-gitops"
|
||||
@@ -0,0 +1,26 @@
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: dnspod
|
||||
labels:
|
||||
app: cert-manager-webhook-dnspod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: admin@dev.cm
|
||||
privateKeySecretRef:
|
||||
name: cert-manager-webhook-dnspod-letsencrypt
|
||||
solvers:
|
||||
- dns01:
|
||||
cnameStrategy: Follow
|
||||
webhook:
|
||||
groupName: cert.dev.cm
|
||||
solverName: dnspod
|
||||
config:
|
||||
ttl: 600
|
||||
secretIdRef:
|
||||
name: dnspod-secret
|
||||
key: secretId
|
||||
secretKeyRef:
|
||||
name: dnspod-secret
|
||||
key: secretKey
|
||||
@@ -0,0 +1,29 @@
|
||||
# 安装后需要将clusterIssuer的cnameStrategy策略设置为Follow
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: cert-manager-webhook-dnspod
|
||||
namespace: infra-devops
|
||||
spec:
|
||||
interval: 30m
|
||||
dependsOn:
|
||||
- name: cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: cert-manager-webhook-dnspod
|
||||
version: 1.4.5
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: imroc
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
image:
|
||||
tag: "1.5.2"
|
||||
namespace: infra-devops
|
||||
certManager:
|
||||
namespace: infra-devops
|
||||
groupName: cert.dev.cm
|
||||
# 此处关闭 选择手动创建 以支持cnameStrategy
|
||||
clusterIssuer:
|
||||
enabled: false
|
||||
@@ -0,0 +1,31 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: cert-manager
|
||||
namespace: infra-devops
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: cert-manager
|
||||
version: v1.19.3
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: jetstack
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
install:
|
||||
crds: CreateReplace
|
||||
upgrade:
|
||||
crds: CreateReplace
|
||||
# 首次install时servicemonitor=false(CRD尚不存在)
|
||||
# infra-monitor层部署后通过SSA patch开启
|
||||
values:
|
||||
crds:
|
||||
enabled: true
|
||||
keep: true
|
||||
enableCertificateOwnerRef: true
|
||||
prometheus:
|
||||
enabled: true
|
||||
servicemonitor:
|
||||
enabled: false
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: reflector
|
||||
namespace: infra-devops
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: reflector
|
||||
version: 9.1.45
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: emberstack
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values: {}
|
||||
@@ -0,0 +1,60 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: velero
|
||||
namespace: infra-devops
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: velero
|
||||
version: 11.3.2
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: vmware-tanzu
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
# 此处暂时切换关闭upgradeCRDs操作 待官方修复后再开启
|
||||
upgradeCRDs: false
|
||||
deployNodeAgent: true
|
||||
snapshotsEnabled: false
|
||||
configuration:
|
||||
backupSyncPeriod: 1h0m0s
|
||||
defaultRepoMaintainFrequency: 3h0m0s
|
||||
repositoryMaintenanceJob:
|
||||
repositoryConfigData:
|
||||
global:
|
||||
keepLatestMaintenanceJobs: 1
|
||||
backupStorageLocation:
|
||||
- name: devcm-hw
|
||||
default: true
|
||||
provider: aws
|
||||
bucket: devcm
|
||||
prefix: velero
|
||||
config:
|
||||
region: cn-east-3
|
||||
s3ForcePathStyle: false
|
||||
s3Url: https://obs.cn-east-3.myhuaweicloud.com
|
||||
checksumAlgorithm: ""
|
||||
extraEnvVars:
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: s3-devcm-hw
|
||||
key: ACCESS_KEY_ID
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: s3-devcm-hw
|
||||
key: ACCESS_SECRET_KEY
|
||||
credentials:
|
||||
useSecret: false
|
||||
initContainers:
|
||||
- name: velero-plugin-for-aws
|
||||
image: velero/velero-plugin-for-aws:v1.13.0
|
||||
volumeMounts:
|
||||
- mountPath: /target
|
||||
name: plugins
|
||||
nodeAgent:
|
||||
# 控制面板不启用 lb节点不启用
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- helmrelease-cert-manager.yaml
|
||||
- helmrelease-cert-manager-webhook-dnspod.yaml
|
||||
- clusterissuer-dnspod.yaml
|
||||
- helmrelease-reflector.yaml
|
||||
- helmrelease-velero.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: infra-devops
|
||||
@@ -0,0 +1,17 @@
|
||||
# 在prometheus-stack部署后 通过SSA patch cert-manager开启ServiceMonitor
|
||||
# cert-manager初始安装时servicemonitor.enabled=false(CRD尚不存在)
|
||||
# infra-monitor层部署时CRD已就绪 此patch合并到已有HelmRelease
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: cert-manager
|
||||
namespace: infra-devops
|
||||
annotations:
|
||||
kustomize.toolkit.fluxcd.io/prune: disabled
|
||||
spec:
|
||||
values:
|
||||
prometheus:
|
||||
servicemonitor:
|
||||
enabled: true
|
||||
interval: 300s
|
||||
prometheusInstance: kube-prometheus
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- helmrelease-cert-manager-patch.yaml
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: gitea-actions-dind-config
|
||||
namespace: infra-gitops
|
||||
data:
|
||||
daemon.json: |-
|
||||
{
|
||||
"mtu": 1280
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: gitea-custom-templates
|
||||
namespace: infra-gitops
|
||||
data:
|
||||
home.tmpl: |-
|
||||
{{template "base/head" .}}
|
||||
<div class="page-content home">
|
||||
<div class="ui stackable middle very relaxed page grid">
|
||||
<div class="sixteen wide center aligned centered column">
|
||||
<div>
|
||||
<img class="logo" width="220" height="220" src="{{AssetUrlPrefix}}/img/logo.svg"/>
|
||||
</div>
|
||||
<div class="hero">
|
||||
<h1 class="ui icon header title">
|
||||
{{AppName}}
|
||||
</h1>
|
||||
<h2><a href="https://dev.cm">Dev.cm</a> - Git {{ctx.Locale.Tr "repository"}}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
||||
extra_links.tmpl: |-
|
||||
<a class="item" href="https://dev.cm" target="_blank">{{if eq ctx.Locale.Lang "zh-CN"}}博客{{else}}Blog{{end}}</a>
|
||||
<a class="item extra-links-end" href="https://fillcode.com" target="_blank">Fillcode</a>
|
||||
<style>
|
||||
.extra-links-end ~ a { display:none !important; }
|
||||
</style>
|
||||
@@ -0,0 +1,47 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: gitea-actions
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 30m
|
||||
dependsOn:
|
||||
- name: gitea
|
||||
chart:
|
||||
spec:
|
||||
chart: actions
|
||||
version: 0.0.2
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: gitea
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
enabled: true
|
||||
statefulset:
|
||||
actRunner:
|
||||
config: |
|
||||
log:
|
||||
level: info
|
||||
cache:
|
||||
enabled: true
|
||||
container:
|
||||
require_docker: true
|
||||
docker_timeout: 300s
|
||||
# 使用bridge网络模式,解决新建任务临时网络mtu与主机不一致的问题
|
||||
network: bridge
|
||||
dind:
|
||||
# 挂载dind docker配置文件,解决mtu带来的网络问题
|
||||
extraVolumeMounts:
|
||||
- name: dind-config-volume
|
||||
mountPath: /etc/docker/daemon.json
|
||||
subPath: daemon.json
|
||||
extraVolumes:
|
||||
- name: dind-config-volume
|
||||
configMap:
|
||||
name: gitea-actions-dind-config
|
||||
persistence:
|
||||
size: 10Gi
|
||||
giteaRootURL: http://gitea-http.infra-gitops.svc.cluster.local:3000
|
||||
existingSecret: gitea-actions
|
||||
existingSecretKey: token
|
||||
@@ -0,0 +1,111 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: gitea
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: gitea
|
||||
version: 12.5.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: gitea
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
redis-cluster:
|
||||
enabled: false
|
||||
postgresql-ha:
|
||||
enabled: false
|
||||
image:
|
||||
tag: 1.25.5
|
||||
ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_set_header Accept-Encoding "";
|
||||
subs_filter_types text/html;
|
||||
subs_filter '<(script|img|link)([^>]*) (src|href)="/' '<$1$2 $3="https://cdn.fillcode.com/git-dev-cm/' ri;
|
||||
subs_filter 'url\(\/' 'url(https://cdn.fillcode.com/git-dev-cm/' ri;
|
||||
subs_filter '<head>' '<head><script src="/__static/pwa-cdn.js"></script>' ri;
|
||||
hosts:
|
||||
- host: git.dev.cm
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
gitea:
|
||||
podAnnotations:
|
||||
backup.velero.io/backup-volumes: data
|
||||
config:
|
||||
APP_NAME: Git Dev.cm
|
||||
RUN_MODE: prod
|
||||
server:
|
||||
DOMAIN: git.dev.cm
|
||||
ROOT_URL: https://git.dev.cm/
|
||||
database:
|
||||
DB_TYPE: postgres
|
||||
HOST: cnpg17-cluster-sh-rw.infra-data:5432
|
||||
NAME: gitea
|
||||
USER: app
|
||||
SSL_MODE: disable
|
||||
session:
|
||||
PROVIDER: redis
|
||||
cache:
|
||||
ADAPTER: redis
|
||||
queue:
|
||||
TYPE: redis
|
||||
repository:
|
||||
DEFAULT_REPO_UNITS: repo.code,repo.releases,repo.issues,repo.pulls
|
||||
actions:
|
||||
ENABLED: true
|
||||
DEFAULT_ACTIONS_URL: github
|
||||
service:
|
||||
DISABLE_REGISTRATION: true
|
||||
NO_REPLY_ADDRESS: noreply.dev.cm
|
||||
picture:
|
||||
GRAVATAR_SOURCE: https://cravatar.cn/avatar/
|
||||
i18n:
|
||||
LANGS: zh-CN,en-US
|
||||
NAMES: 简体中文,English
|
||||
other:
|
||||
SHOW_FOOTER_VERSION: false
|
||||
SHOW_FOOTER_POWERED_BY: false
|
||||
log:
|
||||
LEVEL: Info
|
||||
ui:
|
||||
THEMES: gitea-auto, gitea-light, gitea-dark, github-auto, github-light, github-dark, github-soft-dark
|
||||
DEFAULT_THEME: github-auto
|
||||
additionalConfigFromEnvs:
|
||||
- name: GITEA__DATABASE__PASSWD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: cnpg17-cluster-sh-app
|
||||
key: password
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: valkey-cluster-sh
|
||||
key: valkey-password
|
||||
- name: GITEA__SESSION__PROVIDER_CONFIG
|
||||
value: "redis://:$(REDIS_PASSWORD)@valkey-cluster-sh-headless.infra-data:6379/0?pool_size=100&idle_timeout=180s"
|
||||
- name: GITEA__CACHE__HOST
|
||||
value: "redis://:$(REDIS_PASSWORD)@valkey-cluster-sh-headless.infra-data:6379/0?pool_size=100&idle_timeout=180s"
|
||||
- name: GITEA__QUEUE__CONN_STR
|
||||
value: "redis://:$(REDIS_PASSWORD)@valkey-cluster-sh-headless.infra-data:6379/0?pool_size=100&idle_timeout=180s"
|
||||
valkey-cluster:
|
||||
enabled: false
|
||||
extraVolumes:
|
||||
- name: gitea-custom-templates-volume
|
||||
configMap:
|
||||
name: gitea-custom-templates
|
||||
extraContainerVolumeMounts:
|
||||
- name: gitea-custom-templates-volume
|
||||
subPath: home.tmpl
|
||||
mountPath: /data/gitea/templates/home.tmpl
|
||||
- name: gitea-custom-templates-volume
|
||||
subPath: extra_links.tmpl
|
||||
mountPath: /data/gitea/templates/custom/extra_links.tmpl
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gitea-static
|
||||
namespace: infra-gitops
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_cache cache;
|
||||
proxy_cache_valid 200 302 7d;
|
||||
proxy_cache_valid 404 10m;
|
||||
proxy_cache_valid any 1h;
|
||||
proxy_cache_use_stale error timeout updating http_404 http_500 http_502 http_503 http_504;
|
||||
proxy_cache_bypass $http_x_purge;
|
||||
proxy_ignore_headers Cache-Control;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: git.dev.cm
|
||||
http:
|
||||
paths:
|
||||
- path: /(.*\.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2|ttf|eot)|avatars/[^/]+)$
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: gitea-http
|
||||
port:
|
||||
number: 3000
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- helmrelease-gitea.yaml
|
||||
- helmrelease-gitea-actions.yaml
|
||||
- configmap-templates.yaml
|
||||
- configmap-actions-dind.yaml
|
||||
- ingress-static-gitea.yaml
|
||||
- loadbalancer-ssh.yaml
|
||||
- networkpolicy-gitea.yaml
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gitea-ssh-lb
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: gitea
|
||||
app.kubernetes.io/instance: gitea
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 22
|
||||
targetPort: 2222
|
||||
type: LoadBalancer
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-gitea
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: gitea
|
||||
ingress:
|
||||
- {}
|
||||
egress:
|
||||
- {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
@@ -0,0 +1,57 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: loki
|
||||
namespace: infra-monitor
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: loki
|
||||
version: 6.53.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: grafana
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
deploymentMode: SingleBinary
|
||||
gateway:
|
||||
enabled: false
|
||||
lokiCanary:
|
||||
extraArgs:
|
||||
# 降低测试日志生成条数
|
||||
- -interval=30s
|
||||
- -labelname=service_name
|
||||
- -labelvalue=loki-canary
|
||||
resultsCache:
|
||||
allocatedMemory: 1024
|
||||
chunksCache:
|
||||
allocatedMemory: 1024
|
||||
loki:
|
||||
auth_enabled: false
|
||||
commonConfig:
|
||||
replication_factor: 1
|
||||
limits_config:
|
||||
reject_old_samples_max_age: 168h
|
||||
max_query_series: 10000
|
||||
volume_enabled: true
|
||||
storage:
|
||||
type: "filesystem"
|
||||
schemaConfig:
|
||||
configs:
|
||||
- from: "2024-01-01"
|
||||
store: tsdb
|
||||
index:
|
||||
prefix: loki_index_
|
||||
period: 24h
|
||||
object_store: filesystem
|
||||
schema: v13
|
||||
singleBinary:
|
||||
replicas: 1
|
||||
read:
|
||||
replicas: 0
|
||||
backend:
|
||||
replicas: 0
|
||||
write:
|
||||
replicas: 0
|
||||
@@ -0,0 +1,119 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: prometheus
|
||||
namespace: infra-monitor
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: kube-prometheus-stack
|
||||
version: 81.6.5
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: prometheus-community
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
install:
|
||||
crds: CreateReplace
|
||||
upgrade:
|
||||
crds: CreateReplace
|
||||
values:
|
||||
kubeControllerManager:
|
||||
enabled: false
|
||||
kubeScheduler:
|
||||
enabled: false
|
||||
kubeProxy:
|
||||
enabled: false
|
||||
kubeEtcd:
|
||||
enabled: false
|
||||
|
||||
prometheusOperator: {}
|
||||
|
||||
kube-state-metrics: {}
|
||||
|
||||
grafana:
|
||||
ingress:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_set_header Accept-Encoding "";
|
||||
subs_filter_types text/html;
|
||||
subs_filter '<(script|img|link)([^>]*) (src|href)="/' '<$1$2 $3="https://cdn.fillcode.com/monitor-dev-cm/' ri;
|
||||
subs_filter 'url\(\/' 'url(https://cdn.fillcode.com/monitor-dev-cm/' ri;
|
||||
subs_filter '<head>' '<head><script src="/__static/pwa-cdn.js"></script>' ri;
|
||||
hosts:
|
||||
- monitor.dev.cm
|
||||
paths:
|
||||
- /
|
||||
assertNoLeakedSecrets: false
|
||||
envValueFrom:
|
||||
GF_DATABASE_PASSWORD:
|
||||
secretKeyRef:
|
||||
name: cnpg17-cluster-sh-app
|
||||
key: password
|
||||
grafana.ini:
|
||||
server:
|
||||
root_url: https://monitor.dev.cm/
|
||||
public_dashboards:
|
||||
enabled: false
|
||||
help:
|
||||
enabled: false
|
||||
news:
|
||||
news_feed_enabled: false
|
||||
database:
|
||||
type: postgres
|
||||
host: cnpg17-cluster-sh-rw.infra-data:5432
|
||||
name: grafana
|
||||
user: app
|
||||
password: $__env{GF_DATABASE_PASSWORD}
|
||||
persistence:
|
||||
type: pvc
|
||||
enabled: true
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
size: 10Gi
|
||||
|
||||
prometheus:
|
||||
prometheusSpec:
|
||||
storageSpec:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 30Gi
|
||||
routePrefix: /prometheus
|
||||
serviceMonitorSelectorNilUsesHelmValues: false
|
||||
podMonitorSelectorNilUsesHelmValues: false
|
||||
ruleSelectorNilUsesHelmValues: false
|
||||
scrapeInterval: 1m
|
||||
ingress:
|
||||
enabled: false
|
||||
ingressClassName: nginx
|
||||
hosts:
|
||||
- monitor.dev.cm
|
||||
paths:
|
||||
- /prometheus
|
||||
|
||||
alertmanager:
|
||||
alertmanagerSpec:
|
||||
storage:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
routePrefix: /alertmanager
|
||||
ingress:
|
||||
enabled: false
|
||||
ingressClassName: nginx
|
||||
hosts:
|
||||
- monitor.dev.cm
|
||||
paths:
|
||||
- /alertmanager
|
||||
@@ -0,0 +1,36 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: loki-promtail
|
||||
namespace: infra-monitor
|
||||
spec:
|
||||
interval: 30m
|
||||
dependsOn:
|
||||
- name: loki
|
||||
chart:
|
||||
spec:
|
||||
chart: promtail
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: grafana
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
configmap:
|
||||
enabled: true
|
||||
config:
|
||||
clients:
|
||||
- url: http://loki.infra-monitor:3100/loki/api/v1/push
|
||||
tenant_id: 1
|
||||
snippets:
|
||||
extraRelabelConfigs:
|
||||
# 匹配 devcm-log-collecting/enabled 标签 只有为true时才收集日志
|
||||
- source_labels:
|
||||
[__meta_kubernetes_pod_label_devcm_log_collecting_enabled]
|
||||
action: keep
|
||||
regex: true
|
||||
# 匹配 devcm-log-collecting/only-errors标签并只保留stderr流
|
||||
- source_labels:
|
||||
[__meta_kubernetes_pod_label_devcm_log_collecting_only_errors]
|
||||
action: drop
|
||||
regex: stdout
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: grafana-static
|
||||
namespace: infra-monitor
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "on"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_cache cache;
|
||||
proxy_cache_valid 200 302 7d;
|
||||
proxy_cache_valid 404 10m;
|
||||
proxy_cache_valid any 1h;
|
||||
proxy_cache_use_stale error timeout updating http_404 http_500 http_502 http_503 http_504;
|
||||
proxy_cache_bypass $http_x_purge;
|
||||
proxy_ignore_headers Cache-Control;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: monitor.dev.cm
|
||||
http:
|
||||
paths:
|
||||
- path: /(.*\.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2|ttf|eot)|avatars/[^/]+)$
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: prometheus-grafana
|
||||
port:
|
||||
number: 80
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- helmrelease-loki.yaml
|
||||
- helmrelease-promtail.yaml
|
||||
- helmrelease-prometheus.yaml
|
||||
- ingress-static-grafana.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: infra-monitor
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: dev-cm-crt
|
||||
namespace: infra-net
|
||||
spec:
|
||||
secretName: dev-cm-crt
|
||||
issuerRef:
|
||||
name: dnspod
|
||||
kind: ClusterIssuer
|
||||
group: cert-manager.io
|
||||
dnsNames:
|
||||
- "dev.cm"
|
||||
- "*.dev.cm"
|
||||
- "*.node.dev.cm"
|
||||
@@ -0,0 +1,461 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: static
|
||||
namespace: infra-net
|
||||
data:
|
||||
captcha.html: |
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width,initial-scale=1,user-scalable=no,viewport-fit=cover" name="viewport">
|
||||
<title>出于安全原因 请完成验证</title>
|
||||
<script src="{{captcha_frontend_js}}" async defer></script>
|
||||
<style>
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
#error {
|
||||
position: relative;
|
||||
height: 100vh
|
||||
}
|
||||
|
||||
#error .error {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%)
|
||||
}
|
||||
|
||||
#error .error-bg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
#error .error-bg > div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: #eee
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(1) {
|
||||
left: 20%
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(2) {
|
||||
left: 40%
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(3) {
|
||||
left: 60%
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(4) {
|
||||
left: 80%
|
||||
}
|
||||
|
||||
#error .error-bg > div:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -.5px;
|
||||
-webkit-transform: translateY(-160px);
|
||||
-ms-transform: translateY(-160px);
|
||||
transform: translateY(-160px);
|
||||
height: 160px;
|
||||
width: 2px;
|
||||
background-color: #1cfafe
|
||||
}
|
||||
|
||||
@-webkit-keyframes drop {
|
||||
90% {
|
||||
height: 20px
|
||||
}
|
||||
|
||||
100% {
|
||||
height: 160px;
|
||||
-webkit-transform: translateY(calc(100vh + 160px));
|
||||
transform: translateY(calc(100vh + 160px))
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes drop {
|
||||
90% {
|
||||
height: 20px
|
||||
}
|
||||
|
||||
100% {
|
||||
height: 160px;
|
||||
-webkit-transform: translateY(calc(100vh + 160px));
|
||||
transform: translateY(calc(100vh + 160px))
|
||||
}
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(1):after {
|
||||
-webkit-animation: drop 3s infinite linear;
|
||||
animation: drop 3s infinite linear;
|
||||
-webkit-animation-delay: .2s;
|
||||
animation-delay: .2s
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(2):after {
|
||||
-webkit-animation: drop 2s infinite linear;
|
||||
animation: drop 2s infinite linear;
|
||||
-webkit-animation-delay: .7s;
|
||||
animation-delay: .7s
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(3):after {
|
||||
-webkit-animation: drop 3s infinite linear;
|
||||
animation: drop 3s infinite linear;
|
||||
-webkit-animation-delay: .9s;
|
||||
animation-delay: .9s
|
||||
}
|
||||
|
||||
#error .error-bg > div:nth-child(4):after {
|
||||
-webkit-animation: drop 2s infinite linear;
|
||||
animation: drop 2s infinite linear;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
animation-delay: 1.2s
|
||||
}
|
||||
|
||||
.error {
|
||||
max-width: 520px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.error .error-code {
|
||||
height: 210px;
|
||||
line-height: 210px
|
||||
}
|
||||
|
||||
.error .error-code h1 {
|
||||
font-family: oswald, sans-serif;
|
||||
font-size: 80px;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
text-shadow: 4px 4px 0 #1cfafe
|
||||
}
|
||||
|
||||
.error h2 {
|
||||
font-family: oswald, sans-serif;
|
||||
font-size: 42px;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.6px
|
||||
}
|
||||
|
||||
.error p {
|
||||
font-family: lato, sans-serif;
|
||||
color: #000;
|
||||
font-weight: 400;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 25px
|
||||
}
|
||||
|
||||
.error a {
|
||||
font-family: lato, sans-serif;
|
||||
padding: 10px 30px;
|
||||
display: inline-block;
|
||||
color: #000;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
-webkit-box-shadow: 0 0 0 2px #000, 2px 2px 0 2px #1cfafe;
|
||||
box-shadow: 0 0 0 2px #000, 2px 2px 0 2px #1cfafe;
|
||||
text-decoration: none;
|
||||
-webkit-transition: .2s all;
|
||||
transition: .2s all
|
||||
}
|
||||
|
||||
.error a:not(:first-of-type) {
|
||||
margin-left: 20px
|
||||
}
|
||||
|
||||
.error a:hover {
|
||||
background-color: #1cfafe;
|
||||
-webkit-box-shadow: 0 0 0 0 #000, 0 0 0 2px #1cfafe;
|
||||
box-shadow: 0 0 0 0 #000, 0 0 0 2px #1cfafe
|
||||
}
|
||||
|
||||
.error-social > a {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding: 0;
|
||||
margin: 0 5px
|
||||
}
|
||||
|
||||
.error-social > a:hover {
|
||||
background-color: #1cfafe;
|
||||
-webkit-box-shadow: 0 0 0 0 #000, 0 0 0 2px #1cfafe;
|
||||
box-shadow: 0 0 0 0 #000, 0 0 0 2px #1cfafe
|
||||
}
|
||||
|
||||
#captcha-form {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
height: 65px;
|
||||
overflow: hidden;
|
||||
margin: 0 auto 30px;
|
||||
background-color: #fff;
|
||||
-webkit-box-shadow: 0 0 0 2px #000, 2px 2px 0 2px #1cfafe;
|
||||
box-shadow: 0 0 0 2px #000, 2px 2px 0 2px #1cfafe;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 65px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.loading:has(+ *) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.loading::before {
|
||||
content: "";
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid #000;
|
||||
border-right-color: #1cfafe;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
#captcha {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 480px) {
|
||||
.error .error-code {
|
||||
height: 122px;
|
||||
line-height: 122px
|
||||
}
|
||||
|
||||
.error .error-code h1 {
|
||||
font-size: 60px
|
||||
}
|
||||
|
||||
.error h2 {
|
||||
font-size: 26px
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="error">
|
||||
<div class="error-bg">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="error">
|
||||
<div class="error-code">
|
||||
<h1>FillCode</h1>
|
||||
</div>
|
||||
<h2>请完成验证</h2>
|
||||
<p>请完成下面验证, 页面将会自动跳转到访问页面。</p>
|
||||
<form id="captcha-form" method="POST">
|
||||
<div id="captcha" class="{{captcha_frontend_key}}" data-sitekey="{{captcha_site_key}}"
|
||||
data-callback="captchaCallback" data-size="flexible"></div>
|
||||
<div class="loading">验证码加载中, 请稍等...</div>
|
||||
</form>
|
||||
<a href="mailto:admin@dev.cm">联系我们</a>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function captchaCallback() {
|
||||
setTimeout(() => document.querySelector('#captcha-form').submit(), 500)
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
pwa-cdn.js: |
|
||||
'use strict'
|
||||
|
||||
// 配置
|
||||
const pwaCdnConfig = {
|
||||
cdnUrl: 'https://cdn.fillcode.com/',
|
||||
serviceWorkerUrl: '/__static/sw-cdn.js',
|
||||
staticRegex: /\.(js|css|png|jpg|jpeg|gif|svg|webp|woff|woff2|ttf|ico)$/,
|
||||
debug: false,
|
||||
}
|
||||
|
||||
/**
|
||||
* PWA 初始化函数
|
||||
*/
|
||||
async function initializePWA() {
|
||||
// 检查支持
|
||||
if (!('serviceWorker' in navigator)) return console.log('PWA-CDN: Service Worker not supported')
|
||||
|
||||
let registration;
|
||||
|
||||
try {
|
||||
// 注册Service Worker - 使用相对路径
|
||||
registration = await navigator.serviceWorker.register(pwaCdnConfig.serviceWorkerUrl, {scope: '/'})
|
||||
|
||||
console.log('PWA-CDN: Service Worker registered')
|
||||
} catch (error) {
|
||||
console.error('PWA-CDN: Failed to register Service Worker:', error)
|
||||
}
|
||||
|
||||
// 发送初始配置
|
||||
const sendConfig = () => {
|
||||
registration.active.postMessage({type: 'CONFIG', config: pwaCdnConfig})
|
||||
}
|
||||
|
||||
// 如果注册失败,直接返回错误
|
||||
if(!registration) return console.error('PWA-CDN: Service Worker registration failed, cannot send config')
|
||||
|
||||
// 更新配置函数
|
||||
window.updatePWACDNConfig = (newConfig) => {
|
||||
Object.assign(pwaCdnConfig, newConfig)
|
||||
sendConfig()
|
||||
}
|
||||
|
||||
// 等待Service Worker激活后发送配置
|
||||
if (registration.active) sendConfig()
|
||||
|
||||
// 监听Service Worker更新事件
|
||||
registration.addEventListener('updatefound', () => {
|
||||
const newWorker = registration.installing
|
||||
|
||||
newWorker.addEventListener('statechange', () => {
|
||||
if (newWorker.state === 'activated') sendConfig()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 PWA-CDN
|
||||
* */
|
||||
initializePWA().catch(console.error)
|
||||
|
||||
sw-cdn.js: |
|
||||
'use strict'
|
||||
|
||||
// Service Worker 配置 - 默认值
|
||||
let config = {
|
||||
cdnUrl: 'https://cdn.fillcode.com/',
|
||||
serviceWorkerUrl: '/__static/sw-cdn.js',
|
||||
staticRegex: /(.*\.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2|ttf|eot)|avatars[^/]+)$/,
|
||||
debug: false,
|
||||
}
|
||||
|
||||
// 监听配置更新消息
|
||||
self.addEventListener('message', e => {
|
||||
if (e.data.type !== 'CONFIG') return
|
||||
|
||||
config = e.data.config
|
||||
|
||||
if (config.debug) console.log('PWA-CDN: Config updated', config)
|
||||
})
|
||||
|
||||
// 拦截网络请求
|
||||
self.addEventListener('fetch', e => {
|
||||
const url = new URL(e.request.url)
|
||||
|
||||
// 如果请求不是GET方法,直接返回
|
||||
if (e.request.method !== 'GET') return
|
||||
|
||||
// 如果请求的域名不是当前页面的域名
|
||||
if (url.origin !== self.location.origin) return
|
||||
|
||||
// 过滤__static路径下的请求
|
||||
if (url.pathname.startsWith('/__static/')) return
|
||||
|
||||
// 如果请求的路径不匹配静态资源正则表达式,直接返回
|
||||
if (!config.staticRegex.test(url.pathname)) return
|
||||
|
||||
// 判断是否是强制需要同源请求
|
||||
const requiresSameOrigin = ['worker', 'sharedworker', 'serviceworker'].includes(e.request.destination)
|
||||
|
||||
// 如果是强制需要同源请求的资源类型,直接返回
|
||||
if (requiresSameOrigin) return
|
||||
|
||||
// 开始处理静态资源请求
|
||||
e.respondWith(handleStaticResource(e.request, url))
|
||||
})
|
||||
|
||||
// 处理静态资源请求
|
||||
async function handleStaticResource(request, url) {
|
||||
// 生成CDN子路径
|
||||
const hostname = self.location.hostname
|
||||
const cdnPath = hostname.replace(/\./g, '-')
|
||||
|
||||
const targetUrl = config.cdnUrl + cdnPath + url.pathname + url.search
|
||||
|
||||
if (config.debug) console.log('PWA-CDN:', url.href, '->', targetUrl)
|
||||
|
||||
try {
|
||||
// 创建新请求
|
||||
const newRequest = new Request(targetUrl, {
|
||||
...request,
|
||||
mode: 'cors',
|
||||
redirect: 'error',
|
||||
})
|
||||
|
||||
// 请求目标域名,浏览器会自动处理缓存
|
||||
const response = await fetch(newRequest)
|
||||
|
||||
// 检查响应状态
|
||||
if (!response.ok) throw new Error('PWA-CDN: Non-2xx response detected')
|
||||
|
||||
return response
|
||||
} catch (error) {
|
||||
if (config.debug) console.warn('PWA-CDN: Fallback to original request for', url.href, error)
|
||||
|
||||
// 失败时回退到原始请求
|
||||
return fetch(request)
|
||||
}
|
||||
}
|
||||
|
||||
// Service Worker 生命周期
|
||||
self.addEventListener('install', () => {
|
||||
if (config.debug) console.log('PWA-CDN: Service Worker installing')
|
||||
self.skipWaiting().catch(console.error)
|
||||
})
|
||||
|
||||
self.addEventListener('activate', () => {
|
||||
if (config.debug) console.log('PWA-CDN: Service Worker activated')
|
||||
self.clients.claim().catch(console.error)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: crowdsec
|
||||
namespace: infra-net
|
||||
spec:
|
||||
interval: 30m
|
||||
dependsOn:
|
||||
- name: ingress-nginx
|
||||
- name: loki
|
||||
namespace: infra-monitor
|
||||
chart:
|
||||
spec:
|
||||
chart: crowdsec
|
||||
version: 0.22.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: crowdsec
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
container_runtime: containerd
|
||||
image:
|
||||
tag: v1.7.6
|
||||
agent:
|
||||
isDeployment: true
|
||||
additionalAcquisition:
|
||||
- source: loki
|
||||
log_level: info
|
||||
url: http://loki.infra-monitor:3100/
|
||||
limit: 1000
|
||||
query: |
|
||||
{job="infra-net/ingress-nginx"}
|
||||
labels:
|
||||
type: nginx
|
||||
env:
|
||||
- name: COLLECTIONS
|
||||
value: "crowdsecurity/base-http-scenarios crowdsecurity/http-dos"
|
||||
- name: SCENARIOS
|
||||
value: "crowdsecurity/nginx-req-limit-exceeded"
|
||||
persistentVolume:
|
||||
config:
|
||||
enabled: false
|
||||
appsec:
|
||||
enabled: false
|
||||
acquisitions:
|
||||
- source: appsec
|
||||
listen_addr: "0.0.0.0:7422"
|
||||
path: /
|
||||
appsec_config: crowdsecurity/crs-vpatch
|
||||
labels:
|
||||
type: appsec
|
||||
configs:
|
||||
mycustom-appsec-config.yaml: |
|
||||
name: crowdsecurity/crs-vpatch
|
||||
default_remediation: ban
|
||||
#log_level: debug
|
||||
outofband_rules:
|
||||
- crowdsecurity/crs
|
||||
inband_rules:
|
||||
- crowdsecurity/base-config
|
||||
- crowdsecurity/vpatch-*
|
||||
env:
|
||||
- name: COLLECTIONS
|
||||
value: "crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-crs"
|
||||
lapi:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 150m
|
||||
memory: 100Mi
|
||||
persistentVolume:
|
||||
config:
|
||||
enabled: false
|
||||
data:
|
||||
enabled: false
|
||||
env:
|
||||
- name: DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: cnpg17-cluster-hk-app
|
||||
key: password
|
||||
config:
|
||||
# api config.yaml配置
|
||||
config.yaml.local: |
|
||||
db_config:
|
||||
type: postgresql
|
||||
host: cnpg17-cluster-hk-rw.infra-data
|
||||
port: 5432
|
||||
db_name: crowdsec
|
||||
user: app
|
||||
password: ${DB_PASSWORD}
|
||||
sslmode: require
|
||||
api:
|
||||
server:
|
||||
auto_registration:
|
||||
enabled: true
|
||||
token: "${REGISTRATION_TOKEN}"
|
||||
allowed_ranges:
|
||||
- "127.0.0.1/32"
|
||||
- "192.168.0.0/16"
|
||||
- "172.16.0.0/12"
|
||||
- "10.0.0.0/8"
|
||||
# api profiles.yaml配置
|
||||
profiles.yaml: |
|
||||
name: captcha_remediation
|
||||
filters:
|
||||
# 规则过滤条件 1.范围为Ip 2.触发场景为http或nginx 3.24小时内决策次数小于等于3
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Ip" &&
|
||||
(Alert.GetScenario() contains "http" || Alert.GetScenario() contains "nginx") &&
|
||||
GetDecisionsSinceCount(Alert.GetValue(), "24h") <= 3
|
||||
decisions:
|
||||
- type: captcha
|
||||
duration: 4h
|
||||
on_success: break
|
||||
---
|
||||
name: default_ip_remediation
|
||||
filters:
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Ip"
|
||||
decisions:
|
||||
- type: ban
|
||||
duration: 4h
|
||||
on_success: break
|
||||
---
|
||||
name: default_range_remediation
|
||||
filters:
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Range"
|
||||
decisions:
|
||||
- type: ban
|
||||
duration: 4h
|
||||
on_success: break
|
||||
# agent parsers 配置
|
||||
parsers:
|
||||
s01-parse:
|
||||
# 新增nginx json日志解析
|
||||
nginx-logs.yaml: |
|
||||
filter: "evt.Parsed.program startsWith 'nginx'"
|
||||
onsuccess: next_stage
|
||||
name: crowdsecurity/nginx-logs
|
||||
description: "Parse nginx access and error logs"
|
||||
pattern_syntax:
|
||||
NGCUSTOMURIPATH: "(?:/[A-Za-z0-9$.+!*'\\(\\)\\{\\},~:;=@\\#%&_\\-]*)+"
|
||||
NGCUSTOMURIPATHPARAM: '%{NGCUSTOMURIPATH}(?:%{URIPARAM})?'
|
||||
nodes:
|
||||
# nginx access logs
|
||||
- filter: TrimSpace(evt.Parsed.message) startsWith "{" && UnmarshalJSON(evt.Parsed.message, evt.Unmarshaled, "nginx") in ["", nil]
|
||||
statics:
|
||||
- meta: service
|
||||
value: http
|
||||
- meta: log_type
|
||||
value: http_access-log
|
||||
- target: evt.StrTime
|
||||
expression: evt.Unmarshaled.nginx.time_local
|
||||
- meta: source_ip
|
||||
expression: evt.Unmarshaled.nginx.remote_addr
|
||||
- meta: http_status
|
||||
expression: evt.Unmarshaled.nginx.status
|
||||
- meta: http_path
|
||||
expression: evt.Unmarshaled.nginx.request_uri
|
||||
- meta: http_verb
|
||||
expression: evt.Unmarshaled.nginx.request_method
|
||||
- meta: http_user_agent
|
||||
expression: evt.Unmarshaled.nginx.http_user_agent
|
||||
- meta: target_fqdn
|
||||
expression: evt.Unmarshaled.nginx.server_name
|
||||
# nginx error logs
|
||||
- grok:
|
||||
pattern: '(%{IPORHOST:target_fqdn} )?%{NGINXERRTIME:time} \[%{LOGLEVEL:loglevel}\] %{NONNEGINT:pid}#%{NONNEGINT:tid}: (\*%{NONNEGINT:cid} )?%{GREEDYDATA:message}, client: %{IPORHOST:remote_addr}, server: %{DATA:target_fqdn}, request: "%{WORD:verb} ([^/]+)?%{NGCUSTOMURIPATHPARAM:request}( HTTP/%{NUMBER:http_version})?", host: "%{IPORHOST}(:%{NONNEGINT})?"'
|
||||
apply_on: message
|
||||
statics:
|
||||
- meta: service
|
||||
value: http
|
||||
- meta: log_type
|
||||
value: http_error-log
|
||||
- target: evt.StrTime
|
||||
expression: evt.Parsed.time
|
||||
- meta: source_ip
|
||||
expression: evt.Parsed.remote_addr
|
||||
- meta: http_status
|
||||
expression: evt.Parsed.status
|
||||
- meta: http_path
|
||||
expression: evt.Parsed.request
|
||||
- meta: http_verb
|
||||
expression: evt.Parsed.verb
|
||||
- meta: http_user_agent
|
||||
expression: evt.Parsed.http_user_agent
|
||||
- meta: target_fqdn
|
||||
expression: evt.Parsed.target_fqdn
|
||||
pattern_syntax:
|
||||
NO_DOUBLE_QUOTE: '[^"]+'
|
||||
onsuccess: next_stage
|
||||
nodes:
|
||||
- filter: "evt.Parsed.message contains 'was not found in'"
|
||||
pattern_syntax:
|
||||
USER_NOT_FOUND: 'user "%{NO_DOUBLE_QUOTE:username}" was not found in "%{NO_DOUBLE_QUOTE}"'
|
||||
grok:
|
||||
pattern: '%{USER_NOT_FOUND}'
|
||||
apply_on: message
|
||||
statics:
|
||||
- meta: sub_type
|
||||
value: "auth_fail"
|
||||
- meta: username
|
||||
expression: evt.Parsed.username
|
||||
- filter: "evt.Parsed.message contains 'password mismatch'"
|
||||
pattern_syntax:
|
||||
PASSWORD_MISMATCH: 'user "%{NO_DOUBLE_QUOTE:username}": password mismatch'
|
||||
grok:
|
||||
pattern: '%{PASSWORD_MISMATCH}'
|
||||
apply_on: message
|
||||
statics:
|
||||
- meta: sub_type
|
||||
value: "auth_fail"
|
||||
- meta: username
|
||||
expression: evt.Parsed.username
|
||||
- filter: "evt.Parsed.message contains 'limiting requests, excess'"
|
||||
statics:
|
||||
- meta: sub_type
|
||||
value: "req_limit_exceeded"
|
||||
@@ -0,0 +1,195 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: ingress-nginx
|
||||
namespace: infra-net
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: ingress-nginx
|
||||
version: 4.13.2
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: ingress-nginx
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
fullnameOverride: ingress-nginx
|
||||
controller:
|
||||
image:
|
||||
registry: docker.io
|
||||
image: crowdsecurity/controller
|
||||
tag: v1.13.2
|
||||
digest: sha256:4575be24781cad35f8e58437db6a3f492df2a3167fed2b6759a6ff0dc3488d56
|
||||
labels:
|
||||
devcm-log-collecting/enabled: "true"
|
||||
kind: DaemonSet
|
||||
hostNetwork: true
|
||||
hostPort:
|
||||
enabled: true
|
||||
service:
|
||||
enabled: false
|
||||
publishService:
|
||||
enabled: false
|
||||
# 禁用默认的注解验证以防止冲突
|
||||
enableAnnotationValidations: false
|
||||
config:
|
||||
use-forwarded-headers: "true"
|
||||
enable-real-ip: "true"
|
||||
forwarded-for-header: "X-Dev-Cm-Real-IP"
|
||||
proxy-real-ip-cidr: "0.0.0.0/0"
|
||||
allow-snippet-annotations: "true"
|
||||
annotations-risk-level: Critical
|
||||
# 启用http2
|
||||
use-http2: "true"
|
||||
# http to https重定向
|
||||
ssl-redirect: "true"
|
||||
# 自定义错误页面
|
||||
custom-http-errors: "403,404,502,503"
|
||||
# 全局限速配置
|
||||
limit-req-status-code: "429"
|
||||
limit-conn-status-code: "429"
|
||||
http-snippet: |
|
||||
# lua插件配置
|
||||
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
# 缓存配置
|
||||
proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=cache:2m max_size=100m inactive=7d use_temp_path=off;
|
||||
proxy_cache_key $uri$is_args$args;
|
||||
proxy_cache_lock on;
|
||||
proxy_cache_use_stale updating;
|
||||
# 全局限速配置
|
||||
limit_req_zone $binary_remote_addr zone=global_limit:20m rate=20r/s;
|
||||
limit_req zone=global_limit burst=50 nodelay;
|
||||
server-snippet: |
|
||||
# dns配置 配置在http块下会出现重复配置 所以配置在server块下
|
||||
resolver 169.254.20.10 10.43.0.10 ipv6=off;
|
||||
# 代理全局静态资源 可提供serviceWorker的支持
|
||||
location ^~ /__static/ {
|
||||
proxy_pass http://ingress-nginx-defaultbackend.infra-net.svc.cluster.local/static/;
|
||||
proxy_set_header Host $host;
|
||||
add_header Service-Worker-Allowed "/";
|
||||
}
|
||||
# 启用geoip2模块
|
||||
use-geoip: "false"
|
||||
use-geoip2: "true"
|
||||
# 日志配置
|
||||
log-format-escape-json: "true"
|
||||
log-format-upstream: '{
|
||||
"msec": "$msec",
|
||||
"connection": "$connection",
|
||||
"connection_requests": "$connection_requests",
|
||||
"pid": "$pid",
|
||||
"request_id": "$request_id",
|
||||
"request_length": "$request_length",
|
||||
"remote_addr": "$remote_addr",
|
||||
"remote_user": "$remote_user",
|
||||
"remote_port": "$remote_port",
|
||||
"time_local": "$time_local",
|
||||
"time_iso8601": "$time_iso8601",
|
||||
"request": "$request",
|
||||
"request_uri": "$request_uri",
|
||||
"args": "$args",
|
||||
"status": "$status",
|
||||
"body_bytes_sent": "$body_bytes_sent",
|
||||
"bytes_sent": "$bytes_sent",
|
||||
"http_referer": "$http_referer",
|
||||
"http_user_agent": "$http_user_agent",
|
||||
"http_x_forwarded_for": "$http_x_forwarded_for",
|
||||
"http_host": "$http_host",
|
||||
"http_upgrade": "$http_upgrade",
|
||||
"server_name": "$server_name",
|
||||
"request_time": "$request_time",
|
||||
"upstream": "$upstream_addr",
|
||||
"upstream_connect_time": "$upstream_connect_time",
|
||||
"upstream_header_time": "$upstream_header_time",
|
||||
"upstream_response_time": "$upstream_response_time",
|
||||
"upstream_response_length": "$upstream_response_length",
|
||||
"upstream_cache_status": "$upstream_cache_status",
|
||||
"ssl_protocol": "$ssl_protocol",
|
||||
"ssl_cipher": "$ssl_cipher",
|
||||
"scheme": "$scheme",
|
||||
"request_method": "$request_method",
|
||||
"server_protocol": "$server_protocol",
|
||||
"pipe": "$pipe",
|
||||
"gzip_ratio": "$gzip_ratio",
|
||||
"http_cf_ray": "$http_cf_ray",
|
||||
"geoip_country_code": "$geoip2_city_country_code",
|
||||
"geoip_city": "$geoip2_city",
|
||||
"geoip_org": "$geoip2_org",
|
||||
"geoip_longitude": "$geoip2_longitude",
|
||||
"geoip_latitude": "$geoip2_latitude",
|
||||
"level": "info"
|
||||
}'
|
||||
# crowdsec插件配置
|
||||
plugins: "crowdsec"
|
||||
lua-shared-dicts: "crowdsec_cache: 50m"
|
||||
# 启用geoip2模块
|
||||
maxmindLicenseKey: ""
|
||||
extraArgs:
|
||||
default-ssl-certificate: "infra-net/dev-cm-crt"
|
||||
# crowdsec插件配置
|
||||
extraInitContainers:
|
||||
- name: init-clone-crowdsec-bouncer
|
||||
image: crowdsecurity/lua-bouncer-plugin:v1.1.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: SHELL
|
||||
value: "/bin/sh"
|
||||
- name: API_URL
|
||||
value: "http://crowdsec-service.infra-net.svc.cluster.local:8080"
|
||||
- name: API_KEY
|
||||
value: "ImxBThnyiNm224V5DHYPY63KPAcyJ+WF0rm18Gr4M80"
|
||||
- name: BOUNCER_CONFIG
|
||||
value: "/crowdsec/crowdsec-bouncer.conf"
|
||||
- name: MODE
|
||||
value: "live"
|
||||
- name: CACHE_EXPIRATION
|
||||
value: "3"
|
||||
- name: UPDATE_FREQUENCY
|
||||
value: "10"
|
||||
- name: REQUEST_TIMEOUT
|
||||
value: "1000"
|
||||
- name: CAPTCHA_PROVIDER
|
||||
value: "turnstile"
|
||||
- name: SITE_KEY
|
||||
value: "0x4AAAAAAAxJ2RPNWzn2LCc-"
|
||||
- name: SECRET_KEY
|
||||
value: "0x4AAAAAAAxJ2dwFOaNg5ae3c6wYTmWH0bU"
|
||||
- name: CAPTCHA_TEMPLATE_PATH
|
||||
value: /etc/nginx/static/captcha.html
|
||||
command: ['/bin/sh', '-c']
|
||||
args: ['sh /docker_start.sh; mkdir -p /lua_plugins/crowdsec/; cp -R /crowdsec/* /lua_plugins/crowdsec/']
|
||||
volumeMounts:
|
||||
- name: crowdsec-bouncer-plugin
|
||||
mountPath: /lua_plugins
|
||||
extraVolumes:
|
||||
- name: crowdsec-bouncer-plugin
|
||||
emptyDir: {}
|
||||
- name: static
|
||||
configMap:
|
||||
name: static
|
||||
extraVolumeMounts:
|
||||
- name: crowdsec-bouncer-plugin
|
||||
mountPath: /etc/nginx/lua/plugins/crowdsec
|
||||
subPath: crowdsec
|
||||
- name: static
|
||||
mountPath: /etc/nginx/static
|
||||
defaultBackend:
|
||||
enabled: true
|
||||
image:
|
||||
registry: docker.io
|
||||
image: devcm/default-backend
|
||||
tag: v0.2.0
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 1
|
||||
maxReplicas: 3
|
||||
targetCPUUtilizationPercentage: 80
|
||||
extraVolumes:
|
||||
- name: static
|
||||
configMap:
|
||||
name: static
|
||||
extraVolumeMounts:
|
||||
- name: static
|
||||
mountPath: /app/static
|
||||
@@ -0,0 +1,39 @@
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: tailscale-derp-hk
|
||||
namespace: infra-net
|
||||
spec:
|
||||
interval: 30m
|
||||
chart:
|
||||
spec:
|
||||
chart: tailscale-derp
|
||||
version: 0.0.9
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: devcm-repo
|
||||
namespace: infra-gitops
|
||||
interval: 12h
|
||||
values:
|
||||
image:
|
||||
tag: v1.94.1
|
||||
hostNetwork: true
|
||||
extraVolumes:
|
||||
- name: cert-volume
|
||||
secret:
|
||||
secretName: dev-cm-crt
|
||||
items:
|
||||
- key: tls.key
|
||||
path: tchk.node.dev.cm.key
|
||||
- key: tls.crt
|
||||
path: tchk.node.dev.cm.crt
|
||||
extraVolumeMounts:
|
||||
- name: cert-volume
|
||||
mountPath: /certs
|
||||
derp:
|
||||
hostname: "tchk.node.dev.cm"
|
||||
verify_clients: true
|
||||
http_port: -1
|
||||
https_port: 30443
|
||||
stun_port: 33478
|
||||
certdir: /certs
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: cdn
|
||||
namespace: infra-net
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: "/$3"
|
||||
# 重定向配置
|
||||
nginx.ingress.kubernetes.io/proxy-redirect-from: "/"
|
||||
nginx.ingress.kubernetes.io/proxy-redirect-to: "/$1/"
|
||||
# 添加允许跨域请求
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "https://dev.cm, https://*.dev.cm, https://fillcode.cm, https://*.fillcode.cm"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
# cookie配置
|
||||
nginx.ingress.kubernetes.io/proxy-cookie-domain: "~^(.+)$ cdn.fillcode.com"
|
||||
nginx.ingress.kubernetes.io/proxy-cookie-path: "/ /$1"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
proxy_cookie_flags ~ SameSite=None Secure;
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: cdn.fillcode.com
|
||||
http:
|
||||
paths:
|
||||
- path: /(dev-cm)(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: cdn-halo
|
||||
port:
|
||||
number: 80
|
||||
- path: /(git-dev-cm)(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: cdn-gitea-http
|
||||
port:
|
||||
number: 3000
|
||||
- path: /(monitor-dev-cm)(/|$)(.*)
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: cdn-prometheus-grafana
|
||||
port:
|
||||
number: 80
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cdn-halo
|
||||
namespace: infra-net
|
||||
spec:
|
||||
type: ExternalName
|
||||
externalName: halo.apps.svc.cluster.local
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cdn-gitea-http
|
||||
namespace: infra-net
|
||||
spec:
|
||||
type: ExternalName
|
||||
externalName: gitea-http.infra-gitops.svc.cluster.local
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cdn-prometheus-grafana
|
||||
namespace: infra-net
|
||||
spec:
|
||||
type: ExternalName
|
||||
externalName: prometheus-grafana.infra-monitor.svc.cluster.local
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- helmrelease-ingress-nginx.yaml
|
||||
- configmap-static.yaml
|
||||
- certificate-dev-cm.yaml
|
||||
- ingress-cdn.yaml
|
||||
- helmrelease-crowdsec.yaml
|
||||
- helmrelease-tailscale-derp.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: infra-net
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: coredns-custom
|
||||
namespace: kube-system
|
||||
data:
|
||||
local.override: |
|
||||
# 腾讯云内网DNS会将HINFO解析请求返回本机 造成循环 此处直接屏蔽处理
|
||||
template ANY HINFO . {
|
||||
rcode NXDOMAIN
|
||||
}
|
||||
|
||||
local.server: |
|
||||
#
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- configmap-coredns.yaml
|
||||
- nodelocaldns.yaml
|
||||
@@ -0,0 +1,204 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: node-local-dns
|
||||
namespace: kube-system
|
||||
labels:
|
||||
kubernetes.io/cluster-service: "true"
|
||||
addonmanager.kubernetes.io/mode: Reconcile
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: kube-dns-upstream
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: kube-dns
|
||||
kubernetes.io/cluster-service: "true"
|
||||
addonmanager.kubernetes.io/mode: Reconcile
|
||||
kubernetes.io/name: "KubeDNSUpstream"
|
||||
spec:
|
||||
ports:
|
||||
- name: dns
|
||||
port: 53
|
||||
protocol: UDP
|
||||
targetPort: 53
|
||||
- name: dns-tcp
|
||||
port: 53
|
||||
protocol: TCP
|
||||
targetPort: 53
|
||||
selector:
|
||||
k8s-app: kube-dns
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: node-local-dns
|
||||
namespace: kube-system
|
||||
labels:
|
||||
addonmanager.kubernetes.io/mode: Reconcile
|
||||
data:
|
||||
Corefile: |
|
||||
# 腾讯云内网DNS会将HINFO解析请求返回本机 造成循环 此处直接屏蔽处理
|
||||
(disableHINFO) {
|
||||
template ANY HINFO . {
|
||||
rcode NXDOMAIN
|
||||
}
|
||||
}
|
||||
cluster.local:53 {
|
||||
errors
|
||||
cache {
|
||||
success 9984 30
|
||||
denial 9984 5
|
||||
}
|
||||
reload
|
||||
loop
|
||||
bind 169.254.20.10 10.43.0.10
|
||||
forward . __PILLAR__CLUSTER__DNS__ {
|
||||
force_tcp
|
||||
}
|
||||
prometheus :9253
|
||||
health 169.254.20.10:8080
|
||||
import disableHINFO
|
||||
}
|
||||
in-addr.arpa:53 {
|
||||
errors
|
||||
cache 30
|
||||
reload
|
||||
loop
|
||||
bind 169.254.20.10 10.43.0.10
|
||||
forward . __PILLAR__CLUSTER__DNS__ {
|
||||
force_tcp
|
||||
}
|
||||
prometheus :9253
|
||||
import disableHINFO
|
||||
}
|
||||
ip6.arpa:53 {
|
||||
errors
|
||||
cache 30
|
||||
reload
|
||||
loop
|
||||
bind 169.254.20.10 10.43.0.10
|
||||
forward . __PILLAR__CLUSTER__DNS__ {
|
||||
force_tcp
|
||||
}
|
||||
prometheus :9253
|
||||
import disableHINFO
|
||||
}
|
||||
.:53 {
|
||||
errors
|
||||
cache 30
|
||||
reload
|
||||
loop
|
||||
bind 169.254.20.10 10.43.0.10
|
||||
forward . __PILLAR__UPSTREAM__SERVERS__
|
||||
prometheus :9253
|
||||
import disableHINFO
|
||||
}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: node-local-dns
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: node-local-dns
|
||||
kubernetes.io/cluster-service: "true"
|
||||
addonmanager.kubernetes.io/mode: Reconcile
|
||||
spec:
|
||||
updateStrategy:
|
||||
rollingUpdate:
|
||||
maxUnavailable: 10%
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: node-local-dns
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: node-local-dns
|
||||
annotations:
|
||||
prometheus.io/port: "9253"
|
||||
prometheus.io/scrape: "true"
|
||||
spec:
|
||||
priorityClassName: system-node-critical
|
||||
serviceAccountName: node-local-dns
|
||||
hostNetwork: true
|
||||
dnsPolicy: Default # Don't use cluster DNS.
|
||||
tolerations:
|
||||
- key: "CriticalAddonsOnly"
|
||||
operator: "Exists"
|
||||
- effect: "NoExecute"
|
||||
operator: "Exists"
|
||||
- effect: "NoSchedule"
|
||||
operator: "Exists"
|
||||
containers:
|
||||
- name: node-cache
|
||||
image: registry.k8s.io/dns/k8s-dns-node-cache:1.26.7
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
memory: 5Mi
|
||||
args: [ "-localip", "169.254.20.10,10.43.0.10", "-conf", "/etc/Corefile", "-upstreamsvc", "kube-dns-upstream" ]
|
||||
securityContext:
|
||||
capabilities:
|
||||
add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
- containerPort: 53
|
||||
name: dns
|
||||
protocol: UDP
|
||||
- containerPort: 53
|
||||
name: dns-tcp
|
||||
protocol: TCP
|
||||
- containerPort: 9253
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
host: 169.254.20.10
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 60
|
||||
timeoutSeconds: 5
|
||||
volumeMounts:
|
||||
- mountPath: /run/xtables.lock
|
||||
name: xtables-lock
|
||||
readOnly: false
|
||||
- name: config-volume
|
||||
mountPath: /etc/coredns
|
||||
- name: kube-dns-config
|
||||
mountPath: /etc/kube-dns
|
||||
volumes:
|
||||
- name: xtables-lock
|
||||
hostPath:
|
||||
path: /run/xtables.lock
|
||||
type: FileOrCreate
|
||||
- name: kube-dns-config
|
||||
configMap:
|
||||
name: kube-dns
|
||||
optional: true
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: node-local-dns
|
||||
items:
|
||||
- key: Corefile
|
||||
path: Corefile.base
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
prometheus.io/port: "9253"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
k8s-app: node-local-dns
|
||||
name: node-local-dns
|
||||
namespace: kube-system
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: metrics
|
||||
port: 9253
|
||||
targetPort: 9253
|
||||
selector:
|
||||
k8s-app: node-local-dns
|
||||
@@ -0,0 +1,141 @@
|
||||
# cert-manager
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: jetstack
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://charts.jetstack.io
|
||||
---
|
||||
# cert-manager-webhook-dnspod (OCI)
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: imroc
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
type: oci
|
||||
url: oci://registry-1.docker.io/imroc
|
||||
---
|
||||
# reflector
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: emberstack
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://emberstack.github.io/helm-charts
|
||||
---
|
||||
# velero
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: vmware-tanzu
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://vmware-tanzu.github.io/helm-charts
|
||||
---
|
||||
# cloudnative-pg, plugin-barman-cloud
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: cloudnative-pg
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://cloudnative-pg.github.io/charts
|
||||
---
|
||||
# valkey-cluster (OCI)
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: bitnami
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
type: oci
|
||||
url: oci://registry-1.docker.io/bitnamicharts
|
||||
---
|
||||
# ingress-nginx
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: ingress-nginx
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://kubernetes.github.io/ingress-nginx
|
||||
---
|
||||
# crowdsec
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: crowdsec
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://crowdsecurity.github.io/helm-charts
|
||||
---
|
||||
# tailscale-derp, rustdesk-server
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: devcm-repo
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://devcm-repo.github.io/helm-charts
|
||||
---
|
||||
# loki, promtail
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: grafana
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://grafana.github.io/helm-charts
|
||||
---
|
||||
# kube-prometheus-stack
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: prometheus-community
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://prometheus-community.github.io/helm-charts
|
||||
---
|
||||
# gitea, gitea-actions
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: gitea
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://dl.gitea.com/charts
|
||||
---
|
||||
# whoami
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: cowboysysop
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://cowboysysop.github.io/charts/
|
||||
---
|
||||
# halo
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: halo
|
||||
namespace: infra-gitops
|
||||
spec:
|
||||
interval: 24h
|
||||
url: https://halo-sigs.github.io/charts/
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- helm-repositories.yaml
|
||||
在新议题中引用
屏蔽一个用户