Docker-Kubenetes-微服务教程-五-

42 阅读17分钟

Docker Kubenetes 微服务教程(五)

原文:Kubernetes Microservices with Docker

协议:CC BY-NC-SA 4.0

十四、在多节点集群上安装 Kubernetes

在本书前面的所有章节中,我们都使用了单节点集群。对于大多数小型应用,单节点集群应该足够了。但是,对于相对较大规模的分布式应用,多节点集群是更合适的选择。在本章中,我们将在多节点(2 节点)集群上安装 Kubernetes。本章包括以下几节。

  • 多节点集群的组件
  • 设置环境
  • 安装主节点
  • 设置 flannels 和 etcd
  • 在主节点上启动 Kubernetes
  • 运行服务代理
  • 测试主节点
  • 添加工作节点
  • 导出主 IP
  • 设置 flannels 和 etcd
  • 在工作节点上启动 Kubernetes
  • 运行服务代理
  • 测试 Kubernetes 集群
  • 在群集上运行应用
  • 将应用公开为服务
  • 在浏览器中测试应用
  • 扩展应用

多节点集群的组件

多节点集群由以下主要和辅助组件组成。

  • Kubernetes 特大师节点 Kubernetes 大师节点 Kubernetes 大师节点 Kubernetes 大师节点 Kubernetes 大师节点 Kubernetes 大师节点 Kubernetes 大师节点 Kubernetes 大师节点 Kubernetes 大师节点
  • -Kubernetes 工作节点
  • -还有 cd
  • 法兰绒
  • -服务代理
  • -库柏

第一章讨论了 etcd、kubernetes 主服务器和服务代理。在第一章中介绍的 etcd 是一个分布式的键值存储,由 Kubernetes 集群管理器使用。我们将 etcd 安装在 Kubernetes 主节点所在的节点上,但是在生产环境中,etcd 通常会作为单独的集群安装在 Kubernetes 主节点以外的节点上。对 etcd 集群的提交基于对大多数(法定)可用节点的复制,并为一个或多个节点的故障做好准备。1 节点群集的多数是 1,3 节点群集的多数是 2,4 节点群集的多数是 3,5 节点群集的多数是 3。一个 etcd 集群通常具有奇数个(> 2)具有容错能力的节点。例如,一个 5 节点 etcd 集群可能会失去多达 2 个节点,从而导致一个 3 节点集群,其中大多数节点仍然是可确定的。一个 3 节点集群具有多一个节点的容错能力。2 节点 etcd 集群没有任何容错能力,2 节点集群的大部分被认为是 2。生产中建议的 etcd 集群大小为 3、5 或 7。

法兰绒是一种用于容器的网状织物。法兰绒为运行时容器使用的每个主机提供一个子网。实际上,法兰绒在每个分配子网的主机上运行一个名为 flanneld 的代理。法兰绒建立并管理网络,该网络将 Kubernetes 创建的所有 Docker 容器相互连接。法兰绒由 etcd 支持,使用 etcd 存储网络配置、分配的子网和辅助数据,如主机的 IP 地址。

设置环境

本章我们使用了从 Ubuntu Server 14-04 LTS (HVM)创建的 Amazon EC2 实例,SSD 卷类型- ami-d05e75b8 AMI。本章要求安装以下软件。

  • -Docker 引擎(最新版本)
  • -主节点上的库帐户(1.01 版)
  • -工作节点上的 Kubernetes(版本 1.01)
  • -Kubernetes(1.01 版)

因为我们正在创建一个多节点集群,所以我们需要创建多个 Amazon EC2 实例。对于双节点集群,创建两个 Amazon EC2 实例——KubernetesMaster 和 KubernetesWorker——如图 14-1 所示。

A418863_1_En_14_Fig1_HTML.gif

图 14-1。

Creating two Ubuntu Instances for Kubernetes Master and Worker Nodes

SSH 分别登录到每个节点。主节点的公共 IP 地址可以从 Amazon EC2 控制台获得,如图 14-2 所示。

A418863_1_En_14_Fig2_HTML.gif

图 14-2。

Obtaining the Public IP Address for a Ubuntu Instance

登录到主节点的 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@52.91.243.99

类似地,获取工作者节点的 Ubuntu 实例的公共 IP 地址,并登录工作者节点的 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@52.23.236.15

按照第一章所述,在每个节点上安装 Docker 和 Kubectl。不要像第一章那样安装 Kubernetes,因为 Kubernetes 的多节点配置不同于单节点配置。

启动 Docker 引擎并验证其状态。

sudo service docker start
sudo service docker status

如图 14-3 所示,Docker 引擎应被列为“正在运行”。

A418863_1_En_14_Fig3_HTML.gif

图 14-3。

Starting Docker

安装主节点

主节点托管 API 服务器并将工作分配给工作节点。我们需要运行两个 Docker 守护进程,一个主 Docker 实例和一个引导 Docker 实例。主 Docker 实例由 Kubernetes 使用,引导 Docker 实例由一个 etcd 使用。法兰绒守护进程建立并管理网络,该网络将 Kubernetes 创建的所有 Docker 容器相互连接起来。

设置 flannels 和 etcd

设置 Flanneld 和 etcd 包括为 Docker 设置一个 bootstrap 实例,为法兰绒和 API 服务器启动 etcd,以及在主节点上设置法兰绒。

设置 Docker 的引导实例

法兰绒,它在 Docker 容器之间建立网络;和 etcd 都是在 Docker 容器内部运行的。使用单独的引导 Docker 是因为法兰绒用于 Kubernetes 创建的 Docker 容器之间的联网;在同一个 Docker 引擎中运行法兰绒和 Kubernetes 可能会有问题,不推荐这样做。为法兰绒和 etcd 创建一个单独的 Docker 引导实例。

sudo sh -c 'docker daemon -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null &'

启动 bootstrap Docker 守护进程,前面命令的输出如图 14-4 所示。

A418863_1_En_14_Fig4_HTML.gif

图 14-4。

Starting the Bootstrap Daemon on the Master Node

“–d”选项在 Docker 1.10 中被完全删除,代之以“daemon”。如果使用 Docker 1.10 之前的 Docker 版本,例如 Docker 1.9.1,请将前面命令中的' daemon '替换为'-d ',以运行命令,如下所示:

sudo sh -c 'docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap . log 1>/dev/null&

设置 etcd

使用以下命令为法兰绒和 API 服务器设置 etcd。

sudo docker -H unix:///var/run/docker-bootstrap.sock run --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data

下载 etcd 的容器并安装 etcd,如图 14-5 所示。

A418863_1_En_14_Fig5_HTML.gif

图 14-5。

Setting up etcd on the Master Node

设置无类域间路由(CIDR ),这是一种 IP 寻址方案,可以减少路由表的大小,并提供更多的可用地址。

sudo docker -H unix:///var/run/docker-bootstrap.sock run --net=host gcr.io/google_containers/etcd:2.0.12 etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }'

前面的命令不产生任何输出,如图 14-6 所示。

A418863_1_En_14_Fig6_HTML.gif

图 14-6。

Setting Up CIDR on the Master Node

设置法兰绒

默认情况下,Docker 确实提供了容器和 pod 之间的网络,但法兰绒提供的网络要简单得多。我们将使用法兰绒进行交流。首先,我们需要阻止 Docker。

sudo service docker stop

如图 14-7 所示,

A418863_1_En_14_Fig7_HTML.gif

图 14-7。

Stopping Docker Temporarily

用下面的命令运行法兰绒。

sudo docker -H unix:///var/run/docker-bootstrap.sock run -d --net=host --privileged -v /dev/net:/dev/net quay.io/coreos/flannel:0.5.0

法兰绒的安装如图 14-8 所示。

A418863_1_En_14_Fig8_HTML.gif

图 14-8。

Installing Flannel

法兰绒生成哈希如图 14-9 所示。复制哈希。

A418863_1_En_14_Fig9_HTML.gif

图 14-9。

Obtaining the Hash Generated by Flannel

将哈希复制并粘贴到以下命令中,然后运行该命令以获取子网设置。

sudo docker -H unix:///var/run/docker-bootstrap.sock exec <really-long-hash-from-above-here> cat /run/flannel/subnet.env

列出子网设置,如图 14-10 所示。

A418863_1_En_14_Fig10_HTML.gif

图 14-10。

Listing the Subnet Settings

记下FLANNEL_SUBNETFLANNEL_MTU的值,因为我们将需要它们来编辑 Docker 配置。在 vi 编辑器中打开 Docker 配置文件。

sudo vi /etc/default/docker

docker 配置文件中的默认设置如图 14-11 所示。

A418863_1_En_14_Fig11_HTML.gif

图 14-11。

Docker Configuration File Default Settings

DOCKER_OPTS设置添加以下参数,其值从图 14-10 的输出中获得。

--bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}

修改后的 docker 配置文件如图 14-12 所示。

A418863_1_En_14_Fig12_HTML.gif

图 14-12。

Modified Docker Configuration File

如前所述,Docker 通过一个名为docker0的 Docker 桥提供了自己的网络。因为我们不会使用默认的 Docker 桥,所以请删除默认的 Docker 桥。对于 brctl 二进制文件,首先安装 bridge-utils 包。

sudo /sbin/ifconfig docker0 down
sudo apt-get install bridge-utils
sudo brctl delbr docker0

安装 bridge-utils 包和移除 docker0 桥的输出如图 14-13 所示。

A418863_1_En_14_Fig13_HTML.gif

图 14-13。

Removing docker0 bridge

重启 Docker。

sudo service docker start

Docker 重新启动,如图 14-14 所示。

A418863_1_En_14_Fig14_HTML.gif

图 14-14。

Restarting Docker

启动 Kubernetes Master

设置法兰绒网络是设置单节点集群和多节点集群的主要区别。使用与单节点集群相同的命令启动 Kubernetes 主服务器。

sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/sys:/sys:ro \
  --volume=/dev:/dev \
  --volume=/var/lib/docker/:/var/lib/docker:rw \
  --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \
  --volume=/var/run:/var/run:rw \
  --net=host \
  --privileged=true \
  --pid=host \
  -d \
  gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube kubelet --api-servers=http://localhost:8080 --v=2 --address=0.0.0.0 --enable-server --hostname-override=127.0.0.1 --config=/etc/kubernetes/manifests-multi --cluster-dns=10.0.0.10 --cluster-domain=cluster.local

前面的命令从主节点运行,如图 14-15 所示。

A418863_1_En_14_Fig15_HTML.gif

图 14-15。

Starting Kubernetes on the Master Node

Kubernetes 安装在主节点上,如图 14-16 所示。

A418863_1_En_14_Fig16_HTML.gif

图 14-16。

Kubernetes Started on Master Node

运行服务代理

使用与单节点集群相同的命令运行服务代理。

sudo docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube proxy --master=http://127.0.0.1:8080 --v=2

服务代理的安装如图 14-17 所示。

A418863_1_En_14_Fig17_HTML.gif

图 14-17。

Starting Service proxy on Master Node

测试单节点集群

要测试主节点,请运行以下命令,该命令列出了群集中的节点。

kubectl get nodes

单个节点被列出,如图 14-18 所示。

A418863_1_En_14_Fig18_HTML.gif

图 14-18。

Listing the Nodes, only the Master Node to start with

添加工作节点

设置工作节点与设置主节点非常相似。接下来,我们将设置一个工作节点。工作者节点的 Ubuntu 实例的 SSH 登录。

导出主 IP

首先,我们需要设置环境变量MASTER_IP。获取运行主节点的 Ubuntu 实例的公共 IP 地址,如图 14-19 所示。

A418863_1_En_14_Fig19_HTML.gif

图 14-19。

Obtaining the Master Node’s IP Address

使用公共 IP 地址导出环境变量MASTER_IP

export MASTER_IP=52.91.243.99

回显MASTER_IP环境变量。

echo $MASTER_IP

前面命令的输出如图 14-20 所示。

A418863_1_En_14_Fig20_HTML.gif

图 14-20。

Exporting the MASTER_IP Environment Variable on a Worker Node

设置法兰绒

启动一个 bootstrap Docker 守护进程,只是为了法兰绒网络。

sudo sh -c 'docker daemon -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null &'

自举对接器的设置如图 14-21 所示。

A418863_1_En_14_Fig21_HTML.gif

图 14-21。

Starting Bootstrap Docker on the Worker Node

“–d”选项在 Docker 1.10 中被完全删除,代之以“daemon”。如果使用 Docker 1.10 之前的 Docker 版本,例如 Docker 1.9.1,请将前面命令中的' daemon '替换为'-d ',以运行命令,如下所示:

sudo sh -c 'docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap . log 1>/dev/null&

要安装法兰绒,首先我们需要停止 Docker 引擎。

sudo service docker stop

对接发动机停止,如图 14-22 所示。

A418863_1_En_14_Fig22_HTML.gif

图 14-22。

Stopping Docker Temporarily on the Worker Node

接下来,在 worker 节点上安装法兰绒。主节点上运行的相同 etcd 用于工作节点上的 flanneld。etcd 实例使用MASTER_IP环境变量包含主服务器的 Ip。

sudo docker -H unix:///var/run/docker-bootstrap.sock run -d --net=host --privileged -v /dev/net:/dev/net quay.io/coreos/flannel:0.5.0 /opt/bin/flanneld --etcd-endpoints=http://${MASTER_IP}:4001

法兰绒被设置在工人节点上,如图 14-23 所示。

A418863_1_En_14_Fig23_HTML.gif

图 14-23。

Installing Flannel on the Worker Node

复制前面命令生成的哈希,如图 14-24 所示。

A418863_1_En_14_Fig24_HTML.gif

图 14-24。

Obtaining the Hash geenrated by Flannel

使用以下命令中的哈希值从法兰绒获取子网设置。

sudo docker -H unix:///var/run/docker-bootstrap.sock exec <really-long-hash-from-above-here> cat /run/flannel/subnet.env

子网设置得到如图 14-25 所示的输出。

A418863_1_En_14_Fig25_HTML.gif

图 14-25。

Listing the Subnet Settings on the Worker Node

使用子网设置,我们需要编辑 Docker 配置文件。在 vi 编辑器中打开 Docker 配置文件。

sudo /etc/default/docker

将以下参数添加到DOCKER_OPTS设置中。将从图 14-25 中获得的值代入FLANNEL_SUBNETFLANNEL_MTU中。

--bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}

修改后的 Docker 配置文件如图 14-26 所示。

A418863_1_En_14_Fig26_HTML.gif

图 14-26。

Modified Docker Configuration File

关闭并移除现有的 Docker 网桥docker0,Docker 默认使用该网桥在容器和 pod 之间进行联网。需要安装 bridge-utils 包,因为它在 Amazon EC2 上的 Ubuntu 实例上默认不可用。

sudo /sbin/ifconfig docker0 down
sudo apt-get install bridge-utils
sudo brctl delbr docker0

重启 Docker。

sudo service docker start

对接引擎启动,如图 14-27 所示。

A418863_1_En_14_Fig27_HTML.gif

图 14-27。

Restarting Docker

在工作节点上启动 Kubernetes

使用与主节点相同的命令在 worker 节点上启动 Kubernetes,不同之处在于,不是将--api-servers设置为http://localhost:8080,而是将- api-servers 设置为http://${MASTER_IP}:8080

sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/sys:/sys:ro \
  --volume=/dev:/dev \
  --volume=/var/lib/docker/:/var/lib/docker:rw \
  --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \
  --volume=/var/run:/var/run:rw \
  --net=host \
  --privileged=true \
  --pid=host \
  -d \
  gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube kubelet --api-servers=http://${MASTER_IP}:8080 --v=2 --address=0.0.0.0 --enable-server --hostname-override=$(hostname -i) --cluster-dns=10.0.0.10 --cluster-domain=cluster.local

前面的命令将在 worker 节点上运行,如图 14-28 所示。

A418863_1_En_14_Fig28_HTML.gif

图 14-28。

Starting Kubernetes on the Worker Node

运行服务代理

工作节点上的服务代理也使用与主节点相同的命令运行,只是主节点的 Ip 参数-- master= http://127.0.0.1:8080应该替换为--master=http://${MASTER_IP}:8080

sudo docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v1.0.1 /hyperkube proxy --master=http://${MASTER_IP}:8080 --v=2

服务代理启动,如图 14-29 所示。

A418863_1_En_14_Fig29_HTML.gif

图 14-29。

Starting Service Proxy on the Worker Node

测试 Kubernetes 集群

从主节点,而不是前面命令中配置的工作节点,列出集群中的节点。

kubectl get nodes

列出两个节点,如图 14-30 所示:主节点和工作节点。

A418863_1_En_14_Fig30_HTML.gif

图 14-30。

Listing a Two-Node Cluster

使用本节添加工作节点中讨论的相同过程,根据需要添加更多节点。

在群集上运行应用

要测试集群,请使用 kubectl 在命令行上运行应用。例如,用下面的命令运行 Docker 映像“nginx”。

kubectl -s http://localhost:8080 run nginx --image=nginx --port=80

随后列出 POD。

kubectl get pods

如图 14-31 所示,nginx 应用容器被创建,nginx 复制控制器被创建,默认为 1 个副本。一个吊舱被列出,也如图 14-31 所示。最初,Pod 可以被列为待定状态。几秒钟后运行前面的命令,将 Pod 列为正在运行和就绪。要查找 Pod 正在群集中的哪个实例(节点)上运行,请运行命令。

A418863_1_En_14_Fig31_HTML.gif

图 14-31。

Installing an Application on the Cluster

kubectl get pods -o wide.

将应用公开为服务

要将复制控制器 nginx 作为服务公开,请运行以下命令。

kubectl expose rc nginx --port=80

nginx 服务被创建,如图 14-32 所示。

A418863_1_En_14_Fig32_HTML.gif

图 14-32。

Creating a Service

使用以下命令列出服务。

kubectl get services

为了能够调用服务,使用以下命令获取第一个集群 Ip,如图 14-33 所示。

A418863_1_En_14_Fig33_HTML.gif

图 14-33。

Invoking a Web Server with Curl

kubectl get svc nginx --template={{.spec.clusterIP}}

使用返回的集群 Ip 10 . 0 . 0 . 99 调用 web 服务器。

curl 10.0.0.99

nginx 应用返回的 HTML 输出如图 14-34 所示。

A418863_1_En_14_Fig34_HTML.gif

图 14-34。

The HTML generated by the Application

在浏览器中测试应用

要在浏览器中调用服务端点,设置从10.0.0.99:80端点到localhost:80的端口转发。

ssh -i docker.pem -f -nNT -L 80:10.0.0.99:80 ubuntu@ec2-52-91-243-99.compute-1.amazonaws.com

端口转发的设置如图 14-35 所示。

A418863_1_En_14_Fig35_HTML.gif

图 14-35。

Setting Port Forwarding

在本地浏览器中使用 url http://localhost调用 nginx 应用,如图 14-36 所示。

A418863_1_En_14_Fig36_HTML.gif

图 14-36。

Invoking a Service Endpoint in a Browser

扩展应用

缩放是复制控制器的一种常见使用模式。nginx 复制控制器可以使用kubectl scale命令进行缩放。例如,扩展到 3 个副本。

kubectl scale rc nginx --replicas=3

随后列出 POD。

kubectl get pods

输出“scaled”表示复制控制器已被扩展。三个吊舱被列出,如图 14-37 所示。

A418863_1_En_14_Fig37_HTML.gif

图 14-37。

Listing the Pods

用下面的命令描述服务。

kubectl describe svc nginx

列出三个服务端点,如图 14-38 所示。

A418863_1_En_14_Fig38_HTML.gif

图 14-38。

Describing the Service

为了能够在本地机器上的浏览器中调用每个服务端点,请设置端口转发。

ssh -i docker.pem -f -nNT -L 8081:10.1.34.2:80 ubuntu@ec2-52-91-243-99.compute-1.amazonaws.com
ssh -i docker.pem -f -nNT -L 8082:10.1.35.2:80 ubuntu@ec2-52-91-243-99.compute-1.amazonaws.com
ssh -i docker.pem -f -nNT -L 8083:10.1.35.3:80 ubuntu@ec2-52-91-243-99.compute-1.amazonaws.com

端口转发的设置如图 14-39 所示。

A418863_1_En_14_Fig39_HTML.gif

图 14-39。

Setting port Forwarding for the additional Service Endpoints

可以在本地浏览器中调用服务端点。例如,url http://localhost:8081调用一个服务端点,如图 14-40 所示。

A418863_1_En_14_Fig40_HTML.gif

图 14-40。

Invoking a Service Endpoint in a Browser

类似地,url http://localhost:8082调用另一个服务端点,如图 14-41 所示。

A418863_1_En_14_Fig41_HTML.gif

图 14-41。

Invoking another Service Endpoint in a Browser

类似地,url http://localhost:8083调用第三个服务端点,如图 14-42 所示。

A418863_1_En_14_Fig42_HTML.gif

图 14-42。

Invoking a Third Service Endpoint in a Browser

摘要

在本章中,我们在多节点集群上安装了 Kubernetes。多节点配置利用法兰绒进行联网,而不是 Docker 提供的默认联网。首先,我们在主节点上安装了 Kubernetes。使用主节点的 Ip 地址,我们在一个工作节点上安装了 Kubernetes,结果创建了一个双节点集群。可以使用相同的过程添加所需数量的工作节点。我们使用 nginx Docker 映像创建了一个应用,并使用 curl 在命令行上调用该应用,使用端口转发在本地浏览器中调用该应用。我们还扩展了应用。在单节点集群中,应用在主节点上运行。在多节点集群中,应用同时在工作节点和主节点上运行。本章总结了 Docker 关于 Kubernetes 微服务的书。

第一部分:开始

第二部分:关系数据库

第三部分:NoSQL 数据库

第四部分:Apache Hadoop 生态系统

第五部分:多容器和节点