我在由 Raspberry 4 和 Raspberry 5 节点混合组成的集群服务器上运行 K3S Kubernetes。
我想在集群服务器上安装Unifi 网络应用程序,并且已经通过使用 Ansible进行了相当深入的配置MetalLB
。Longhorn
Cert-Manager
我正在使用linuxserver.io 的Docker 映像作为我的集群服务器,它要求我安装一个包含的单独 pod MongoDB
。
在线搜索如何安装 MongoDB 给了我以下 Ansible 文件:
- name: Generate MongoDB secrets
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
namespace: default
type: Opaque
data:
password: VmVyeVNlY3JldFBhc3NvcmQ= # "VerySecretPassword" encoded in Base64
- name: Create Unifi DB init script
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-init-script
namespace: default
data:
init-script.js: |-
db.getSiblingDB("unifi-db").createUser({user: "unifi", pwd: "unifi", roles: [{role: "dbOwner", db: "unifi-db"}]});
db.getSiblingDB("unifi-db_stat").createUser({user: "unifi", pwd: "unifi", roles: [{role: "dbOwner", db: "unifi-db_stat"}]});
- name: Create MongoDB service
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: mongodb-svc
namespace: default
labels:
app: mongodb
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 27017
targetPort: 27017
selector:
app: mongodb
- name: Create MongoDB statefull set
kubernetes.core.k8s:
state: present
definition:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
namespace: default
labels:
app: mongodb
spec:
serviceName: mongodb-svc
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo:4.4.18 # Do NOT set it to 'latest'. I'll explain below.
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
value: admin
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: password
volumeMounts:
- name: mongodb-data
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: mongodb-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
- name: Initialize MongoDB
kubernetes.core.k8s:
state: present
definition:
apiVersion: batch/v1
kind: Job
metadata:
name: mongodb-init-job
namespace: default
spec:
template:
metadata:
name: mongodb-init-pod
spec:
restartPolicy: OnFailure
containers:
- name: mongodb-init-container
image: mongo:4.4.18 # Again: Do NOT set it to 'latest'.
command: [ "mongo", "--host", "mongodb-0.mongodb-svc.default.svc.cluster.local", "--authenticationDatabase", "admin", "--username", "admin", "--password", "$(MONGO_INITDB_ROOT_PASSWORD)", "/mongo-init-script/init-script.js" ]
env:
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: password
volumeMounts:
- name: mongo-init-script
mountPath: /mongo-init-script
volumes:
- name: mongo-init-script
configMap:
name: mongodb-init-script
该部分运行良好。
输出kubectl logs mongodb-init-job-f5f54
如下:
MongoDB shell version v4.4.18
connecting to: mongodb://mongodb-0.mongodb-svc.default.svc.cluster.local:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("39ad2f51-07a9-4e67-8c5b-68f6fff92872") }
MongoDB server version: 4.4.18
Successfully added user: {
"user" : "unifi",
"roles" : [
{
"role" : "dbOwner",
"db" : "unifi-db"
}
]
}
Successfully added user: {
"user" : "unifi",
"roles" : [
{
"role" : "dbOwner",
"db" : "unifi-db_stat"
}
]
}
这意味着我可以以admin
MongoDB 用户身份登录并创建具有数据库访问权限的unifi
密码。unifi
unifi-db
我还知道可以通过将数据库主机设置为mongodb-0.mongodb-svc.default.svc.cluster.local
使用端口来通过 DNS 访问它27017
。
我选择安装 MongoDB 4.4.18 版本的原因是,尽管 Unifi 网络应用程序支持高达 7.0 版本,但 MongoDB 对 Raspberry Pi 板的支持情况并不相同。
MongoDB 只能在 Raspberry Pi 上运行到 4.4.18 版本。
接下来是让我的集群服务器上运行 Unifi 网络应用程序。
我正在使用以下任务来执行此操作:
---
- name: Define storage space for Unifi
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: unifi-cluster-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 5Gi
- name: Add unifi deployment
kubernetes.core.k8s:
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: unifi
namespace: default
labels:
app: unifi
spec:
replicas: 1
selector:
matchLabels:
app: unifi
template:
metadata:
labels:
app: unifi
spec:
volumes:
- name: unifi-config
persistentVolumeClaim:
claimName: unifi-cluster-pvc
containers:
- name: unifi
image: lscr.io/linuxserver/unifi-network-application:latest
ports:
- containerPort: 3478
protocol: UDP
- containerPort: 10001
protocol: UDP
- containerPort: 5514
protocol: UDP
- containerPort: 8080
- containerPort: 8443
- containerPort: 8843
- containerPort: 8880
- containerPort: 6789
volumeMounts:
- name: unifi-config
mountPath: /config
env:
- name: PUID
value: "1000"
- name: GUID
value: "1000"
- name: MONGO_USER
value: "unifi"
- name: MONGO_PASS
value: "unifi"
- name: MONGO_HOST
value: "mongodb-0.mongodb-svc.default.svc.cluster.local"
- name: MONGO_PORT
value: "27017"
- name: MONGO_DBNAME
value: "unifi-db"
- name: MONGO_TLS
value: "false"
- name: Define unifi service ports
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: unifi
namespace: default
spec:
type: LoadBalancer
selector:
app: unifi
ports:
- name: "8080"
port: 8080
targetPort: 8080
- name: "8443"
port: 8443
targetPort: 8443
- name: "8843"
port: 8843
targetPort: 8843
- name: "8880"
port: 8880
targetPort: 8880
- name: "6789"
port: 6789
targetPort: 6789
- name: "3478"
port: 3478
protocol: UDP
targetPort: 3478
- name: "10001"
port: 10001
protocol: UDP
targetPort: 10001
- name: "5514"
port: 5514
protocol: UDP
targetPort: 5514
- name: Add unifi ingress
kubernetes.core.k8s:
state: present
definition:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: unifi
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
cert-manager.io/cluster-issuer: letsencrypt-staging
cert-manager.io/acme-challenge-type: dns01
spec:
ingressClassName: nginx
tls:
- hosts:
- unifi.example.com
secretName: unifi-tls
rules:
- host: 'unifi.example.com'
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: unifi
port:
number: 8443
运行该命令kubectl get pods
得到以下输出:
NAME READY STATUS RESTARTS AGE
mongodb-0 1/1 Running 0 64m
unifi-5dcdbfb6d9-8wbbp 1/1 Running 0 64m
mongodb-init-job-f5f54 0/1 Completed 2 64m
unifi-db
我可以使用以下命令登录数据库:kubectl exec mongodb-0 -it -- mongo -u unifi -p unifi unifi-db
命令:show collections
除其他外,还给我以下信息:
account
admin
alarm
crashlog
dashboard
device
...
到目前为止,一切都很好。
然而,我无法启动并运行 Unifi 网络应用程序的网站。
该命令的输出kubectl log unifi-5dcdbfb6d9-8wbbp
包括以下消息:
Error creating bean with name 'statDbService'
defined in com.ubnt.service.DatabaseSpringContext:
Command failed with error 13 (Unauthorized): 'not
authorized on unifi-db_stat to execute command {
listCollections: 1, cursor: {}, nameOnly: true, $db:
"unifi-db_stat", lsid: { id: UUID("99b4d07f-b3f3-49c9-9979-dbdd27445881")
} }' on server mongodb-0.mongodb-svc.default.svc.cluster.local:27017.
The full response is {"ok": 0.0, "errmsg": "not authorized on unifi-db_stat
to execute command { listCollections: 1, cursor: {}, nameOnly: true, $db:
\"unifi-db_stat\", lsid: { id: UUID(\"99b4d07f-b3f3-49c9-9979-dbdd27445881\")
} }", "code": 13, "codeName": "Unauthorized"}
我该如何解决这个问题?
阅读有关 MongoDB 中角色分配工作原理的文档后,我发现将用户的角色设置为dbOwner
基本上是一种全通行证,因为它将readWrite
、dbAdmin
和的角色组合userAdmin
成一个角色。
您获得的权限之一是listCollections
,上面的错误代码中引用了该权限。
那么发生了什么?
嗯...这似乎是一个已知问题。
在网上搜索后,我偶然发现了GitHub 上的这条评论
因此,不要使用如下所示的初始化脚本:
它应该是这样的:
我距离 MongoDB 上的导出还很远,所以我不知道这两个 javascript 之间的微妙之处在哪里。
我修改后的
ConfigMap
调用mongodb-init-script
现在如下所示:在彻底重置我的集群服务器并重新运行我的剧本后,我就能够在浏览器中看到 Unifi 网络应用程序页面。:-)