有人说:“如果你觉得国庆7天短的话,那么接下来上班的7天你就知道有多长了【二哈】”,今天周一,照列来一波干货来袭,喜欢来收。
2016年9月26日发布Kubernetes 1.4版本,其中包括几项新的功能。一个有趣的是使用扩展的状态的应用支持 Helm Charts。在这篇文章中,我们将使用Kubernetes 1.4的这个新功能部署MongoDB实例来Kubernetes。
他们的博客公告:
策划和预测试Helm Charts普通状态的应用,如MariaDB的,MySQL和詹金斯将可使用头盔包管理器的版本2单命令启动。
请记住,即使Helm只是官方Kubernetes的一部分,但是不要它的话法,将无法正常工作。如果你发现有任何问题,可以在GitHub上创建一个问题来需求解决。
什么是 Helm?
Helm,是Kubernetes的软件包管理器。Charts表示可以安装并组成的预配置Kubernetes资源包。
配置 Helm
Helm采用客户端机服务器模式。服务器部分被称为tiller,同时包括你运行Kubernetes集群。客户端部分被称为helm,安装在本地的开发系统上。
安装客户端Helm
首先我们安装需要的客户端,以便我们能在Kubernetes群集上安装helm。在helm的每个版本中大多数OS是二进制文件。去他们的GitHub库kubernetes 或者Helm,并找到最新版本。在这篇文章撰写时最新的版本是V2.0.0,alpha.4,所以我们将使用该版本。
注意:安装helm的同时请确保你已经把kubectl安装在相同环境下。这将使我们能够从开发环境的群集上安装helm。
运行下面的命令下载并解压二进制文件:
export HELM_OS=linux && wget <span class="hljs-symbol">https:</span>/<span class="hljs-regexp">/github.com/kubernetes</span><span class="hljs-regexp">/helm/releases</span><span class="hljs-regexp">/download/v</span>2.<span class="hljs-number">0</span>.<span class="hljs-number">0</span>-alpha.<span class="hljs-number">4</span>/helm-v2.<span class="hljs-number">0</span>.<span class="hljs-number">0</span>-alpha.<span class="hljs-number">4</span>-$HELM_OS-amd64.tar.gz && tar -zxvf helm-v2.<span class="hljs-number">0</span>.<span class="hljs-number">0</span>-alpha.<span class="hljs-number">4</span>-$HELM_OS-amd64.tar.gz && cd $HELM_OS-amd64
www#gaodaima.com来源gaodai#ma#com搞*!代#%^码网搞代码
将二进制放到有用的地方:
sudo mv linux-amd54/helm /usr/<span class="hljs-built_in">local</span>/bin/helm
验证是否安装正确:
helm <span class="hljs-built_in">help</span>
安装 Helm server
现在,我们已经安装了客户端helm,我们可以用它在我们的Kubernetes群集上安装helm。要安装简单helm运行以下命令:
<code class="hljs sql">$ helm init Creating /home/stackadmin/.helm Creating /home/stackadmin/.helm/repository Creating /home/stackadmin/.helm/repository/<span class="hljs-keyword">cache</span> Creating /home/stackadmin/.helm/repository/<span class="hljs-keyword">local</span> Creating /home/stackadmin/.helm/repository/repositories.yaml Creating /home/stackadmin/.helm/repository/<span class="hljs-keyword">local</span>/<span class="hljs-keyword">index</span>.yaml $HELM_HOME has been configured <span class="hljs-keyword">at</span> $HOME/.helm. Tiller (the helm <span class="hljs-keyword">server</span> side component) has been installed <span class="hljs-keyword">into</span> your Kubernetes Cluster. Happy Helming!</code>
该命令完成后,您可以通过列出所有kube-system验证它安装helm:
<code class="hljs cs">$ kubectl <span class="hljs-keyword">get</span> pods –<span class="hljs-keyword">namespace</span>=kube-system tiller-deploy<span class="hljs-number">-500364655</span>-e3ldg <span class="hljs-number">1</span>/<span class="hljs-number">1</span> Running <span class="hljs-number">0</span> <span class="hljs-number">1</span>m</code>
现在,我们可以验证客户端和服务器部分被重新运行。我们应该看到这两个部分中列出的版本:(实际上,它指出在这个从GitHub的helm note,但在实践中使用命令,我只看到它显示了客户端版)
<code class="hljs css"><span class="hljs-selector-tag">helm</span> <span class="hljs-selector-tag">version</span> <span class="hljs-selector-tag">v2</span><span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.0-alpha</span><span class="hljs-selector-class">.4</span></code>
准备 GCE
为了让我们的Chart正常运行,我们需要得到一些底层架构。该图表将创建3 个MongoDB的实例,每个都需要有一个持久Kubernetes Persistent Volume。由于我们这篇文章使用GCE的云服务提供商,我们需要使用gcloud SDK第一设置3个 GCE永久磁盘。确保你在同一区域作为你kubernetes集群创建的磁盘。
<code class="hljs sql">$ gcloud compute disks <span class="hljs-keyword">create</span> pd-disk<span class="hljs-number">-1</span> pd-disk<span class="hljs-number">-2</span> pd-disk<span class="hljs-number">-3</span> <span class="hljs-comment">--zone us-central1-b –size=10GB</span> <span class="hljs-keyword">WARNING</span>: You have selected a disk <span class="hljs-keyword">size</span> <span class="hljs-keyword">of</span> <span class="hljs-keyword">under</span> [<span class="hljs-number">200</span>GB]. This may <span class="hljs-keyword">result</span> <span class="hljs-keyword">in</span> poor I/O <span class="hljs-keyword">performance</span>. <span class="hljs-keyword">For</span> more information, see: https://developers.google.com/<span class="hljs-keyword">compute</span>/docs/disks#pdperformance. Created [https://www.googleapis.com/<span class="hljs-keyword">compute</span>/v1/projects/<span class="hljs-keyword">compact</span>-market<span class="hljs-number">-142402</span>/zones/us-central1-b/disks/pd-disk<span class="hljs-number">-1</span>]. Created [https://www.googleapis.com/<span class="hljs-keyword">compute</span>/v1/projects/<span class="hljs-keyword">compact</span>-market<span class="hljs-number">-142402</span>/zones/us-central1-b/disks/pd-disk<span class="hljs-number">-2</span>]. Created [https://www.googleapis.com/<span class="hljs-keyword">compute</span>/v1/projects/<span class="hljs-keyword">compact</span>-market<span class="hljs-number">-142402</span>/zones/us-central1-b/disks/pc-disk<span class="hljs-number">-3</span>]. <span class="hljs-keyword">NAME</span> ZONE SIZE_GB <span class="hljs-keyword">TYPE</span> <span class="hljs-keyword">STATUS</span> pd-disk<span class="hljs-number">-1</span> us-central1-b <span class="hljs-number">10</span> pd-standard READY pd-disk<span class="hljs-number">-2</span> us-central1-b <span class="hljs-number">10</span> pd-standard READY pc-disk<span class="hljs-number">-3</span> us-central1-b <span class="hljs-number">10</span> pd-standard READY <span class="hljs-keyword">New</span> disks <span class="hljs-keyword">are</span> unformatted. You must <span class="hljs-keyword">format</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">mount</span> a disk <span class="hljs-keyword">before</span> it can be used. You can find instructions <span class="hljs-keyword">on</span> how <span class="hljs-keyword">to</span> <span class="hljs-keyword">do</span> this <span class="hljs-keyword">at</span>: https://cloud.google.com/<span class="hljs-keyword">compute</span>/docs/disks/<span class="hljs-keyword">add</span>-persistent-disk#formatting</code>
不要担心警告,新的磁盘格式化,MongoDB会提醒我们。现在,我们有GCE PD的创建,我们需要创建相应的Kubernetes Persistent Volumes。创建一个名为GCE-pv.yaml的文件,内容如下:
<code class="hljs makefile">kind: PersistentVolume apiVersion: v1 <span class="hljs-section">metadata:</span> name: pv0001 annotations: volume.beta.kubernetes.io/storage-class: generic <span class="hljs-section">spec:</span> capacity: storage: 10Gi accessModes: - ReadWriteOnce gcePersistentDisk: fsType: ext4 pdName: pd-disk-1 --- kind: PersistentVolume apiVersion: v1 <span class="hljs-section">metadata:</span> name: pv0002 annotations: volume.beta.kubernetes.io/storage-class: generic <span class="hljs-section">spec:</span> capacity: storage: 10Gi accessModes: - ReadWriteOnce gcePersistentDisk: fsType: ext4 pdName: pd-disk-2 --- kind: PersistentVolume apiVersion: v1 <span class="hljs-section">metadata:</span> name: pv0003 annotations: volume.beta.kubernetes.io/storage-class: generic <span class="hljs-section">spec:</span> capacity: storage: 10Gi accessModes: - ReadWriteOnce gcePersistentDisk: fsType: ext4 pdName: pd-disk-3</code>
保存文件,然后使用kubectl来创建它们
<code class="hljs bash">$ kubectl create <span class="hljs-_">-f</span> gce-pv.yaml persistentvolume <span class="hljs-string">"pv0001"</span> created persistentvolume <span class="hljs-string">"pv0002"</span> created persistentvolume <span class="hljs-string">"pv0003"</span> created</code>
现在我们可以来安装Chart!
Charts
Charts是描述软件包的Kubernetes方式。chart基本上与描述了如何部署应用程序文件的目录。这与Puppet Modules非常相似,因为它们是描述应用程序代码的目录。
文件结构
顶层目录的名称是应用程序的名称。structore概述如下:
<code class="hljs objectivec">mongodb/ Chart.yaml LICE<span class="hljs-built_in">NSE</span> README.md values.yaml charts/ templates/ templates/NOTES.txt</code>
该Chart.yaml和values.yaml文件是唯一需要的文件,包括有关chart信息。
Chart.yaml
我不会把Chart.yaml文件的详细信息弄的那么繁杂。这种东西应该是帮助我们理解抽象的部署应用程序,就像MongoDB的那么容易,因为用apt或yum的安装。如果你真的想知道更多有关如何将文件的组织知识,你可以自行阅读相关知识。
MongoDB Chart
Incubator 状态
Chart被认为是“_incubator status_’,这意味着它不符合下列条件之一是:
- 提供了数据持久性的方法(如适用)
- 支持应用升级
- 允许应用程序配置的定制
- 提供一个安全的默认配置
- 不要利用Kubernetes alpha功能
MongoDB chart使用大量的Kubernetesalpha功能这使得它处于孵化器的状态。
获取Chart
第一步,通过用git clone到本地存储库以获得图表。
<code class="hljs nginx"><span class="hljs-attribute">git</span> clone https://github.com/kubernetes/charts.git</code>
安装 Chart
现在,可以用一个命令来安装我们的chart。
<code class="hljs sql">helm <span class="hljs-keyword">install</span> charts/incubator/mongodb/ reeling-indri <span class="hljs-keyword">Last</span> Deployed: Thu <span class="hljs-keyword">Oct</span> <span class="hljs-number">6</span> <span class="hljs-number">22</span>:<span class="hljs-number">49</span>:<span class="hljs-number">15</span> <span class="hljs-number">2016</span> Namespace: <span class="hljs-keyword">default</span> <span class="hljs-keyword">Status</span>: DEPLOYED Resources: ==> v1/Service <span class="hljs-keyword">NAME</span> CLUSTER-IP <span class="hljs-keyword">EXTERNAL</span>-IP PORT(S) AGE reeling-indri-mongodb <span class="hljs-keyword">None</span> <<span class="hljs-keyword">none</span>> <span class="hljs-number">27017</span>/TCP <span class="hljs-number">0</span>s ==> apps/PetSet <span class="hljs-keyword">NAME</span> DESIRED <span class="hljs-keyword">CURRENT</span> AGE reeling-indri-mongodb <span class="hljs-number">3</span> <span class="hljs-number">3</span> <span class="hljs-number">0</span>s Notes: Getting Started: <span class="hljs-number">1.</span> <span class="hljs-keyword">After</span> the petset <span class="hljs-keyword">is</span> created completely, one can <span class="hljs-keyword">check</span> which <span class="hljs-keyword">instance</span> <span class="hljs-keyword">is</span> primary <span class="hljs-keyword">by</span> running: $ <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-string">`seq 0 2`</span>; <span class="hljs-keyword">do</span> kubectl exec reeling-indri-mongodb-$i <span class="hljs-comment">-- sh -c "/usr/bin/mongo --eval="printjson(rs.isMaster())""; done.</span> This assumes <span class="hljs-number">3</span> replicas, <span class="hljs-number">0</span> <span class="hljs-keyword">through</span> <span class="hljs-number">2.</span> It should be modified <span class="hljs-keyword">to</span> reflect the actual <span class="hljs-built_in">number</span> <span class="hljs-keyword">of</span> replicas specified. <span class="hljs-number">2.</span> One can <span class="hljs-keyword">insert</span> a <span class="hljs-keyword">key</span> <span class="hljs-keyword">into</span> the primary <span class="hljs-keyword">instance</span> <span class="hljs-keyword">of</span> the mongodb replica <span class="hljs-keyword">set</span> <span class="hljs-keyword">by</span> running the <span class="hljs-keyword">following</span>: $ kubectl exec MASTER_POD_NAME <span class="hljs-comment">-- /usr/bin/mongo --eval="printjson(db.test.insert({key1: "value1"}))"</span> MASTER_POD_NAME must be replaced <span class="hljs-keyword">with</span> the <span class="hljs-keyword">name</span> <span class="hljs-keyword">of</span> the <span class="hljs-keyword">master</span> <span class="hljs-keyword">found</span> <span class="hljs-keyword">from</span> the previous step. <span class="hljs-number">3.</span> One can <span class="hljs-keyword">fetch</span> the <span class="hljs-keyword">keys</span> <span class="hljs-keyword">stored</span> <span class="hljs-keyword">in</span> the primary <span class="hljs-keyword">or</span> <span class="hljs-keyword">any</span> <span class="hljs-keyword">of</span> the <span class="hljs-keyword">slave</span> nodes <span class="hljs-keyword">in</span> the <span class="hljs-keyword">following</span> manner. $ kubectl exec POD_NAME <span class="hljs-comment">-- /usr/bin/mongo --eval="rs.slaveOk(); db.test.find().forEach(printjson)"</span> POD_NAME must be replaced <span class="hljs-keyword">by</span> the <span class="hljs-keyword">name</span> <span class="hljs-keyword">of</span> the pod being queried.</code>
这将在默认的命名空间内为MongoDB创建Kubernetes服务和petset。从helm来看,先安装命令是PetSet发布的名称。这很重要,因为这是我们以后的一切引用。几分钟后,检查我们的pods的状态。
<code class="hljs cs">kubectl <span class="hljs-keyword">get</span> pods –<span class="hljs-keyword">namespace</span>=<span class="hljs-keyword">default</span> NAME READY STATUS RESTARTS AGE reeling-indri-mongodb<span class="hljs-number">-0</span> <span class="hljs-number">1</span>/<span class="hljs-number">1</span> Running <span class="hljs-number">0</span> <span class="hljs-number">2</span>m reeling-indri-mongodb<span class="hljs-number">-1</span> <span class="hljs-number">1</span>/<span class="hljs-number">1</span> Running <span class="hljs-number">0</span> <span class="hljs-number">1</span>m reeling-indri-mongodb<span class="hljs-number">-2</span> <span class="hljs-number">1</span>/<span class="hljs-number">1</span> Running <span class="hljs-number">0</span> <span class="hljs-number">51</span>s</code>
现在,我们在Kubernetes集群中有运行的的MongoDB集群。最后,我们将学习如何访问它,并验证一切工作。
验证 MongoDB 的运行
现在,我们的MongoDB在运行中,我们可以在上面运行一些命令来检查MongoDB是否在真正运行。
<code class="hljs bash"><span class="hljs-built_in">export</span> RELEASE_NAME=reeling-indri</code>
现在运行以下命令来找出哪一个是主要的MongoDB pods。
<code class="hljs bash">$ <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> 0 1 2; <span class="hljs-keyword">do</span> kubectl <span class="hljs-built_in">exec</span> <span class="hljs-variable">$RELEASE_NAME</span>-mongodb-<span class="hljs-variable">$i</span> -- sh -c <span class="hljs-string">"/usr/bin/mongo --eval="printjson(rs.isMaster())""</span>; <span class="hljs-keyword">done</span> MongoDB shell version: 3.2.10 connecting to: <span class="hljs-built_in">test</span> { <span class="hljs-string">"hosts"</span> : [ <span class="hljs-string">"whopping-elk-mongodb-0.whopping-elk-mongodb.default.svc.cluster.local:27017"</span> ], <span class="hljs-string">"setName"</span> : <span class="hljs-string">"rs0"</span>, <span class="hljs-string">"ismaster"</span> : <span class="hljs-literal">false</span>, <span class="hljs-string">"secondary"</span> : <span class="hljs-literal">false</span>, <span class="hljs-string">"info"</span> : <span class="hljs-string">"Does not have a valid replica set config"</span>, <span class="hljs-string">"isreplicaset"</span> : <span class="hljs-literal">true</span>, <span class="hljs-string">"maxBsonObjectSize"</span> : 16777216, <span class="hljs-string">"maxMessageSizeBytes"</span> : 48000000, <span class="hljs-string">"maxWriteBatchSize"</span> : 1000, <span class="hljs-string">"localTime"</span> : ISODate(<span class="hljs-string">"2016-10-07T03:58:29.718Z"</span>), <span class="hljs-string">"maxWireVersion"</span> : 4, <span class="hljs-string">"minWireVersion"</span> : 0, <span class="hljs-string">"ok"</span> : 1 } MongoDB shell version: 3.2.10 connecting to: <span class="hljs-built_in">test</span> { <span class="hljs-string">"hosts"</span> : [ <span class="hljs-string">"reeling-indri-mongodb-1.reeling-indri-mongodb.default.svc.cluster.local:27017"</span> ], <span class="hljs-string">"setName"</span> : <span class="hljs-string">"rs0"</span>, <span class="hljs-string">"setVersion"</span> : 1, <span class="hljs-string">"ismaster"</span> : <span class="hljs-literal">true</span>, <span class="hljs-string">"secondary"</span> : <span class="hljs-literal">false</span>, <span class="hljs-string">"primary"</span> : <span class="hljs-string">"reeling-indri-mongodb-1.reeling-indri-mongodb.default.svc.cluster.local:27017"</span>, <span class="hljs-string">"me"</span> : <span class="hljs-string">"reeling-indri-mongodb-1.reeling-indri-mongodb.default.svc.cluster.local:27017"</span>, <span class="hljs-string">"electionId"</span> : ObjectId(<span class="hljs-string">"7fffffff0000000000000001"</span>), <span class="hljs-string">"maxBsonObjectSize"</span> : 16777216, <span class="hljs-string">"maxMessageSizeBytes"</span> : 48000000, <span class="hljs-string">"maxWriteBatchSize"</span> : 1000, <span class="hljs-string">"localTime"</span> : ISODate(<span class="hljs-string">"2016-10-07T03:58:30.775Z"</span>), <span class="hljs-string">"maxWireVersion"</span> : 4, <span class="hljs-string">"minWireVersion"</span> : 0, <span class="hljs-string">"ok"</span> : 1 } MongoDB shell version: 3.2.10 connecting to: <span class="hljs-built_in">test</span> { <span class="hljs-string">"hosts"</span> : [ <span class="hljs-string">"lanky-bronco-mongodb-0.lanky-bronco-mongodb.default.svc.cluster.local:27017"</span> ], <span class="hljs-string">"setName"</span> : <span class="hljs-string">"rs0"</span>, <span class="hljs-string">"ismaster"</span> : <span class="hljs-literal">false</span>, <span class="hljs-string">"secondary"</span> : <span class="hljs-literal">false</span>, <span class="hljs-string">"info"</span> : <span class="hljs-string">"Does not have a valid replica set config"</span>, <span class="hljs-string">"isreplicaset"</span> : <span class="hljs-literal">true</span>, <span class="hljs-string">"maxBsonObjectSize"</span> : 16777216, <span class="hljs-string">"maxMessageSizeBytes"</span> : 48000000, <span class="hljs-string">"maxWriteBatchSize"</span> : 1000, <span class="hljs-string">"localTime"</span> : ISODate(<span class="hljs-string">"2016-10-07T03:58:31.878Z"</span>), <span class="hljs-string">"maxWireVersion"</span> : 4, <span class="hljs-string">"minWireVersion"</span> : 0, <span class="hljs-string">"ok"</span> : 1</code>
你可以从上面举的例子中看到,第二个pod是主MongoDB实例。
卸载
如果你想MongoDB停止运行,你可以使用“uninstall”命令。
<code class="hljs coffeescript">helm <span class="hljs-keyword">delete</span> reeling-indri</code>
结论
现在你有一个MongoDB的安装配置好并存储数据。我们用一个简单方法安装了它Kubernetes称为Helm。由于这仍然是相当新的技术,所以这篇文章只有几个chart可用,但我相信在不久的将来会有很多。