#kubernetes #backend #kubernetes-ingress #multi-tenant
Вопрос:
Я пытаюсь понять, как развернуть многопользовательский кластер в Kubernetes, где у меня было бы несколько баз данных, к которым можно получить доступ, определив несколько входных ресурсов, например, по поддомену foo.domain.com, bar.domain.com и т.д.
Там будет модуль интерфейса и модуль бэкенда.
В настоящее время у нас есть кластер с одним арендатором, в котором каждый клиент имеет свои собственные интерфейсные и серверные модули (foo.domain.com и api.foo.domain.com), и мы пытаемся перейти на многопользовательскую архитектуру, где нам не придется управлять таким количеством отдельных модулей, чтобы снизить затраты и повысить эффективность развертывания обновлений. Пожалуйста, любая информация о том, как я должен подойти к этому, была бы признательна.
Это пример того, как мое развертывание.yml выглядит так:
let deploymentManifest = {
kind: "Deployment",
metadata: {
name: "deployment_" business_name
},
spec: {
replicas: 1,
selector: {
matchLabels: {
app: "store_" business_name
}
},
template: {
metadata: {
labels: {
app: "store_" business_name
}
},
spec: {
containers: [{
name: "mysql-" business_name,
image: "mysql",
env: [{
name: "MYSQL_ROOT_PASSWORD",
value: "12345678"
},
{
name: "MYSQL_DATABASE",
value: "store_db"
}
],
ports: [{
containerPort: 3306,
name: "mysql"
}],
imagePullPolicy: "Always",
volumeMounts: [{
name: "mysql-persistent-storage",
mountPath: "/var/lib/mysql"
}]
},
{
name: "backend_" business_name,
image: "app/app.backend",
ports: [{
containerPort: 3000,
targetPort: 3000
}],
imagePullPolicy: "Always",
env: [{
name: "PASSWORD_MYSQL",
value: "12345678"
},
{
name: "PORT_MYSQL",
value: "3306"
},
{
name: "USER_MYSQL",
value: "root"
},
{
name: "DB_MYSQL_URI",
value: "localhost"
},
{
name: "DB_MYSQL",
value: "store_db"
},
{
name: "PORT",
value: "3000"
},
{
name: "LOG_LEVEL",
value: "debug"
},
{
name: "JWT_SECRET",
value: "_"
}
]
},
{
name: "front_" business_name,
image: "app/app.frontend",
ports: [{
containerPort: 80,
targetPort: 4200
}],
imagePullPolicy: "Always",
env: [{
name: "Url",
value: "store_service_" business_name
}],
},
{
name: "mongodb-standalone-" business_name,
image: "mongo",
imagePullPolicy: "",
volumeMounts: [{
name: "mongo-persistent-storage",
mountPath: "/data/db"
}]
}
],
volumes: [{
name: "mysql-persistent-storage",
persistentVolumeClaim: {
claimName: "mysql-pv-claim-" business_name
}
},
{
name: "mongo-persistent-storage",
persistentVolumeClaim: {
claimName: "mongo-pv-claim-" business_name
}
}
]
}
}
}
}
let serviceManifest = {
metadata: {
name: "store_service_" business_name,
labels: {
app: "store_service_" business_name
}
},
spec: {
type: "ClusterIP",
ports: [{
name: "backend_" business_name,
protocol: "TCP",
port: 3000,
targetPort: 3000
},
{
name: "front_" business_name,
protocol: "TCP",
port: 80,
targetPort: 80
}
],
selector: {
app: "store_" business_name
}
}
};
let ingressManifest = {
"metadata": {
"name": business_name "-ingress",
"annotations": {
"cert-manager.io/cluster-issuer": "letsencrypt-prod",
"nginx.ingress.kubernetes.io/proxy-body-size": "50m",
"nginx.ingress.kubernetes.io/from-to-www-redirect": "true"
}
},
"spec": {
"tls": [{
"hosts": [
subdomain ".app.com",
"api." subdomain ".app.com"
],
"secretName": business_name "-secret-tls"
}],
"rules": [{
"host": subdomain ".app.com",
"http": {
"paths": [{
"path": "/",
"backend": {
"serviceName": "store_service_" business_name,
"servicePort": 80
}
}, ]
}
},
{
"host": "api." subdomain ".app.com",
"http": {
"paths": [{
"path": "/",
"backend": {
"serviceName": "app_service_" business_name,
"servicePort": 3000
}
}, ]
}
}
]
}
};
let pvManifest = {
kind: "PersistentVolume",
metadata: {
name: "mysql-pv-volume-" business_name,
labels: {
type: "local"
}
},
spec: {
storageClassName: "manual",
capacity: {
storage: "1Gi"
},
accessModes: [
"ReadWriteOnce"
],
hostPath: {
path: "/data/db/data-" business_name,
}
}
}
let pvManifestMongo = {
kind: "PersistentVolume",
metadata: {
name: "mongo-pv-volume-" business_name,
labels: {
type: "local",
"pv-name": "mongo-pv-volume-" business_name
}
},
spec: {
storageClassName: "manual",
capacity: {
storage: "1Gi"
},
accessModes: [
"ReadWriteOnce"
],
hostPath: {
path: "/mnt/mongo-data-" business_name,
},
persistentVolumeReclaimPolicy: "Retain"
}
}
let pvClaimManifest = {
kind: "PersistentVolumeClaim",
metadata: {
name: "mysql-pv-claim-" business_name
},
spec: {
storageClassName: "manual",
accessModes: [
"ReadWriteOnce"
],
resources: {
requests: {
storage: "1Gi"
}
}
}
}
let pvClaimManifestMongo = {
kind: "PersistentVolumeClaim",
metadata: {
name: "mongo-pv-claim-" business_name,
},
spec: {
storageClassName: "manual",
accessModes: [
"ReadWriteOnce"
],
resources: {
requests: {
storage: "1Gi"
}
},
selector: {
matchLabels: {
"pv-name": "mongo-pv-volume-" business_name
}
}
}
}
Таким образом, в этом случае у каждого отдельного пользователя, которому требуется программное обеспечение, есть выделенный модуль в узле с бэкэндом, интерфейсом, базой данных MySQL и базой данных mongo. Я изменяю это, чтобы определить том, где каждый пользователь получает свое собственное постоянное требование на том, и есть только 3 внешних и внутренних модуля. Я делаю это, чтобы избежать потребления ресурсов неактивными пользователями, чтобы не было модуля 24/7, работающего с нулевой активностью. Единственная проблема заключается в управлении соединением между одним внутренним сервером и множеством постоянных утверждений тома, определенных в наборе с отслеживанием состояния.
Заранее спасибо за ваше время и надеюсь, что мне удалось объяснить свою проблему. ✌