如何在kubernetes-pet上运行mongodb副本
使用Docker容器运行和管理有状态的应用程序或数据库(例如MongoDB,Redis和MySQL)并非易事。
有状态的应用程序必须在容器已关闭或迁移到新节点后保留其数据(例如,如果在故障转移或扩展操作期间,该容器已关闭并在新主机上重新创建)。
默认情况下,Docker容器将其根磁盘用作临时存储,这是运行该容器的主机文件系统中的磁盘空间的一部分。
该磁盘空间无法与其他进程共享,也无法轻松迁移到新主机。
当你
能够
使用“ Docker commit”
命令(将创建一个新的Docker映像,其中将包含您修改的数据)保存在容器中所做的更改,它不能用作存储内容的实际方法。
另一方面,“ Docker卷”功能使您可以运行安装了专用卷的容器。
该卷包含来自主机的另一块空间(但这一次是持久的,并且独立于容器生命周期;在删除容器后不会删除),网络存储或共享文件系统挂载,具体取决于您使用的存储插件。
对于生产级的容器化状态应用程序管理,您可以利用诸如“ flocker”和“ convoy”之类的工具。
”为避免为集群中的每个Docker主机手动配置它们,您可以使用Kubernetes“持久卷”,该抽象抽象底层存储层-AWS EBS卷,GCE持久磁盘,Azure磁盘,Ceph,OpenStack Cinder或其他 支持的系统。
在本教程中,我们将说明如何运行MongoDB 3的容器化副本集。
2个数据库,使用Kubernetes 1。
5,并利用StatefulSet功能(以前称为PetSet)。
StatefulSet功能将持久性DNS名称分配给Pod,并允许我们随时将所需的存储卷重新附加到Pod迁移到的另一台计算机上。
注意
:要继续学习本教程,需要具备Kubernetes基础知识和术语(例如Pod,配置映射和服务)的能力。
StatefulSet功能与专用的“服务”一起使用,该服务指向其每个成员吊舱。
此服务应为“无头”服务,这意味着它不会为负载平衡创建ClusterIP,而是用于将要启动的Pod的静态DNS命名。
该服务名称将在StatefulSet配置文件的“ spec:serviceName:”部分中引用。
它将导致以以下格式创建枚举DNS记录:“名称0”,“名称1”,“名称2”等。
幸运的是,Kubernetes服务发现允许任何Pod只需查询服务名称即可访问同一名称空间中的服务。
如果启动了pod并检测到其自己的主机名为“ mongodb-4”,它将确定知道要在哪里查找主机,即“ mongodb-0”。
”
在StatefulSet中,Pod严格地一个接一个地启动。
只有前一个Pod成功初始化后,才会启动下一个Pod。
这样,您可以放心地计划Pod的部署,“ name-0”是第一个启动的Pod。
“名称-0”将引导群集,副本集等。
,具体取决于您运行的应用程序。
在MongoDB中,主节点将初始化副本集。
然后,命名为“ name-1”,“ name-2”等的Pod。
将认识到已经创建了“副本集”并将其连接到现有节点的事实。
值得注意的是,在部署Consul,MongoDB,Redis等应用程序时,可能很难知道哪个是当前的主节点。
这是因为这些应用程序不仅在故障转移期间而且(例如)即使在“ rs.f”之后也定期重新选择主节点/主节点。
add(hostname)”(将新成员添加到副本集的MongoDB shell命令),则下一个启动的pod成员不能确定“ mongodb-0”仍然是主要成员。
到“ mongodb-4”窗格启动时,由于内部重新选举,任何先前的节点可能已经是新的主节点。
以上所有内容应有助于我们了解以下示例bash init脚本中发生的情况。
我们将以舵图(Kubernetes软件包)为例,该示例部署具有三个MongoDB副本集成员的StatefulSet。
要安装helm软件包管理器及其服务器端组件Tiller,请遵循此官方安装指南。
If you’d prefer to skip reading the guide, just run this on the same machine where you have kubectl properly configured (helm uses kubectl configuration to connect to Kubernetes cluster):
The first step is to download and install helm. Next, install Tiller in your cluster (helm knows where to install, from the file, and can access Kubernetes API like kubectl using this config file).
If both steps are completed successfully, you will be presented with the message: “Tiller” (the helm server-side component) has been installed into your Kubernetes Cluster.” We can then proceed to the installation steps of MongoDB cluster.
At the time of writing, MongoDB StatefulSet helm chart is located in the “incubator” repository, meaning it hasn’t yet been released to “stable” repo. We’ll use this chart as an example to understand how StatefulSet works, and how we can modify it to fit our needs or later run any type of database using the same techniques.
Check which packages are visible to you with “helm search” command, notice you can see only “stable/something” packages. Enable “incubator” helm charts repository:
You will see “incubator has been added to your repositories,” and by running “helm search” again, verify you see new “incubator/something” packages.
If want to change default values provided with this package, download the file or simply copy its content and replace any values, like Storage: “10Gi,” Memory: “512Mi,” or Replicas: 3.
Then, during install, command point to your modified file with .
Now you are ready to launch MongoDB replica set with this command:
(If you have modified default values).
After a few seconds, refer to your Kubernetes dashboard; you should see the following resources created:
StatefulSet named .
“Persistent Volume Claims” and three volumes:
Next, refer to your again. It should be lit green now because all three pods are initialized.
AWS notice: If you are running on AWS, the default Kubernetes 1.5 StorageClass will provision EBS volumes in different availability zones. You will see an error such as “pod (mymongo-mongodb-re-0) failed to fit in any node fit failure summary on nodes : NoVolumeZoneConflict (2), PodToleratesNodeTaints (1)”.
If this happens, delete the EBS volumes in “wrong” AZs and create a constrained to a particular availability zone, where your cluster has its worker nodes, using the following example. Create a file named with content:
Submit this to Kubernetes with , and you should see response of “storageclass generic created.”
Now persistent volume claims will dynamically create PVs in only (replace in this file with the AZ that fits your cluster setup).
Following this package authors advice, we can find which pod is our primary replica, using this bash command:
Then, look at which pod shows : true and copy its name (this JSON output shows full-service DNS names, so a single pod name is the left part before the first dot).
In my case, it’s still the pod. We can write some value into the pod mongo. Then, execute this command:
If everything is working, you should see . To read this value from any slave pod, execute:
You will see something like this:
Those basic verification steps prove that your replication is working and a value we inserted into the primary node can be fetched from any of the slave replicas.
Also, you can log into the interactive MongoDB shell by executing the following:
This allows you to perform arbitrary actions on the database and you can safely exit the shell without worrying that your container will close on exit (as if you exit the shell after opening it with “Docker attach”).
Let’s have a quick look at the components Helm Chart used to create this MongoDB StatefulSet and persistent volumes for storing data.
A service that doesn’t have a ClusterIP or NodePort specified means it doesn’t attempt to load-balance traffic to underlying pods. Its sole purpose is to trigger DNS names creation for pods.
Please notice the annotation used:
It will cause endpoint creation for a pod, ignoring its 数据库实时同步 state, which is exactly what we need.
Why? Because we use our own initialization mechanism in MongoDB when a pod starts, and each replica set member must be able to reach others during initialization, even if they’re not yet “healthy” (ready to serve requests and traffic).
All extra settings and fine tuning of mongo behavior goes here. This file will be rendered into every pod and used as config file. The file in Helm Chart that we used is very minimalistic and has no special performance tuning or whatever you might need in your production deployment. Feel free to modify it to fit your needs. The simplest method is to git clone the chart’s repository, modify the needed files and definitions, and use “helm package mongodb-replicaset” which will archive your modified “mongodb-replicaset” folder to “.tgz” archive, to use later with “helm install — name your-release-name mongodb-replicaset-0.1.3.tgz”. If you don’t specify — name, you’ll have to live with a random release name helm generates for your set, like “curious-penguin” or the like. You can read more about helm here (highly recommended).
The StatefulSet YAML manifest includes the Persistent Volume Claims template. This is the most complex resource declaration, which has init containers defined in this section:
The two containers named “install” and “bootstrap” are started before the main pod container. The first one, named “Install,” loads a small image which holds special files like “install.sh,” “on-start.sh,” and “peer-finder.” This container does two important things: mounts two of your newly defined volumes (one is “config” which is created from ConfigMap and has only the config file, second is a temporary mount named “work-dir”), and copies needed init files to “work-dir.” You can rebuild that image and put anything else that might be needed for your stateful application. Pay attention, “work-dir” is not yet the persistent volume, it’s just a place for running few init files in your pod during next steps.
The second init container, named “bootstrap,” uses MongoDB 3.2 official image (by the time you read this, it might be any other new version of MongoDB image, but because we do init steps in separate containers, we don’t need to modify real mongo image, we add our extra files using mounts “work-dir” and “config”). It will mount the main persistent volume (which is defined later on, in the section of StatefulSet manifest) to the path. And run “peer-finder,” a simple tool used for fetching other peers endpoints from Kubernetes service API, you can find it here. has the logic that detects whether MongoDB replica set is already initialized by other peers and joins the current pod to a replica set. If it detects no replica set, it will set itself as master and initialize one, so others will join.
Before we can use this in production, the next step is to write more data into our newly created replica set and verify the failover mechanism in case one of our Kubernetes nodes goes down unexpectedly.