Skip to main content

使用 Kubernetes 进行部署

KubernetesBackstage 就是为适应这种模式而设计的,它作为无状态应用程序与外部 PostgreSQL 数据库一起运行。

Kubernetes 集群有许多不同的工具和模式,因此部署到现有 Kubernetes 设置的最佳方法是_同样的方式部署其他一切。

本指南涵盖在典型集群中启动和运行Backstage所需的基本 Kubernetes 定义。 对象定义可能看起来很熟悉,因为Backstage软件目录还使用实体定义文件的 Kubernetes 对象格式!

本地测试​

要在本地测试这些概念,然后再部署到生产型 Kubernetes 集群,首先要安装kubectl,Kubernetes 命令行工具。

接下来,安装minikube这会在本地计算机上创建一个单节点 Kubernetes 集群:

# Assumes Mac + Homebrew; see the minikube site for other installations
$ brew install minikube
$ minikube start

...
Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default.

现在您可以运行kubectl命令,并将更改应用到 minikube 集群。 您应该可以看到kube-systemKubernetes pods 正在运行:

$ kubectl get pods -A

完成教程后,使用minikube stop以停止群集并release资源。

创建命名空间​

Kubernetes 中的部署通常分配给自己的命名空间以隔离多租户环境中的服务。

可以通过以下方式实现kubectl直接:

$ kubectl create namespace backstage
namespace/backstage created

或者,创建并应用名称空间定义:

# kubernetes/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: backstage
$ kubectl apply -f kubernetes/namespace.yaml
namespace/backstage created

创建 PostgreSQL 数据库​

生产中的 Backstage 使用 PostgreSQL 作为数据库。 为了将数据库与 Backstage 应用程序部署隔离,我们可以为 PostgreSQL 创建一个单独的 Kubernetes 部署。

创建 PostgreSQL Secret​

首先,为 PostgreSQL 用户名和密码创建一个 Kubernetes Secret。 PostgreSQL 数据库和 Backstage 部署都将使用这个Secret:

# kubernetes/postgres-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: postgres-secrets
namespace: backstage
type: Opaque
data:
POSTGRES_USER: YmFja3N0YWdl
POSTGRES_PASSWORD: aHVudGVyMg==

Kubernetes Secret中的数据是 base64 编码的。 这些值可以在命令行中生成:

$ echo -n "backstage" | base64
YmFja3N0YWdl

注意:Secret是基于 64 编码的,但未加密。 请务必为集群启用 > Encryption at Rest >。若要在 Git 中存储Secret,请考虑 > SealedSecrets 或其他解决方案。

现在可以将Secret应用到 Kubernetes 集群:

$ kubectl apply -f kubernetes/postgres-secrets.yaml
secret/postgres-secrets created

创建 PostgreSQL 持久卷​

PostgreSQL 需要一个持久卷来存储数据;我们将创建一个持久卷和一个PersistentVolumeClaim在这种情况下,我们索要的是整个卷,但也可以只索要一个卷的一部分。

# kubernetes/postgres-storage.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-storage
namespace: backstage
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 2G
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: '/mnt/data'
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-storage-claim
namespace: backstage
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2G

该文件包含两种不同类型的定义,以一行三破折号隔开。 如果想将相关的 Kubernetes 定义合并到一个文件中并同时应用,该语法很有帮助。

注意音量type: local这将使用 Kubernetes 节点上的本地磁盘创建一个卷。 在生产场景中,您更可能希望使用更高可用性的类型的 PersistentVolume.

将存储卷和声明应用到 Kubernetes 集群:

$ kubectl apply -f kubernetes/postgres-storage.yaml
persistentvolume/postgres-storage created
persistentvolumeclaim/postgres-storage-claim created

创建 PostgreSQL 部署​

现在,我们可以为 PostgreSQL 数据库部署本身创建 Kubernetes 部署描述符:

# kubernetes/postgres.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: backstage
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:13.2-alpine
imagePullPolicy: 'IfNotPresent'
ports:
- containerPort: 5432
envFrom:
- secretRef:
name: postgres-secrets
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgresdb
volumes:
- name: postgresdb
persistentVolumeClaim:
claimName: postgres-storage-claim

如果您不熟悉 Kubernetes,这将是一个很大的挑战。 我们正在描述一个部署(应用程序的一个或多个实例),我们希望 Kubernetes 在metadata块。

spec块描述了所需的状态。 在这里,我们请求 Kubernetes 创建 1 个副本(PostgreSQL 的运行实例),并使用给定的 pod 创建副本template该模板同样包含 Kubernetes 元数据和所需的状态。 模板spec显示了一个容器,由已出版postgres:13.2-alpinedocker 映像。

注意envFrom和secretRef- 我们还引用了为部署而创建的卷,并给出了 PostgreSQL 期望的挂载路径。

将 PostgreSQL 部署应用到 Kubernetes 集群:

$ kubectl apply -f kubernetes/postgres.yaml
deployment.apps/postgres created

$ kubectl get pods --namespace=backstage
NAME READY STATUS RESTARTS AGE
postgres-56c86b8bbc-66pt2 1/1 Running 0 21s

连接 pod 验证部署:

$ kubectl exec -it --namespace=backstage postgres-56c86b8bbc-66pt2 -- /bin/bash
bash-5.1# psql -U $POSTGRES_USER
psql (13.2)
backstage=# \q
bash-5.1# exit

创建 PostgreSQL 服务​

数据库 pod 正在运行,但另一个 pod 如何与其连接?

Kubernetes pod 是瞬时的,它们可以停止、重启或动态创建。 因此,我们不想直接连接 pod,而是创建一个 Kubernetes 服务。 服务会跟踪 pod 并将流量引导到正确的地方。

数据库的最后一步是创建服务描述符:

# kubernetes/postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: backstage
spec:
selector:
app: postgres
ports:
- port: 5432

将服务应用到 Kubernetes 集群:

$ kubectl apply -f kubernetes/postgres-service.yaml
service/postgres created

$ kubectl get services --namespace=backstage
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
postgres ClusterIP 10.96.5.103 <none> 5432/TCP 29s

创建Backstage实例​

既然 PostgreSQL 已经启动并准备好存储数据,我们就可以创建 Backstage 实例了。 步骤与 PostgreSQL 部署类似。

创建BackstageSecret​

对于授权令牌等任何Backstage配置Secret,我们可以像创建 Kubernetes Secret 一样创建一个类似的 Kubernetes Secret用于 PostgreSQL记住要对值进行 base64 编码:

# kubernetes/backstage-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: backstage-secrets
namespace: backstage
type: Opaque
data:
GITHUB_TOKEN: VG9rZW5Ub2tlblRva2VuVG9rZW5NYWxrb3ZpY2hUb2tlbg==

将Secret应用到 Kubernetes 集群:

$ kubectl apply -f kubernetes/backstage-secrets.yaml
secret/backstage-secrets created

创建Backstage部署​

要创建Backstage部署,首先创建一个docker 映像我们将使用该镜像创建 Kubernetes 部署。 在本例中,我们将使用标准主机构建,捆绑前端并由后端提供服务。

首先,创建 Kubernetes 部署描述符:

# kubernetes/backstage.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
namespace: backstage
spec:
replicas: 1
selector:
matchLabels:
app: backstage
template:
metadata:
labels:
app: backstage
spec:
containers:
- name: backstage
image: backstage:1.0.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 7007
envFrom:
- secretRef:
name: postgres-secrets
- secretRef:
name: backstage-secrets
# Uncomment if health checks are enabled in your app:
# https://backstage.io/docs/plugins/observability#health-checks
# readinessProbe:
# httpGet:
# port: 7007
# path: /healthcheck
# livenessProbe:
# httpGet:
# port: 7007
# path: /healthcheck

对于生产部署,image引用通常是容器注册表(例如 AWS 上的 ECR)上一个存储库的完整 URL。

用于本地测试minikube,可以将本地 Docker 守护进程指向minikube内部 Docker 注册表,然后重建镜像进行安装:

$ eval $(minikube docker-env)
$ yarn build-image --tag backstage:1.0.0

访问 PostgreSQL 服务无需特殊布线。 由于它运行在同一个集群上,Kubernetes 会注入POSTGRES_SERVICE_HOST和POSTGRES_SERVICE_PORT这些环境变量可以在Backstage容器中使用。app-config.yaml以及Secret:

backend:
database:
client: pg
connection:
host: ${POSTGRES_SERVICE_HOST}
port: ${POSTGRES_SERVICE_PORT}
user: ${POSTGRES_USER}
password: ${POSTGRES_PASSWORD}

确保在应用后重建 Docker 映像app-config.yaml变化。

将此部署应用到 Kubernetes 集群:

$ kubectl apply -f kubernetes/backstage.yaml
deployment.apps/backstage created

$ kubectl get deployments --namespace=backstage
NAME READY UP-TO-DATE AVAILABLE AGE
backstage 1/1 1 1 1m
postgres 1/1 1 1 10m

$ kubectl get pods --namespace=backstage
NAME READY STATUS RESTARTS AGE
backstage-54bfcd6476-n2jkm 1/1 Running 0 58s
postgres-56c86b8bbc-66pt2 1/1 Running 0 9m

如果遇到任何问题,请查看 pod 中的容器日志:

# -f to tail, <pod> -c <container>
$ kubectl logs --namespace=backstage -f backstage-54bfcd6476-n2jkm -c backstage

创建Backstage服务​

就像PostgreSQL 服务以上,我们需要为 Backstage 创建一个 Kubernetes 服务,以处理将请求连接到正确 pod 的操作。

创建 Kubernetes 服务描述符:

# kubernetes/backstage-service.yaml
apiVersion: v1
kind: Service
metadata:
name: backstage
namespace: backstage
spec:
selector:
app: backstage
ports:
- name: http
port: 80
targetPort: http

selector这里是告诉服务以哪些 pod 为目标,而端口映射则是将正常 HTTP 端口 80 转换为 pod 的后端 http 端口(7007)。

将此服务应用到 Kubernetes 集群:

$ kubectl apply -f kubernetes/backstage-service.yaml
service/backstage created

现在,我们有了可全面运作的 Backstage 部署! 🎉 For a大揭秘您可以将本地端口转发给服务:

$ sudo kubectl port-forward --namespace=backstage svc/backstage 80:80
Forwarding from 127.0.0.1:80 -> 7007

显示端口 7007,因为port-forward没有真的支持服务,所以它会通过查找第一个 pod 的服务并连接到映射的 pod 端口来作弊。

请注意app.baseUrl和backend.baseUrl在你的app-config.yaml应与我们在此转发的内容相匹配(本例中省略了端口,因为我们使用的是默认 HTTP 端口 80):

# app-config.yaml
app:
baseUrl: http://localhost

organization:
name: Spotify

backend:
baseUrl: http://localhost
listen:
port: 7007
cors:
origin: http://localhost

如果您使用的是认证提供者要使验证弹出窗口正常工作,也应配置此地址。

现在,您可以在机器上打开浏览器,以本地主机并浏览 Kubernetes 部署的 Backstage 实例。

进一步的步骤​

这是在 Kubernetes 上全面部署 Backstage 的大部分步骤,可能还需要一些额外的步骤,超出了本文档的范围。

设置更可靠的音量​

PersistentVolume上述配置使用localKubernetes 节点存储。 应将其替换为云卷、网络连接存储或 Kubernetes 节点之外更持久的存储。

公开Backstage服务​

Kubernetes 服务不对群集外的外部连接开放。 通常是通过 Kubernetes侵入或外部负载平衡器.

更新部署映像​

要将 Kubernetes 部署更新为新发布版本的 docker 映像,请更新以下内容中的映像标记引用backstage.yaml然后使用kubectl apply -f kubernetes/backstage.yaml.

在生产过程中,该镜像标签通常是一个完整的 URL,指向托管已构建 Docker 镜像的容器注册中心。 该注册中心可以托管在基础架构内部,也可以是云提供商提供的托管注册中心。