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 映像。

注意envFromsecretRef- 我们还引用了为部署而创建的卷,并给出了 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_HOSTPOSTGRES_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.baseUrlbackend.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 镜像的容器注册中心。 该注册中心可以托管在基础架构内部,也可以是云提供商提供的托管注册中心。