AI 摘要
文章讲述在Kubernetes集群中部署JumpServer的两种方法,使用Helm安装,涉及Traefik配置、Metallb负载均衡、依赖的PostgreSQL与Redis,并解决GitLab占用22端口后改用2222的SSH访问,以及外部数据库场景下的配置与验证。
一、环境准备
- kubenetes
- k8s
- harbor
- dnsmasq
- helm
- cert-manager
- traefik
- metallb
gitlab 占用了 ssh 22 端口,这里为了图方便,不换 ip 了,就改用默认的 2222 端口。
二、安装【法一】
2.1 traefik 配置
- 添加 helm 仓库
1 2
| helm repo add jumpserver https://jumpserver.github.io/helm-charts helm repo update jumpserver
|
- 给 traefik 添加端口的配置
1
| vim /opt/selfhost/infra-deployment/traefik/v3-traefik-ssh.yaml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ingressClass: enabled: true isDefaultClass: true
api: dashboard: true
ingressRoute: dashboard: enabled: false
ports: ssh: port: 2222 exposedPort: 22 protocol: TCP expose: default: true jms-ssh: port: 2223 exposedPort: 2222 protocol: TCP expose: default: true
|
- 更新
traefik
1
| helm upgrade traefik traefik/traefik -n traefik -f /opt/selfhost/infra-deployment/traefik/v3-traefik-ssh.yaml
|
- 验证
1
| kubectl -n traefik get svc traefik -o wide
|
2.2 jms 依赖的组件
主要是 pgsql、redis、命名空间、ingress 等
- 编辑资源清单文件
1
| vim jumpserver-stack.yaml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
apiVersion: v1 kind: Namespace metadata: name: jumpserver ---
apiVersion: v1 kind: Secret metadata: name: jms-postgresql namespace: jumpserver type: Opaque stringData: POSTGRES_DB: jumpserver POSTGRES_USER: jumpserver POSTGRES_PASSWORD: "u4bWW0RTZMFeqVPGI315" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: jms-postgresql-data namespace: jumpserver spec: accessModes: - ReadWriteOnce storageClassName: nfs-client resources: requests: storage: 10Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: jms-postgresql namespace: jumpserver spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: jms-postgresql template: metadata: labels: app: jms-postgresql spec: containers: - name: postgresql image: postgres:16-alpine envFrom: - secretRef: name: jms-postgresql env: - name: PGDATA value: /var/lib/postgresql/data/pgdata ports: - containerPort: 5432 readinessProbe: exec: command: ["pg_isready", "-U", "jumpserver", "-d", "jumpserver"] initialDelaySeconds: 10 periodSeconds: 5 volumeMounts: - name: data mountPath: /var/lib/postgresql/data volumes: - name: data persistentVolumeClaim: claimName: jms-postgresql-data --- apiVersion: v1 kind: Service metadata: name: jms-postgresql namespace: jumpserver spec: selector: app: jms-postgresql ports: - port: 5432 targetPort: 5432 ---
apiVersion: v1 kind: Secret metadata: name: jms-redis namespace: jumpserver type: Opaque stringData: REDIS_PASSWORD: "62rnrIY03ilA8TZF3vI3" --- apiVersion: apps/v1 kind: Deployment metadata: name: jms-redis namespace: jumpserver spec: replicas: 1 selector: matchLabels: app: jms-redis template: metadata: labels: app: jms-redis spec: containers: - name: redis image: redis:7-alpine args: ["--requirepass", "$(REDIS_PASSWORD)"] env: - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: jms-redis key: REDIS_PASSWORD ports: - containerPort: 6379 readinessProbe: exec: command: ["sh", "-c", "redis-cli -a \"$REDIS_PASSWORD\" ping"] initialDelaySeconds: 5 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: jms-redis namespace: jumpserver spec: selector: app: jms-redis ports: - port: 6379 targetPort: 6379 ---
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: jms-web namespace: jumpserver annotations: cert-manager.io/cluster-issuer: qx-ca-issuer spec: ingressClassName: traefik tls: - hosts: - jms.qx.lab secretName: jms-qx-lab-tls rules: - host: jms.qx.lab http: paths: - path: / pathType: Prefix backend: service: name: jms-jumpserver-jms-web port: number: 80 ---
apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: jms-ssh namespace: jumpserver spec: entryPoints: - jms-ssh routes: - match: HostSNI(`*`) services: - name: jms-jumpserver-jms-koko port: 2222
|
- 创建资源
1
| kubectl apply -f jumpserver-stack.yaml
|
- 验证
1 2
| kubectl -n jumpserver rollout status deploy/jms-postgresql kubectl -n jumpserver rollout status deploy/jms-redis
|
2.3 helm 安装 jumpserver
- 创建
values.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
ingress: enabled: false
externalDatabase: engine: postgresql host: jms-postgresql port: 5432 user: jumpserver password: "u4bWW0RTZMFeqVPGI315" database: jumpserver
externalRedis: host: jms-redis port: 6379 password: "62rnrIY03ilA8TZF3vI3"
core: config: secretKey: "E4TbGLMRiSLSORtZpDaOeAFcZE4oppgKcsx1EZb55l169AY9WV" bootstrapToken: "E0BQP33Vm6GQ2NNpwf037R1i" log: level: ERROR env: SESSION_EXPIRE_AT_BROWSER_CLOSE: true DOMAINS: "jms.qx.lab:443" persistence: storageClassName: nfs-client accessModes: - ReadWriteMany size: 10Gi
koko: service: type: ClusterIP web: port: 5000 ssh: port: 2222 persistence: storageClassName: nfs-client accessModes: - ReadWriteMany size: 10Gi
lion: persistence: storageClassName: nfs-client accessModes: - ReadWriteMany size: 10Gi
chen: persistence: storageClassName: nfs-client accessModes: - ReadWriteMany size: 5Gi
web: persistence: storageClassName: nfs-client accessModes: - ReadWriteMany size: 1Gi
xpack: enabled: false
|
- 安装
1
| helm install jms jumpserver/jumpserver -n jumpserver -f values.yaml
|
- 验证
1
| kubectl -n jumpserver get pods -w
|
二、安装【法二】
2026年8月27日补充,第二次部署,集群里没有 gitlab,数据库、redis 都放到了集群外.
2.1 更新 traefik
- 复制配置文件
1
| cp traefik-values.yaml traefik-values-with-ssh.yaml
|
- 编辑配置文件
1
| vim traefik-values-with-ssh.yaml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
ingressClass: enabled: true isDefaultClass: true
api: dashboard: true
ingressRoute: dashboard: enabled: false
ports: ssh: port: 2222 exposedPort: 22 protocol: TCP expose: default: true
|
- 更新 traefik
1 2
| helm upgrade traefik traefik/traefik \ -n traefik --version 41.3.0 -f traefik-values-with-ssh.yaml
|
- 验证
22 端口
1
| kubectl get svc -n traefik traefik -o wide
|
2.2 创建数据库
- 创建用户,限制连接数,创建数据库
1 2 3 4 5 6 7 8
| CREATE ROLE jumpserver WITH LOGIN PASSWORD 'jq3lW54MgXQFl7MXOkoY';
ALTER ROLE jumpserver CONNECTION LIMIT 20;
CREATE DATABASE jumpserver OWNER = jumpserver ENCODING = 'UTF8' TEMPLATE = template0;
|
- 数据库层面
pg_hba.conf 放行
1
| host jumpserver jumpserver 10.244.0.0/16 scram-sha-256
|
- 验证 pgsql
1
| kubectl run pgtest --rm -it --image=harbor.qx.lab/dockerhub/library/postgres:17 --restart=Never -- psql "postgresql://jumpserver:jq3lW54MgXQFl7MXOkoY@192.168.10.1:5432/jumpserver" -c '\conninfo'
|
- 验证 redis
1 2
| kubectl run redistest --rm -it --image=harbor.qx.lab/dockerhub/library/redis:7 --restart=Never -- \ redis-cli -h 192.168.10.1 -a '123456' ping
|
2.3 准备 secrets
这里的 charts 不支持使用密钥。
- 创建命名空间
1
| kubectl create ns jumpserver
|
- 创建 secrets
1 2 3 4 5
| kubectl create secret generic jms-secret -n jumpserver \ --from-literal=db-password='jq3lW54MgXQFl7MXOkoY' \ --from-literal=redis-password='123456' \ --from-literal=secret-key="$(openssl rand -hex 32)" \ --from-literal=bootstrap-token="$(openssl rand -hex 16)"
|
2.4 查看 helm
- 添加仓库,查看仓库
1 2 3
| helm repo add jumpserver https://jumpserver.github.io/helm-charts helm repo update helm search repo jumpserver --versions | head
|
- 查看字段
1
| helm show values jumpserver/jumpserver --version v4.10.19 > values-ref.yaml
|
- 筛选数据库相关的字段
1
| grep -nE 'external|postgres|redis|Database|persistence' values-ref.yaml
|
2.5 安装
- 设置字段
1
| vim jumpserver-values.yaml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| postgresql: enabled: false redis: enabled: false
externalDatabase: engine: postgresql host: 192.168.10.1 port: 5432 user: jumpserver password: "jq3lW54MgXQFl7MXOkoY" database: jumpserver
externalRedis: host: 192.168.10.1 port: 6379 password: "123456"
core: config: secretKey: "bedfe1ca79f5e1daf62c14ff6554443730a117edacc94f95760baa1a3b6eab82" bootstrapToken: "a6e6f1f55313b8dd77f19be7b1dc49b5" persistence: storageClassName: nfs-client
koko: persistence: storageClassName: nfs-client
lion: persistence: storageClassName: nfs-client
chen: persistence: storageClassName: nfs-client
web: persistence: storageClassName: nfs-client
ingress: enabled: false
|
- 渲染检查
1 2
| helm template jumpserver jumpserver/jumpserver \ -n jumpserver -f jumpserver-values.yaml | grep -A2 'DB_HOST\|REDIS_HOST'
|
- 安装
1 2
| helm install jumpserver jumpserver/jumpserver \ -n jumpserver --version v4.10.19 -f jumpserver-values.yaml
|
- 验证
1
| kubectl get pods -n jumpserver -w
|
2.6 添加域名访问、证书、ssh
- 查看 svc
1
| kubectl get svc -n jumpserver
|
- 添加路由,需要和 svc 的信息保持一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: jumpserver namespace: jumpserver annotations: cert-manager.io/cluster-issuer: qx.lab-ca-issuer traefik.ingress.kubernetes.io/router.entrypoints: websecure spec: ingressClassName: traefik tls: - hosts: [jms.qx.lab] secretName: jumpserver-tls rules: - host: jms.qx.lab http: paths: - path: / pathType: Prefix backend: service: name: jumpserver-jms-web port: number: 80 --- apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: jumpserver-ssh namespace: jumpserver spec: entryPoints: [ssh] routes: - match: HostSNI(`*`) services: - name: jumpserver-jms-koko port: 2222
|
- 创建资源并验证
1 2
| kubectl apply -f jms-routes.yaml kubectl get certificate -n jumpserver
|
三、验证
- 浏览器访问验证
1 2 3
| 地址: https://jms.qx.lab 用户名: admin 密码: ChangeMe
|
- ssh验证
1
| ssh -p 2222 admin@jms.qx.lab
|