传统的观点认为,你不能在容器中运行数据库。"容器是无状态的!"他们说,"数据库没有状态是没有意义的!"
当然,这根本不是真的。在谷歌,一切都在容器中运行,包括数据库。你只是需要合适的工具。Kubernetes 1.5包括新的StatefulSet对象,有了StatefulSets,Kubernetes使得运行数据库等有状态的工作负载变得更加容易。
Headless Service(无头服务)
需要创建一个无头服务。像普通的Kubernetes服务,只是它们不为你做任何负载平衡。当与StatefulSets结合时,它们可以给你唯一的DNS地址,让你直接访问pods 这对于创建MongoDB副本集来说是完美的,因为我们的应用程序需要单独连接到所有的MongoDB节点。
无头服务的配置看起来像这样:
kind: Service
metadata:
name: mongo
labels:
name: mongo
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
role: mongo
clusterIP被设置为“None”。除此之外,它看起来和正常的Kubernetes服务完全一样。
StatefulSet
StatefulSet实际上是运行MongoDB,并将所有东西协调起来。StatefulSet 与 ReplicaSets 在某些方面不同,StatefulSet 更适合于有状态的应用程序,在StatefulSet下创建的pod有一些独特的属性。pod的名字不是随机的,相反,每个pod都有一个顺序的名字。结合无头服务,这使得pod有稳定的识别。此外,pod是一次创建一个,而不是一次全部创建,这在启动一个有状态的系统时可以有所帮助。
跟之前一样,这个"sidecar"容器将自动配置MongoDB副本集。sidecar是一个辅助容器,它帮助主容器完成其工作。
StatefulSet的配置看起来像这样:
kind: StatefulSet
metadata:
name: mongo
spec:
selector:
matchLabels:
role: mongo
environment: test
serviceName: "mongo"
replicas: 3
template:
metadata:
labels:
role: mongo
environment: test
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongo
image: mongo
command:
- mongod
- "--replSet"
- rs0
- "--smallfiles"
- "--noprealloc"
ports:
- containerPort: 27017
volumeMounts:
- name: mongo-persistent-storage
mountPath: /data/db
- name: mongo-sidecar
image: cvallance/mongo-k8s-sidecar
env:
- name: MONGO_SIDECAR_POD_LABELS
value: "role=mongo,environment=test"
volumeClaimTemplates:
- metadata:
name: mongo-persistent-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi
创建yaml
依次创建以上2个yaml:
kubectl apply -f https://www.kubebiz.com/raw/KubeBiz/MongoDB/3.4/StatefulSet.yaml?namespace=default
kubectl apply -f https://www.kubebiz.com/raw/KubeBiz/MongoDB/3.4/headless-service.yaml?namespace=default
查看状态:
kubectl get pods
NAME READY STATUS RESTARTS AGE
mongo-0 2/2 Running 0 3m
mongo-1 2/2 Running 0 3m
mongo-2 2/2 Running 0 3m
全部为Running
。
由无头服务支持的StatefulSet中的每个pod将有一个稳定的DNS名称。遵循这种格式:<pod-name>.<service-name>
。
这意味着MongoDB副本的DNS名称是:
mongo-0.mongo
mongo-1.mongo
mongo-2.mongo
在这种情况下,连接字符串URI将是:
mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo:27017/dbname\_?
安装完成!
相关链接
原文:https://kubernetes.io/blog/2017/01/running-mongodb-on-kubernetes-with-statefulsets/
版本:https://hub.docker.com/_/mongo
yaml文件:https://www.kubebiz.com/KubeBiz/MongoDB