我正在努力获得一个现有的应用程序,该应用程序由在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}}
在作为我的Swarm服务一部分的每个容器中,这将把env var 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
唉,容器的名称是 a)相当冗长 b)随机(即缩小和缩小不会重复使用名称), 例如名为foo-deployment的部署的pod将命名为
FOO部署-64db944b84-bwrxx
FOO部署-64db944b84-5jf7c
等。 据我了解,K8s保证最后五个字符在部署的所有活动pod中都是唯一的,但在向上和向下扩展时它们不会被重用(尽管罕见的碰撞)。
是否存在与Swarm的“slot”概念相对应的机制?
此致 PalatinateJ
答案 0 :(得分:0)
11个月后,但这是解决方法:
要在K8S中获得稳定的容器(pod)名称,您必须 使用StatefulSet
。 StatefulSets
是为必须维护状态的应用程序设计的,但是,如果您不使用K8S卷作为状态(将它们保持短暂状态),则可以毫无问题地使用StatefulSets
。将您的Deployment
转换为StatefulSet
的过程很简单:
apiVersion:
更改为apps/v1
kind:
更改为StatefulSet
spec:
下添加selector:
标签。该标签将包含您用于选择适当服务的所有内容。 此外,您必须确保spec:template:metadata:labels
下的所有项目都与spec:selector:matchLabels
下的所有项目相匹配(在提供的示例中,这样做会更合理)strategy
中称为Deployment
,请将其更改为updateStrategy
。供以后参考,如果不进行更新,则最终会同时部署StatefulSet
和ReplicaSet
,因为K8S试图填充strategy
和{{1} } 要求。 应用这些更改后,将部署StatefulSet
。我们如何从中获得任务空档?主机名。
由于K8S保持稳定的Pod名称,因此您将使用以下名称:
StatefulSet
在运行pod/mypod-0 1/1 Running 0 10m
pod/mypod-1 1/1 Running 0 9m
时。之后,只需从广告连播名称中解析数字即可。
以下是kubetctl
的YAML:
StatefulSet
差异在等效的apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myStatefulSetName
labels:
app: SomeLabel1
label2: SomeLabel2
spec:
replicas: 100
selector:
matchLabels:
app: SomeLabel1
label2: SomeLabel2
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: SomeLabel1
label2: SomeLabel2
spec:
containers:
- name: myPodName
image: myPod:latest
imagePullPolicy: Always
ports:
- name: myPodPort
containerPort: 8080
上显而易见:
Deployment