之前已经写过文章如何在Ubuntu 16.06等使用systemd的系统上面部署Kubernetes,正好使用的是非systemd系统的Ubuntu 14.04部署了一下Kubernetes,按照官方文档遇到了很多问题,总结了一下发出来,希望可以帮助到遇到同样问题的人。

本文主要参考自Kubernetes官方文档《Manually Deploying Kubernetes on Ubuntu Nodes》,但因文档很久没有更新了,部署比较新的版本时会有很多问题,所以这里列一下部署步骤,并说明部署过程中可能遇到的问题及解决方案。

NB:该部署方法只适用于Ubuntu 14.04等使用upstart的系统,不适用于使用Systemd的系统(比如对于Ubuntu,15.04及之后版本)。

假设你有三台服务器,且规划如下:

IP AddressRole
10.10.103.223node
10.10.103.162node
10.10.103.250both master and node

请保证已经安装了docker 1.2+、bridge-utils工具。

1. 部署过程

  1. 设置多台服务器免密登录:

    $ ssh-keygen -t rsa
    $ cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys

    类似上面这样生产密钥信息,并将每台的id_rsa.pub信息加到其它节点的/root/.ssh/authorized_keys。这里使用的是root相互免密登录,如果是其他用户,注意改变目录。更多细节可参考:http://www.path8.net/tn/archives/4473

  2. 下载代码:

    git clone --depth 1 https://github.com/kubernetes/kubernetes.git
  3. 修改配置文件cluster/ubuntu/config-default.sh,如下为需要修改的地方,修改内容请更换为自己的信息:

    export nodes="vcap@10.10.103.250 vcap@10.10.103.162 vcap@10.10.103.223"
    export roles="ai i i"
    export NUM_NODES=${NUM_NODES:-3}
    export SERVICE_CLUSTER_IP_RANGE=192.168.3.0/24
    export FLANNEL_NET=172.16.0.0/16
    • nodes部分填写你机器的用户名及IP信息。
    • roles有三种类型:ai表示既是master,又是node;i表示为node节点。
    • NUM_NODES表示Node节点的个数。
    • SERVICE_CLUSTER_IP_RANGE表示service可用的IP地址范围,如果和你物理机IP不冲突的话,不建议修改默认值。
    • FLANNEL_NET表示flanneld的子网范围,如果和你物理机IP不冲突的话,不建议修改默认值。
  4. 配置完后,在cluster目录执行KUBERNETES_PROVIDER=ubuntu ./kube-up.sh命令,中途会下载很多依赖的东西,请保证网络畅通。如果出现类似下面的打印信息,则表示安装成功:

    ...
    ... calling validate-cluster
    Found 1 node(s).
    NAME            STATUS    AGE
    172.31.12.197   Ready     20s
    Validate output:
    NAME                 STATUS    MESSAGE              ERROR
    controller-manager   Healthy   ok
    scheduler            Healthy   ok
    etcd-0               Healthy   {"health": "true"}
    Cluster validation succeeded
    Done, listing cluster services:
    
    Kubernetes master is running at http://172.31.12.197:8080
    
    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

2. 可能遇到的问题

  1. version文件缺失,报错信息类似下面这样:

    Can't determine Kubernetes release.
    /root/kubernetes/cluster/get-kube-binaries.sh should only be run from a     prebuilt Kubernetes release.
    Did you mean to use get-kube.sh instead?

    该问题见#39224,目前的解决方案是在kubernetes目录下创建version文件,内容为你想安装的Kubernetes版本,比如v1.5.5

  2. /root/kube/util.sh: line 23: /cluster/common.sh: No such file or director

    解决方案:在cluster/ubuntu/util.sh中设置KUBE_ROOT环境变量,值是下载的Kubernetes的目录。

  3. /root/kube/util.sh: line 48: nodes: unbound variable

    解决方案:在cluster/ubuntu/util.sh中执行一下config-default.sh

    source $KUBE_ROOT/cluster/ubuntu/config-default.sh
  4. kube-apiserver一直起不来,报错信息类似:

    The connection to the server 172.31.12.197:8080 was refused - did you specify the right host or port?`

    解决方案:这个原因是因为1.6版本中增加了一些插件支持,但是1.5不支持,见#43693。修改cluster/ubuntu/config-default.sh,删除export ADMISSION_CONTROL=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota里面的DefaultTolerationSeconds

3. kube-up.sh简要分析

这个shell脚本是Kubernetes官方提供了一个部署一个集群的脚本,里面调用了很多其他的脚本,这里不打算细述,主要有三个原因:

  • 极大多数人只是需要使用这个脚本来拉起一个Kubernetes集群,而并不需要关注其中的细节。
  • Kubernetes仍然处于快速的开发中,后续很可能就不会使用这种方法去部署集群了(毕竟个人觉得这种方法不是非常的严谨,而且感觉有点low,不是Google的风格)。目前根据官方的文档来看,该脚本也只适用于在upstart系统上面部署,而对于比较新的使用systemd的Linux系统,需要使用新的部署工具kubeadm
  • shell脚本很简单,都是Linux命令组成的,没什么需要分析的。如果你还看不懂,那就man或者Google,如果还看不懂,那应该去看《Linux从入门到放弃》orz...

但是我们仍然需要对这个部署的过程有一个大概的了解,主要有两个目的:

  • 出了问题时方便定位问题。
  • 如果我们想要修改一些默认的参数值,需要知道去哪里修改。

所以这也是我为什么要对kube-up.sh进行简要分析的原因。虽然kube-up.sh引用了一大堆其他脚本和函数,但其实如果你对于Kubernetes的组成非常清楚,特别是如果你读过我之前《手动部署Kubernetes》系列的文章:

那你看这个脚本时就会非常清楚,其实这个脚本就是把手动执行的东西都自动化了,不过是基于upstart系统而已。好吧,说了这么多废话,现在开始简要分析吧。

kube-up.sh支持在多种平台部署Kubernetes,这里以Ubuntu为例。我们在cluster目录执行KUBERNETES_PROVIDER=ubuntu ./kube-up.sh命令后,kube-up.sh知道是在Ubuntu系统上面部署,就会使用cluster/ubuntu目录下的脚本。如果是其他平台的,就会执行其他平台下面的脚本,不过结构基本是类似的。

首先涉及的就是download-release.sh这个脚本,kube-up.sh首先会检查依赖的包是否有下载下来,如果没有,就会进行下载,而具体下载过程就是这个脚本控制的。如果这个脚本里面写的地址因为一些不可抗拒的原因无法下载,你可以通过其他方式下载下来,然后修改一下脚本,注释掉下载的部分,直接使用你下载好的,或者直接将脚本里面下载地址换为其他你可以访问的地址。对于中国用户,这个往往非常重要。

其次要分析的就是config-default.sh这个脚本,其实这个是集群的配置文件,包括大部分Kubernetes进程(master的四个进程和node的两个进程以及flanneld等)的配置,所以,如果我们想要更改集群默认的配置,首先就在这个文件里面找,看是否有相关的选项。比如kube-apiserver的启动参数、kubelet的启动参数、flanneld的子网配置等都在这个文件里面。

再次要分析的就是utils.sh脚本,这个脚本里面基本上都是函数,kube-up.sh及其它脚本调用的函数基本上都是在这里定义的。这些函数主要是生成集群的配置文件,检查集群的状态等。这个脚本里面也有一部分集群的配置,如果在config-default.sh脚本里面找不到的配置,可以在这个脚本里面找一下,或者直接在这个脚本的具体函数里面添加。该脚本生成的各进程的配置文件在/etc/default/目录下面。

最后再提一下reconfDocker.sh这个脚本,这个脚本主要是负责配置docker,其实做的事情就是《Ubuntu16.04手动部署Kubernetes(2)——Flannel网络部署》讲的操作。

几个比较重要的脚本介绍完毕后,最后再介绍一个需要注意的点:Kubernetes提供了kube-up.sh来拉起一个集群,提供了kube-down.sh来关闭一个集群。我们需要清楚哪些文件是在在执行kube-up.sh时拷贝到某个目录,然后执行kube-down.sh时被删除。需要知道这个的原因是我们做一些自定义的修改时就知道在哪里修改不会被下次的kube-up.sh覆盖。这里列几个:

  • /root/kube:该目录下的文件是执行kube-up.sh时从cluster/ubuntu下面拷贝过去的,每执行一次就会拷贝一次,且执行kube-down.sh时会被删除,所以如果需要修改这个下面的内容,一定要去修改cluster/ubuntu下的脚本,然后重新执行kube-up.sh
  • /opt/bin:默认所有进程文件都会安装到这个目录下,是从cluster/ubuntu/binaries/目录下拷贝过去的。
  • /etc/default:所有Kubernetes进程的启动参数配置文件都在这个目录下,是utils.sh脚本执行时生成到这里的,如果更改了这里的文件,不能通过执行kube-up.sh使其生效,而应该改了哪个进程,就执行service xxx restart来使其生效。

最后,Kubernetes开发速度很快,部署对很多不熟悉Kubernetes的人一直是个头疼的问题,特别是不同的Linux发行版部署方法还不太一样。所以遇到问题多Google,或者直接去Github上面搜索或者提issue,很多问题其实别人可能已经问过了,且有解决方案了。个人推荐最好可以手动部署一套,部署的过程也就是学习Kubernetes的过程,而且这样部署一遍后,其他的任何方案都只是对这种最原始部署方案的封装而已。