我正在努力让现有的应用程序由一组运行在 Docker Swarm 和 Kubernetes 上的无状态、可扩展的微服务(当然还有一些作为后端的有状态微服务)组成。更改应用程序的代码基本上是不可能的,因此我必须使我们拥有的一些现有机制(例如服务发现)在 Swarm 和 K8s 环境中工作。
对我使用 Docker Swarm 进行启动和运行有很大帮助的一件事是 Swarm 的“服务创建”命令的模板功能(https://docs.docker.com/engine/reference/commandline/service_create/#create-services -using-templates),我可以在其中做类似的事情
-e my_env_var=foo{{.Task.Slot}}
Run Code Online (Sandbox Code Playgroud)
在属于我的 Swarm 服务的每个容器内,这会将环境变量 my_env_var 设置为 fooX 形式的值,其中“X”是容器的“槽号”。要了解槽号是什么,请考虑具有 N 个实例的服务(即,scale=N)。每个容器占用一个槽位,槽位编号为1到N。
这样,我就可以在我的容器内获得一个 ID,该 ID 在我的服务的所有当前活动容器中是唯一的,但同时,它并不是完全随机的。如果我将服务从 1 扩展到 5,我的服务中的五个容器将获得插槽 1、2、3、4 和 5。如果我将其缩小到 3,则两个容器将被停止(例如,2 和 4,剩下 1、3 和 5)。但如果我再次将其放大到 5,插槽编号(通常)将再次为 1 到 5(即使它们是,例如 2-6,这仍然比完全随机要好)。
事实证明,这对于我的应用程序支持 Swarm 非常有用,我正在拼命寻找 K8s 中类似的东西(特别是在 K8s 部署的上下文中,我将其用于我们的无状态微服务,因为它们似乎是最合适的 K8s)概念)。我发现可以将 pod 名称传递到容器中
env:
- name: metadata_name
valueFrom:
fieldRef:
fieldPath: metadata.name
Run Code Online (Sandbox Code Playgroud)
唉,容器的名称是 a) 相当长 b) 随机的(即,缩小和扩大不会重用名称),例如,名为 foo-deployment 的部署的 pod 将被命名为类似的名称
foo-部署-64db944b84-bwrxx
foo-部署-64db944b84-5jf7c …
我目前正在为多容器应用程序编写 Helm 图表。我们有一堆微服务容器(我们称它们为“应用程序”),它们在通过 K8s 处理的方式上非常相似,并且可以(因此应该)由相同的 Helm 模板处理以避免重复。另一方面,能够为不同的应用程序(例如,资源请求)单独配置某些设置是有意义的。我目前正在做这样的事情:
{{- $applications:= <obtain list of applications> }}
{{ range $app:= $applications }}
apiVersion: apps/v1
kind: StatefulSet
spec:
[...]
spec:
containers:
- name: {{ $app }}
image: {{ $.Values.image.registry }}mycompany/myproduct-{{ $app }}:{{ $.Values.image.version }}
[...]
Run Code Online (Sandbox Code Playgroud)
我现在想要做的是能够设置一些特定于应用程序的值(以 K8s resources.requests.memory 或副本数为例),可以在 values.yaml 中为每个应用程序单独设置,但回退到如果未设置,则为默认值。这个想法是在 values.yaml 中有这样一个部分:
applications:
default:
replicas: 1
resources:
requests:
memory: 512Mi
cpu: 250m
applicationA:
resources:
requests:
memory: 7Gi
applicationB:
resources:
requests:
cpu: 500m
[...]
Run Code Online (Sandbox Code Playgroud)
我的想法是我将“默认”部分中的值用于应用程序,除非在相应应用程序的部分中指定了特定于应用程序的值。在我的示例中,我有一个用于 applicationA 的内存请求的自定义值和一个用于应用程序 B 的 CPU 请求的自定义值,但所有其他值都应来自默认部分。也可能存在根本没有定义应用程序特定设置的应用程序(在这种情况下,所有内容都来自 values.yaml 的默认部分)。“索引”功能似乎允许我做我想做的事情,所以在我的模板中,我尝试了这个(为了可读性而换行):
resources: …Run Code Online (Sandbox Code Playgroud)