如何在CoreOS集群的顶部安装和配置Kubernetes

Kubernetes是一组用于集群调度和服务编排工具。它通过分组逻辑任务一起进行调度。在本指南中,我们将演示如何让安装CoreOS集群上Kubernetes。

介绍

Kubernetes是一个系统,旨在管理跨群集环境在Docker容器中构建的应用程序。 它处理容器化应用程序的整个生命周期,包括部署和扩展。

在本指南中,我们将演示如何开始使用CoreOS群集上的Kubernetes。 这个系统将允许我们使用Kubernetes调用的“pods”将相关的服务组合在一起作为单个主机上的单元进行部署。 它还提供健康检查功能,高可用性和资源的高效使用。

本教程使用Kubernetes v0.7.0进行测试。 请记住,此软件频繁更改。 要查看您的版本,安装后,请运行:

kubecfg -version

先决条件和目标

我们将从以前的CoreOS指南中使用的相同的基本CoreOS集群开始。 为了得到这个三个成员组运行起来,按照我们的CoreOS集群指南

这将给你三个服务器配置。 虽然每个节点在CoreOS级别上基本上是可互换的,但是在Kubernetes中,我们需要分配更多专门的角色。 我们需要一个节点作为主节点,这将运行一些额外的服务,如API服务器和控制器管理器。

对于本指南,我们将使用以下详细信息:

主机名 公共IPv4 私有IPv4 角色
coreos-1 192.168.2.1 10.120.0.1
coreos-2 192.168.2.2 10.120.0.2 Minion1
coreos-3 192.168.2.3 10.120.0.3 Minion2

在配置我们将以下,主人也将是一个功能齐全的minion服务器能够完成工作。 这种配置的想法是从拍摄布赖恩Ketelson指南上CoreOS设置Kubernetes在这里。

如果你按照上面的指导,创建集群,既etcdfleet应该被配置为使用每个服务器的私有IPv4进行通信。 公共IP地址可用于从本地计算机连接。

本指南将采用这个基本的CoreOS集群,并在其上安装一些服务。

首先,我们将配置flannel ,网布层,提供每台机器与容器通信的各个子网。 这是一个相对较新的CoreOS项目,在很大程度上是为了适应Kubernetes关于网络环境的假设。

我们将配置Docker将此网络层用于部署。 除此之外,我们将设置Kubernetes。 这涉及很多件。 我们需要配置一个代理服务,一个API层和一个名为Kubelet的节点级“pod”管理系统。

创建法兰网络结构层

我们需要做的第一件事是配置flannel服务。 这是为集群中的每台计算机提供单独子网的组件。 Docker将被配置为将其用于部署。 由于这是一个基本要求,它是一个伟大的地方开始。

在写这篇文章的时候,有没有预先生成的二进制文件flannel项目提供。 由于这个事实,我们将必须构建二进制文件并自己安装。 为了节省构建时间,我们将在单个机器上构建此构建器,然后将可执行文件传输到我们的其他节点。

与CoreOS的许多部分一样,Flannel内置在Go编程语言中。 而不是设置一个完整的Go环境来构建包,我们将使用为此目的预先构建的容器。 Google会针对这些类型的情况专门维护Go容器。

所有我们将安装的应用程序将被放置在/opt/bin的目录,这是不是在CoreOS自动创建。 现在创建目录:

sudo mkdir -p /opt/bin

现在我们可以使用Go容器构建项目。 只需运行这个Docker命令从Docker Hub中提取映像,运行容器,并下载并构建容器中的包:

docker run -i -t google/golang /bin/bash -c "go get github.com/coreos/flannel"

当操作完成后,我们可以从容器中复制编译的二进制文件。 首先,我们需要知道容器ID:

docker ps -l -q

结果将是如下所示的ID:

004e7a7e4b70

我们可以利用这个ID来指定复制操作到/opt/bin目录。 二进制一直放在/gopath/bin/flannel容器内。 由于/opt/bin目录是不是我们写core用户,我们将不得不使用sudo

sudo docker cp 004e7a7e4b70:/gopath/bin/flannel /opt/bin/

我们现在有法兰绒可用在我们的第一台机器。 稍后,我们将把它复制到我们的其他机器。

构建Kubernetes二进制

Kubernetes由相当多的不同应用程序和分层技术组成。 目前,该项目不包含我们需要的各种组件的预构建二进制文件。 我们将自己建立自己。

我们只完成了其中一台服务器这一过程。 由于我们的服务器在性质上是统一的,我们可以通过简单地传输我们将生成的二进制文件来避免不必要的构建时间。

第一步是从其GitHub存储库克隆项目。 我们将它克隆到我们的主目录:

cd ~
git clone https://github.com/GoogleCloudPlatform/kubernetes.git

接下来,我们将进入存储库中的构建目录。 从这里,我们可以使用包含的脚本构建二进制文件:

cd kubernetes/build
./release.sh

这个过程将需要相当长的时间。 它将启动一个Docker容器来构建必要的二进制包。

当完成构建过程中,您将能够找到的二进制文件~/kubernetes/_output/dockerized/bin/linux/amd64目录:

cd ~/kubernetes/_output/dockerized/bin/linux/amd64
ls
e2e          kube-apiserver           kube-proxy      kubecfg  kubelet
integration  kube-controller-manager  kube-scheduler  kubectl  kubernetes

我们将这些数据传输到/opt/bin我们前面创建的目录:

sudo cp * /opt/bin

我们的第一台机器现在有我们的项目所需的所有二进制文件。 我们现在可以专注于在我们的其他服务器上获取这些应用程序。

将可执行文件传输到其他服务器

我们的第一台机器具有启动Kubernetes集群所需的所有组件。 我们需要将这些复制到我们的其他机器,虽然之前,这将工作。

由于Kubernetes不是一个统一的安装(有一个主和多个minion),每个主机不需要所有的二进制文件。 每个minion服务器只需要调度程序,docker,proxy,kubelet和flannel可执行文件。

然而,转移所有可执行文件给我们更多的灵活性。 这也更容易。 我们将转移本指南中的一切。

当您连接到您的第一台机器,你应该通过连接转发您的SSH代理信息-A标志(启动代理并添加你的密钥之后)。 这是一个重要的步骤。 如果您之前未通过此标志,请断开并重新连接。

您将需要运行evalssh-add第2步进行身份验证部分命令本教程中使用连接之前-A

首先移动到我们放置我们的二进制文件的目录:

cd /opt/bin

现在,我们可以将此目录中的文件复制到我们的其他主机。 我们将通过将可执行文件直接导入我们的shell标准来实现。 然后我们将管道这进入我们的SSH命令,我们将连接到我们的其他主机之一。

我们将使用将创建的SSH命令/opt/bin我们的其他主机上目录,更改到该目录,并解压所收到的信息,通过SSH隧道。 整个命令看起来像这样:

tar -czf - . | ssh core@192.168.2.2 "sudo mkdir -p /opt/bin; cd /opt/bin; sudo tar xzvf -"

这将把所有可执行文件传输到您指定的IP地址。 使用第三个主机再次运行该命令:

tar -czf - . | ssh core@192.168.2.3 "sudo mkdir -p /opt/bin; cd /opt/bin; sudo tar xzvf -"

你现在有所有的可执行文件在你的三台机器上。

设置主服务

下一步是建立我们systemd单元文件正确配置和推出我们新的应用。 我们将开始处理只在我们的主服务器上运行的应用程序。

我们将会把这些文件中/etc/systemd/system目录下。 现在移动:

cd /etc/systemd/system

现在我们可以开始构建我们的服务文件。 我们将在主机上创建两个文件,并且还在属性上创建五个文件。 所有这些文件将在/etc/systemd/system/*.service

主文件:

  • apiserver.service
  • controller-manager.service

所有服务器的Minion文件:

  • scheduler.service
  • flannel.service
  • docker.service
  • proxy.service
  • kubelet.service

创建API服务器单元文件

我们要配置的第一个文件是API服务器的单元文件。 API服务器用于提供有关集群的信息,处理更改信息的请求,调度每个服务器上的工作以及同步共享信息。

我们将调用这个单元文件apiserver.service为简单起见。 现在创建并打开该文件:

sudo vim apiserver.service

在此文件中,我们将从有关我们的服务的基本元数据开始。 我们需要确保本机不启动,直到etcd和Docker服务启动并运行:

[Unit]
Description=Kubernetes API Server
After=etcd.service
After=docker.service
Wants=etcd.service
Wants=docker.service

接下来,我们将完成[Service]部分。 这将主要用于启动具有描述我们的环境的一些参数的API服务器。 我们还将设置重新启动条件:

[Unit]
Description=Kubernetes API Server
After=etcd.service
After=docker.service
Wants=etcd.service
Wants=docker.service

[Service]
ExecStart=/opt/bin/kube-apiserver \
-address=127.0.0.1 \
-port=8080 \
-etcd_servers=http://127.0.0.1:4001 \
-portal_net=10.100.0.0/16 \
-logtostderr=true
ExecStartPost=-/bin/bash -c "until /usr/bin/curl http://127.0.0.1:8080; do echo \"waiting for API server to come online...\"; sleep 3; done"
Restart=on-failure
RestartSec=5

上述部分建立的网络地址和端口所在的服务器将运行,以及所在的位置etcd正在监听。 portal_net参数给出使网络范围flannel服务将使用。

在我们启动服务后,我们检查它是否在一个循环中运行。 这确保了在依赖服务启动之前服务实际上能够接受连接。 没有这个可能会导致依赖服务的错误,需要手动重新启动。

最后,我们将安装此单元。 我们可以做到这一点与[Install]部分,将告诉我们的主机启动此服务时,机器完全启动:

[Unit]
Description=Kubernetes API Server
After=etcd.service
After=docker.service
Wants=etcd.service
Wants=docker.service

[Service]
ExecStart=/opt/bin/kube-apiserver \
-address=127.0.0.1 \
-port=8080 \
-etcd_servers=http://127.0.0.1:4001 \
-portal_net=10.100.0.0/16 \
-logtostderr=true
ExecStartPost=-/bin/bash -c "until /usr/bin/curl http://127.0.0.1:8080; do echo \"waiting for API server to come online...\"; sleep 3; done"
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

完成后,关闭文件。

创建控制器管理器单元文件

Kubernetes需要的下一个部分是Controller Manager服务器。 此组件用于在群集单元之间执行数据复制。

打开一个名为controller-manager.service在同一目录下:

sudo vim controller-manager.service

我们将再次从基本元数据开始。 这将遵循与最后一个文件相同的格式。 除了其他依赖项,此服务必须在我们刚配置的API服务器单元之后启动:

[Unit]
Description=Kubernetes Controller Manager
After=etcd.service
After=docker.service
After=apiserver.service
Wants=etcd.service
Wants=docker.service
Wants=apiserver.service

对于[Service]这个文件的一部分,我们只需要几个参数传递给可执行文件。 主要是,我们将应用程序指向我们的API服务器的位置。 在这里,我们已经通过了我们每台机器的私有IP地址,用逗号分隔。 修改这些值以镜像您自己的配置。 同样,我们将确保此单元在故障时重新启动,因为它需要我们的Kubernetes集群正常运行:

[Unit]
Description=Kubernetes Controller Manager
After=etcd.service
After=docker.service
After=apiserver.service
Wants=etcd.service
Wants=docker.service
Wants=apiserver.service

[Service]
ExecStart=/opt/bin/kube-controller-manager \
-master=http://127.0.0.1:8080 \
-machines=10.120.0.1,10.120.0.2,10.120.0.3
Restart=on-failure
RestartSec=5

我们还将使用相同的安装说明,以便本机也在启动时启动:

[Unit]
Description=Kubernetes Controller Manager
After=etcd.service
After=docker.service
After=apiserver.service
Wants=etcd.service
Wants=docker.service
Wants=apiserver.service

[Service]
ExecStart=/opt/bin/kube-controller-manager \
-master=http://127.0.0.1:8080 \
-machines=10.120.0.1,10.120.0.2,10.120.0.3
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

保存并在完成后关闭文件。

设置群集服务

现在,我们已经配置了主特定的服务,我们可以配置需要存在于所有我们的机器单元文件。 这意味着您应该将这些文件添加到主服务器和从属服务器,并相应地配置它们。

这五个文件应该在所有机器上创建,在/etc/systemd/system/*.service

  • scheduler.service
  • flannel.service
  • docker.service
  • proxy.service
  • kubelet.service

创建调度程序单元文件

下一个组件是调度程序。 调度程序决定哪个minion运行工作负载并进行通信,以确保发生这种情况。

现在创建并打开此单元的文件:

sudo vim scheduler.service

本机以与最后一台相同的方式启动。 它依赖于所有相同的服务:

[Unit]
Description=Kubernetes Scheduler
After=etcd.service
After=docker.service
After=apiserver.service
Wants=etcd.service
Wants=docker.service
Wants=apiserver.service

服务部分本身是非常直接的。 我们只需要将可执行文件指向API服务器所在的网络地址和端口。 同样,如果失败,我们将重新启动服务。

安装部分反映了我们目前为止看到的其他部分:

[Unit]
Description=Kubernetes Scheduler
After=etcd.service
After=docker.service
After=apiserver.service
Wants=etcd.service
Wants=docker.service
Wants=apiserver.service

[Service]
ExecStart=/opt/bin/kube-scheduler -master=127.0.0.1:8080
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

完成后,保存并关闭文件。

创建法兰单位文件

我们所需要的下一个组件起床,跑是flannel ,我们的网络结构层。 这将用于给每个节点自己的子网为Docker容器。

同样,在每个机,切换到systemd配置目录:

cd /etc/systemd/system

创建和打开flannel在文本编辑器单元文件:

sudo vim flannel.service

在这个文件的内部,我们将从元数据信息开始。 由于该服务需要etcd注册子网信息,我们需要后启动此etcd

[Unit]
Description=Flannel network fabric for CoreOS
Requires=etcd.service
After=etcd.service

对于[Service]部分中,我们首先要源/etc/environment文件,这样我们就可以有机会获得我们主机的私有IP地址。

下一步将是放置ExecStartPre=行试图与注册子网范围etcd 它会不断尝试注册etcd,直到它成功。 我们将使用10.100.0.0/16范围本指南。

然后,我们将开始flannel与我们从环境文件采购的专用IP地址。

之后,我们要检查是否flannel写它的信息到它的文件(让Docker可以在一瞬间读)和睡觉,如果它没有。 这确保Docker服务在可用之前不尝试读取文件(这可能发生在第一个服务器上)。 我们将使用通常的参数配置重新启动和使用安装单位multi-user.target再次:

[Unit]
Description=Flannel network fabric for CoreOS
Requires=etcd.service
After=etcd.service

[Service]
EnvironmentFile=/etc/environment
ExecStartPre=-/bin/bash -c "until /usr/bin/etcdctl set /coreos.com/network/config '{\"Network\": \"10.100.0.0/16\"}'; do echo \"waiting for etcd to become available...\"; sleep 5; done"
ExecStart=/opt/bin/flannel -iface=${COREOS_PRIVATE_IPV4}
ExecStartPost=-/bin/bash -c "until [ -e /run/flannel/subnet.env ]; do echo \"waiting for write.\"; sleep 3; done"
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

保存并在完成后关闭文件。 在其他主机上创建相同的文件。

创建Docker单元文件

我们将创造下一个文件是不是实际上与我们的可执行文件/opt/bin目录。 我们需要建立一个Docker的服务文件,以便该服务将与知识开始flannel我们刚刚配置的网络覆盖。

使用文本编辑器创建相应的单元文件:

sudo vim docker.service

从常见的元数据开始。 我们需要在这之后开始flannel服务已配置并联机:

[Unit]
Description=Docker container engine configured to run with flannel
Requires=flannel.service
After=flannel.service

对于[Service]部分中,我们需要采购该文件flannel用它来存储它正在创建环境变量。 这将具有当前主机的子网信息。

然后,我们搞垮当前docker0桥接口如果正在运行并删除它。 这允许我们用干净的平板重新启动Docker。 这个过程将配置docker0使用接口flannel联网信息。

我们使用相同的重启和[Install] ,我们一直在使用我们的其他单位的详细信息:

[Unit]
Description=Docker container engine configured to run with flannel
Requires=flannel.service
After=flannel.service

[Service]
EnvironmentFile=/run/flannel/subnet.env
ExecStartPre=-/usr/bin/ip link set dev docker0 down
ExecStartPre=-/usr/sbin/brctl delbr docker0
ExecStart=/usr/bin/docker -d -s=btrfs -H fd:// --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

保存并在完成后关闭文件。 在每个主机上创建此相同的文件。

创建代理单元文件

下一个要讨论的逻辑单元是每个集群成员运行的代理服务器。 Kubernetes代理服务器用于路由和转发流向和来自容器的流量。

使用文本编辑器打开代理单元文件:

sudo vim proxy.service

对于元数据中,我们将需要定义依赖etcd和Docker。 对于[Service]部分,我们只需要启动与本地可执行etcd服务器的地址。 重新启动的配置和安装细节将镜像我们以前的服务文件:

[Unit]
Description=Kubernetes proxy server
After=etcd.service
After=docker.service
Wants=etcd.service
Wants=docker.service

[Service]
ExecStart=/opt/bin/kube-proxy -etcd_servers=http://127.0.0.1:4001 -logtostderr=true
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

完成后保存文件。 在每个主机上创建此相同的文件。

创建Kubelet单元文件

现在,我们将创建Kubelet单元文件。 此组件用于管理容器部署。 它确保容器处于它们应该处于的状态,并且监视系统在部署的期望状态中的变化。

在文本编辑器中创建并打开文件:

sudo vim kubelet.service

元数据部分将包含大约在同一依赖信息etcd和Docker:

[Unit]
Description=Kubernetes Kubelet
After=etcd.service
After=docker.service
Wants=etcd.service
Wants=docker.service

对于[Service]部分,我们不得不再次来源/etc/environment文件,以获得进入主机的私有IP地址。 然后,我们将调用kubelet可执行文件,设置其地址和端口。 我们还覆盖使用相同的私有IP地址和指向该服务到本地主机名etcd实例。 我们提供与我们一直使用的重新启动和安装相同的详细信息:

[Unit]
Description=Kubernetes Kubelet
After=etcd.service
After=docker.service
Wants=etcd.service
Wants=docker.service

[Service]
EnvironmentFile=/etc/environment
ExecStart=/opt/bin/kubelet \
-address=${COREOS_PRIVATE_IPV4} \
-port=10250 \
-hostname_override=${COREOS_PRIVATE_IPV4} \
-etcd_servers=http://127.0.0.1:4001 \
-logtostderr=true
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

保存并在完成后关闭文件。

启用服务

现在您已启动所有服务文件,您可以启用这些单位。 这样做处理中的信息[Install]每个单元的部分。

由于我们的单元表示它们是多用户目标所希望的,这意味着当系统尝试使服务器进入多用户模式时,我们的所有服务将自动启动。

要做到这一点,去你/etc/systemd/system目录:

cd /etc/systemd/system

从这里,我们可以启用所有脚本:

sudo systemctl enable *

这将创建一个multi-user.target.wants符号链接到我们单位文件的目录。 这个目录将被处理systemd朝向引导过程的结束。

在每个服务器上重复此步骤。

现在我们已启用我们的服务,我们可以依次重新启动服务器。

我们将从主服务器开始,但您可以按任何顺序这样做。 虽然没有必要重新启动以启动这些服务,但这样做可确保我们的单元文件的写入方式允许无缝的依赖性链:

sudo reboot

主服务器重新联机后,您可以重新启动您的随从服务器:

sudo reboot

所有服务器都联机后,请确保您的服务正确启动。 您可以通过键入以下内容进行检查:

systemctl status service_name

或者你可以通过键入:

journalctl -b -u service_name

查找服务是否正常启动和运行的指示。 如果有任何问题,重新启动特定服务可能有帮助:

sudo systemctl restart service_name

完成后,您应该能够从主服务器查看机器。 登录到主服务器后,键入以下命令检查所有服务器是否可用:

kubecfg list minions
Minion identifier
----------
10.200.0.1
10.200.0.2
10.200.0.3

在以后的指南中,我们将讨论如何使用Kubernetes来计划和控制您的CoreOS集群上的服务。

结论

您现在应该在您的CoreOS集群中设置Kubernetes。 这为您提供了一个良好的管理和调度接口,用于处理逻辑分组中的服务。

您可能注意到上述步骤导致非常手动的过程。 其中很大一部分是因为我们在我们的机器上构建了二进制文件。 如果您要在可以在私有网络中访问的Web服务器上托管二进制文件,则可以拉下二进制文件并通过创建特殊的cloud-config文件来自动配置它们。

云配置文件具有足够的灵活性,你可以注入的大部分单元文件的不作任何修改(与外apiserver.service文件,这需要对每个节点的IP地址的访问)和启动它们作为CoreOS节点被引导。 这不在本指南的范围之内,但在自动化过程方面是一个很好的下一步。