在线申请试用
首页 产品 方案与服务 案例 精灵学院 关于我们

400-9023-269

Institute

干货文章

培训课程针对企业开设,培训内容以理论结合实践,帮助企业突破技术壁垒,助力企业技术转型。
培训课程针对企业开设,培训内容以理论结合实践,帮助企业突破技...

如何通过在多个Vagrant管理的虚拟机上部署多节点的Kubernetes集群

发布时间:2018/02/01 16:43:43   Click:

 

Kubernetes是一个非常受欢迎的开源容器管理系统。Kubernetes的价值是实现跨多个节点对容器进行管理像在单个系统上的容器管理一样简单。 为了实现这一点,它提供了不少独特的功能,比如负载均衡、自我修复(自动重启)、调度、缩放和滚动更新。

 

在今天的文章中,我们将通过在多节点Kubernetes集群中部署简单的Web应用来了解Kubernetes。然而,在我们开始部署容器之前,我们首先需要建一个集群。

 

建一个Kubernetes集群

 

官方的入门指南会引导你在Google的ContainerEngine平台上部署Kubernetes集群。这确实是一个简单易行的方法,但在本文里,我们将介绍通过另一种方法(主要是通过Vagrant)来部署Kubernetes。我们使用Vagrant有不少原因,但主要是因为它展示了如何在通用平台上部署Kubernetes而不是仅仅是在GCE。

 

Kubernetes为各种平台提供了几个安装脚本。其中大多数脚本是使用Bash环境变量来改变Kubernetes的安装方式。

 

对于这个安装,我们规定两个变量:

NUM_NODES - 控制部署节点的数量

KUBERNETES_PROVIDER - 指定安装Kubernetes的平台

我们规定安装脚本使用vagrant平台并配置2节点集群。

 

$ export NUM_NODES=2

$ export KUBERNETES_PROVIDER=vagrant

 

例如,如果我们想在亚马逊上部署Kubernetes,我们可以通过将KUBERNETES_PROVIDER环境变量更改为亚马逊的变量来实现。

 

使用Kubernetes安装脚本

 

虽然关于如何安装Kubernetes有很多步骤,但我发现最简单的方法是使用https://get.k8s.io上提供的Kubernetes安装脚本。

 

这个脚本基本上是Kubernetes分发安装脚本的一个包装程序,这使安装过程变得更容易一些。我最喜欢这个脚本的原因之一是它会为你下载Kubernetes。

 

要开始使用这个脚本,我们需要先下载,我们可以用一个快速的curl命令来完成下载。一旦我们下载了脚本,我们可以通过运行bash命令和脚本名来执行脚本。

 

$ curl https://get.k8s.io >kubernetes_install.sh

$ bash kubernetes_install.sh

Downloading kubernetes release v1.2.2 to/var/tmp/kubernetes.tar.gz

  %Total    % Received % Xferd  Average Speed   Time    Time    Time  Current

                                 Dload  Upload  Total   Spent    Left Speed

100 426M  100  426M   0     0  12.2M     0  0:00:34  0:00:34 --:--:-- 6007k

Unpacking kubernetes release v1.2.2

Creating a kubernetes on vagrant...

Kubernetes master is running athttps://10.245.1.2

Heapster is running athttps://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/heapster

KubeDNS is running athttps://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kube-dns

kubernetes-dashboard is running athttps://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard

Grafana is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana

InfluxDB is running athttps://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb

Installation successful!


 

脚本完成执行后,我们就会有一个正在运行的Kubernetes集群。但是,在我们开始与这个Kubernetes集群交互之前,我们还需一个步骤,那就是安装kubectl命令。

 

设置kubectl

 

 

kubectl命令对于Linux和Mac OS X两种系统都适用。我会一边在MacBook运行此安装,一边安装kubectl的Mac OS X 版本。这就意味着我将通过Vagrant运行集群,但是会用MacBook与该集群交互。

 

下载kubectl命令,我们将再次使用curl。

 

$ curlhttps://storage.googleapis.com/kubernetes-release/release/v1.2.0/bin/darwin/amd64/kubectl> kubectl

  %Total    % Received % Xferd  Average Speed   Time   Time     Time  Current

                                 Dload  Upload  Total   Spent    Left Speed

100 38.7M 100 38.7M    0     0 10.4M      0 0:00:03  0:00:03 --:--:-- 10.4M

$ chmod 750 kubectl

 

在kubectl二进制文件下载并权限更改为允许执行之后,kubectl命令就算准备就绪。在我们开始与Kubernetes集群进行交互之前,还需一个步骤,就是配置kubectl命令。

 

$ export KUBECONFIG=~/.kube/config

 

与大多数Kubernetes脚本一样,kubectl命令的配置由环境变量驱动。当我们执行上面的集群安装脚本时,该脚本会在主目录中创建了一个.kube配置目录。 在这个配置目录中,它还会创建了一个名为config的文件,这个文件用于存储已创建的Kubernetes群集相关的信息。

 

通过将KUBECONFIG环境变量设置为/ .kube / config,我们定义kubectl命令应该引用那个配置文件。可以看看下图就是该文件展示,能更好地了解设置的内容。

 

$ cat ~/.kube/config

apiVersion: v1

clusters:

- cluster:

   certificate-authority-data:

   server: https://10.245.1.2

 name: vagrant

contexts:

- context:

   cluster: vagrant

   user: vagrant

 name: vagrant

current-context: vagrant

kind: Config

preferences: {}

users:

- name: vagrant

 user:

    client-certificate-data:

   client-key-data:

   token: sometoken

- name: vagrant-basic-auth

 user:

   password: somepassword

   username: admin

 

.kube / config文件设置了两个主要信息:

 

集群的位置

与该群集通信的身份验证数据

通过定义.kube / config文件,尝试对的Kubernetes集群执行一个kubectl命令来完成验证。

 

$ ./kubectl get nodes

NAME                STATUS    AGE

kubernetes-node-1   Ready    31m

kubernetes-node-2   Ready    24m

 

/kubectl get nodes命令的输出能够显示连接的Kubernetes集群并显示两个节点kubernetes-node-1和kubernetes-node-2的状态。 完成了这个,我们就可以继续下一步。

 

关于Kubernetes节点

 

 

在上面的命令中,我们使用了kubectl来显示集群上可用的Kubernetes节点的状态。但是,我们实际上并没有探索节点是什么,或者它在集群中的作用。

 

Kubernetes节点是用于托管应用容器的物理设备或虚拟机。在传统的容器环境中,您通常会定义指定的容器在指定的物理设备或虚拟机上运行。但是,在Kubernetes集群中,你只需定义想运行的应用容器即可。 Kubernetes主节点能够决定应用容器将在哪个节点上运行。

 

此方法还能够让Kubernetes集群执行任务,比如当遇到容器或节点死掉时自动重新启动。

 

部署应用

 

使用我们准备好的Kubernetes集群,我们现在可以开始部署应用容器。我们今天要部署的应用容器是一个实例-Ghost。Ghost是一个基于JavaScript的流行博客平台,拥有正规的Docker镜像,部署起来非常简单。

 

由于我们将使用预先构建的Docker容器,因此我们不需要先构建Docker镜像。 但是,为了在Kubernetes集群上使用定制的容器,行动是非常重要的。那就是你必须先构建容器并将其推送到Docker存储库(如Docker Hub)。

 

要启动我们的Ghost容器,我们将使用带有run选项的./kubectl命令。

 

$ ./kubectl run ghost --image=ghost--port=2368

deployment "ghost" created

 

在上面的命令中,我们使用镜像ghost创建一个命名为ghost的调度,并指定ghost容器的端口是2368. 以免我们跑错太远,需要先验证容器是否正在运行,可以通过使用getpodsoptions执行kubectl命令来验证容器是否正在运行。

 

$ ./kubectl get pods

NAME                     READY     STATUS   RESTARTS   AGE

ghost-3550706830-4c2n5   1/1      Running   0          20m

 

get pod选项将会发出kubectl命令,列出当前部署到集群上所有的Kubernetes Pods。

 

什么是Pods和部署?

 

Pod是一组可以相互通信的容器,就好像它们在同一个系统中运行一样。 对于那些熟悉Docker的人来说,这可能听起来像连接容器,但实际上Pod不仅仅是个连接器。Pod内的容器不仅能够通过本地主机相互连接,并且容器中运行的进程也能够与其他容器共享内存。

 

Pod的目标是允许在Pod中运行的应用在不同的容器中以同样的方式进行交互,而不仅仅是在同一个物理主机上运行。这种能力使得部署那些并不是专门为容器设计的应用变得容易。

 

部署或部署对象类似于Desired State的概念。基本上,部署是相比所需功能更高级的配置。例如,在我们开始使用Ghost容器的时候,我们并没有启动一个Ghost容器。我们实际上是配置了Kubernetes以确保至少有一个Ghost容器的副本正在运行。

 

为Ghost创建服务

 

虽然Pod内的容器可以连接到集群外的系统,但外部系统以及其他Pod无法与其通信。这是因为默认情况下,为Ghost服务定义的端口不会显示在此群集外。

 

服务开始,为了让我们的Ghost应用可以在群集外部访问,我们刚刚创建的部署需要作为Kubernetes的服务显示。要将我们的Ghost部署设置为服务,我们将再次使用kubectl命令,这次使用上面显示的选项。

 

$ ./kubectl expose deployment ghost--type="NodePort"

service "ghost" exposed

 

在上面的命令中,我们使用了带NodePort参数的标志。这个标志定义了在这种情况下服务显示是一个NodePort服务类型。 NodePort服务类型将设置所有节点在指定的端口上。如果再次使用kubectl命令且获取服务选项,我们就能看到我们的更改生效了。

 

$ ./kubectl get services

NAME        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE

ghost       10.247.63.140   nodes         2368/TCP   55s

kubernetes  10.247.0.1             443/TCP    19m

 

服务类型

 

 

目前,Kubernetes支持三种服务类型:

 

ClusterIP

NodePort

LoadBalancer

 

如果我们只想显示服务给集群中其他的Pod,我们可以使用默认的ClusterIP服务类型。这种服务类型可以打开Pod之间通信的每个节点上的端口。

 

LoadBalancer服务类型主要用于提供外部IP作为服务负载均衡器。 由于我们的部署是使用Vagrant在本地笔记本电脑上完成的,因此该选项在我们的环境中不起作用。 LoadBalancer服务类型可运用于部署在云环境中的Kubernetes集群。(如GCE或AWS)

 

测试Ghost实例

 

 

由于我们在定义NodePort服务时没有指定端口,Kubernetes随机分配了一个端口。要查看它分配是哪一个端口,我们可以使用描述服务选项的kubectl命令。

 

$ ./kubectl describe service ghost

Name:           ghost

Namespace:      default

Labels:         run=ghost

Selector:       run=ghost

Type:           NodePort

IP:        10.247.63.140

Port:          2368/TCP

NodePort:      32738/TCP

Endpoints:      10.246.3.3:2368

Session Affinity:   None

No events.

 

我们可以看到分配的端口是32738。通过这个端口,我们可以使用curl命令对我们的任何Kubernetes节点进行HTTP调用,并将其重新分配到到应用容器内的端口2368中。

 

$ curl -vk http://10.245.1.3:32738

* Rebuilt URL to: http://10.245.1.3:32738/

*  Trying 10.245.1.3...

* Connected to 10.245.1.3 (10.245.1.3) port32738 (#0)

> GET / HTTP/1.1

> Host: 10.245.1.3:32738

> User-Agent: curl/7.43.0

> Accept: */*

< HTTP/1.1 200 OK

< X-Powered-By: Express

 

从curl命令的输出中,我们可以看到一个200ok的回复,即表示连接成功。 有趣的是,这个请求是给一个没有运行在Ghost容器中的节点。如果我们使用kubectl来描述Pod,我们可以看到下图的结果:

 

$ ./kubectl describe podghost-3550706830-ss4se

Name:      ghost-3550706830-ss4se

Namespace: default

Node:      kubernetes-node-2/10.245.1.4

Start Time: Sat, 16 Apr 2016 21:13:20 -0700

Labels:    pod-template-hash=3550706830,run=ghost

Status:    Running

IP:    10.246.3.3

Controllers:    ReplicaSet/ghost-3550706830

Containers:

 ghost:

   Container ID:  docker://55ea497a166ff13a733d4ad3be3abe42a6d7f3d2c259f2653102fedda485e25d

   Image:      ghost

   Image ID:      docker://09849b7a78d3882afcd46f2310c8b972352bc36aaec9f7fe7771bbc86e5222b9

   Port:       2368/TCP

   QoS Tier:

     memory:   BestEffort

     cpu:  Burstable

   Requests:

     cpu:      100m

   State:      Running

     Started:      Sat, 16 Apr 201621:14:33 -0700

   Ready:      True

   Restart Count:  0

   Environment Variables:

Conditions:

 Type      Status

 Ready     True

Volumes:

 default-token-imnyi:

   Type:   Secret (a volume populatedby a Secret)

   SecretName: default-token-imnyi

No events.

 

在上面的描述中,我们可以看到Ghost Pod在kubernetes-node-2上运行。 但是,我们刚刚做出的HTTP请求是kubernetes-node-1,这可以通过名为kube-proxy的Kubernetes服务来实现。 使用kube-proxy,只需流量到达服务的端口,Kubernetes节点就会检查服务是否在本地运行。如果不是,则会将流量重新分配到运行该服务的节点上。

 

在上面的情况下,就意味着即使HTTP请求是针对kubernetes-node-1,kube-proxy服务也会将通信重新分配到正在运行的kubernetes-node-2的容器。

 

此功能允许用户运行服务,而无需担心服务在哪里以及服务是否完成从一个节点移动到另一个节点。这是一个非常有用的功能,减少维护成本和烦恼。

 

 

扩展部署

 

 

假如我们的Ghost服务正在运行,并且可以被外界访问,我们需要执行最后一项任务,跨多个实例扩展我们的Ghost应用。 要做到这一点,我们可以简单地再次调用kubectl命令,但这次使用scale选项。

 

$ ./kubectl scale deployment ghost--replicas=4

deployment "ghost" scaled

 

我们已经指定应该有4个ghost部署的副本。如果我们执行kubectl再次获取Pods,我们可以看到3个额外用于ghost部署的Pods。

 

./kubectl get pods

NAME                     READY     STATUS   RESTARTS   AGE

ghost-3550706830-49r81   1/1      Running   0          7h

ghost-3550706830-4c2n5   1/1       Running  0          8h

ghost-3550706830-7o2fs   1/1      Running   0          7h

ghost-3550706830-f3dae   1/1      Running   0          7h

 

最后一步,我们现在可以在多个节点和多个Pod上运行我们的Ghost服务。 随着我们的Ghost服务收到请求,这些请求将被负载均衡到各种的Ghost实例中。

 

概要

 

在本文中,我们学习了如何通过在多个Vagrant管理的虚拟机上部署多节点的Kubernetes集群。我们还学习了如何将应用部署到集群、使用应用访问外部系统和将应用扩展到四个实例,但是那怕我们完成了所有的这些任务,但我们只是了解到了Kubernetes的表面。

 

 

本文为原创翻译文章 原文链接:

https://dzone.com/articles/getting-started-with-kubernetes


成都精灵云科技有限公司

新一代云技术的引领者