本文主要讲Kubernetes的一种原始部署方式。Kubernetes从开发至今,其部署方式已经变得越来越简单。常见的有三种:
a. 最简单的就是使用Minikube方式。下载一个二进制文件即可拥有一个单机版的Kubernetes,而且支持各个平台。
b. 从源码安装。这种方式也是简单的进行一些配置,然后执行kube-up.sh
就可以部署一个Kubernetes集群。可参见官方文档《Manually Deploying Kubernetes on Ubuntu Nodes》。PS:目前,该文档部署Kubernetes 1.5.3版本会有些问题。
c. 通过kubeadm部署。可参见官方文档《Installing Kubernetes on Linux with kubeadm》
其实,除了上面三种方式外,有些Linux发行版已经提供了Kubernetes的安装包,比如在CentOS 7上面,直接执行yum install -y etcd kubernetes
即可安装Kubernetes,然后做些配置就可以完成部署了。我相信对于Google这种追求自动化、智能化的公司,他们会让Kubernetes部署方式还会更加简化。但这些都不是本文的重点,本文要讲述的是如何像堆积木一样一个模块一个模块的部署Kubernetes。为什么要这样做?
为了更好的理解学习Kubernetes。现在简单化的部署方式屏蔽了很多细节,使得我们对于各个模块的感知少了很多。而且很容器觉得Kubernetes的内部部署细节非常的麻烦或者复杂,但其实并非如此,其实Kubernetes集群就是由为数不多的几个二进制文件组成,部署一个基本的集群也非难事。因为是使用Go开发的,这些二进制文件也没有任何依赖,从别的地方拷贝过来就可使用。本文就介绍如何从这些二进制文件搭建一个Kubernetes集群, 以加深对Kubernetes的理解。而且,其他部署方式其实也只是对这种方式的一种封装。
现在Systemd逐渐替代了Upstart,有的部署方式也只支持Systemd的Linux发行版,如果是Upstart,还得做适配。至于什么是Systemd和Upstart,不是本文要讨论的,后续会总结发出来。这里我使用的Linux发行版是Ubuntu 16.04。当然Ubuntu 15.04+的都使用的是Systemd,应该都是适用的,其他使用Systemd的系统应该也是适用的,但可能需要做些小的改动。另外,前文介绍了Kubernetes集群分为Master和Node,所以我们部署也一样,分为Master的部署和Node的部署。
我的环境是用Virtualbox虚拟了两台Ubuntu 16.04,虚拟机和主机的通信方式是NAT和host-only方式。NAT用于访问外网,host-only用于两台虚拟机之间访问,IP分别为192.168.67.133和192.168.67.134.其中133这台机器机器既是Master,又是Node;134是Node。本文只装了133,后面再测试网络等需要多台的时候再安装134.因为Kubernetes里面Node是主动向Master注册的(通过Node上面的kubelet),所以要扩展Node的话也非常容易。
Kubernetes集群内主要包含这些模块:Master中:APIServer、scheduler、controller manager、etcd;Node中:kubelet、kube-proxy、runtime(这里指Docker)。
上面每个模块都由一个二进制文件实现,所以我们需要上面每个模块对应的那个二进制文件。获取方式有很多。最直观的方式就是去github上面下载release的包,里面有二进制文件。但那个包有1GB+大小,特别对于中国用户就呵呵了,当然还有许多其他获取的方式。这里我说一个地方,在Kubernetes源码的kubernetes/cluster/ubuntu
目录下有master和minion目录,下面的init_scripts
里面就有Master和Node上面需要的二进制文件。另外,你也可以使用如下命令下载kubernetes-server-linux-amd64.tar.gz
包:
wget -c https://github.com/kubernetes/kubernetes/releases/download/v1.5.2/kubernetes.tar.gz
tar -zxvf 解压kubernetes.tar.gz文件后在kubernetes/server
目录中找到kubernetes-server-linux-amd64.tar.gz
将其解压,这个包解压后的kubernetes/server/bin
目录下就有我们需要的二进制文件,我将这些二进制文件都放到了/opt/bin
目录下,并且将该目录加到了PATH中(vi /etc/environment
)。你也可以直接将这些文件放到系统的PATH路径中,比如/usr/bin
。OK,有了这些二进制文件,我们就可以开始部署了。
1、部署Master
前文介绍过,Master上面主要四个模块:APIServer、scheduler、controller manager、etcd,我们一一来部署。
部署etcd
我建议直接使用apt install etcd
命令去安装,这样同时也会安装etcdctl。安装完后etcd的数据默认存储在/var/lib/etcd/default
目录,默认配置文件为/etc/default/etcd
,可通过/lib/systemd/system/etcd.service
文件进行修改。
安装好以后,执行以下命令:
systemctl enable etcd.service # 将etcd加到开机启动列表中
systemctl start etcd.service # 启动etcd
安装好以后,etcd默认监听http://127.0.0.1:2379地址供客户端连接。我们可以使用etcdctl来检查etcd是否正确启动:
ubuntu➜ bin etcdctl cluster-health
member ce2a822cea30bfca is healthy: got healthy result from http://localhost:2379
cluster is healthy
可以看到运行正常。当然,部署多台的话,因为所有Node都需要访问etcd,所以etcd必须要监听在其他Node可以访问的IP上面才可以,在/etc/default/etcd
中增加以下两行:
ETCD_LISTEN_CLIENT_URLS=”http://0.0.0.0:2379”
ETCD_ADVERTISE_CLIENT_URLS=”http://0.0.0.0:2379”
重启etcd即可使etcd在所有IP上起监听。
部署APIServer
APIServer对应的二进制文件是kube-apiserver
,我们先来设置systemd服务文件/lib/systemd/system/kube-apiserver.service
:
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes
After=etcd.service
Wants=etcd.service[Service]
EnvironmentFile=/etc/kubernetes/apiserver
ExecStart=/opt/bin/kube-apiserver $KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
重点项简单说明:
kube-apiserver服务依赖etcd,所以设置了After。
EnvironmentFile是该服务的配置文件。
ExecStart说明如何启动该服务。
我们看到kube-apiserver的启动参数为$KUBE_API_ARGS,我们在配置文件/etc/kubernetes/apiserver中定义这个环境变量:
KUBE_API_ARGS=”–etcd_servers=http://127.0.0.1:2379 –insecure-bind-address=0.0.0.0 –insecure-port=8080 –service-cluster-ip-range=169.169.0.0/16 –service-node-port-range=1-65535 –admission_control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ResourceQuota –logtostderr=false –log-dir=/var/log/kubernetes –v=2”
选项说明:
--etcd_servers:就是etcd的地址。
--insecure-bind-address:apiserver绑定主机的非安全IP地址,设置0.0.0.0表示绑定所有IP地址。
--insecure-port:apiserver绑定主机的非安全端口,默认为8080。
--service-cluster-ip-range:Kubernetes集群中Service的虚拟IP地址段范围,以CIDR格式表示,该IP范围不能与物理机真实IP段有重合。
-service-node-port-range:Kubernetes集群中Service可映射的物理机端口范围,默认为30000~32767.
--admission_control: Kubernetes集群的准入控制设置,各控制模块以插件形式依次生效。
--logtostderr:设置为false表示将日志写入文件,不写入stderr。
--log-dir: 日志目录。
--v:日志级别。
OK,APIServer的部署配置完成了。后面其他模块的配置与之大同小异。
部署controller manager
controller manager对应的二进制文件是kube-controller-manager
,且该服务依赖于kube-apiserver。
依旧先配置systemd的服务文件/lib/systemd/system/kube-controller-manager.service
:
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes
After=kube-apiserver.service
Requires=kube-apiserver.service[Service]
EnvironmentFile=/etc/kubernetes/controller-manager
ExecStart=/opt/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
在/etc/kubernetes/controller-manager
中设置$KUBE_CONTROLLER_MANAGER_ARGS
:
KUBE_CONTROLLER_MANAGER_ARGS=”–master=http://192.168.67.133:8080 –logtostderr=false –log-dir=/var/log/kubernetes –v=2”
–master指的是APIServer的地址。
部署scheduler
scheduler对应的二进制文件是kube-scheduler
,scheduler依赖于APIServer。
配置systemd服务文件/lib/systemd/system/kube-scheduler.service
:
[Unit]
Description=Kubernetes Scheduler Manager
Documentation=https://github.com/kubernetes
After=kube-apiserver.service
Requires=kube-apiserver.service[Service]
EnvironmentFile=/etc/kubernetes/scheduler
ExecStart=/opt/bin/kube-scheduler $KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
在配置文件/etc/kubernetes/scheduler
中设置$KUBE_SCHEDULER_ARGS
:
KUBE_SCHEDULER_ARGS=”–master=http://192.168.67.133:8080 –logtostderr=false –log-dir=/var/log/kubernetes –v=2”
至此,Master上面的四个模块都部署完了,我们按照顺序启动他们,并将其加入到开机自启动选项中:
//重新加载systemd配置管理,切记增加*.service后一定要先执行该命令,否则启动服务时会报错
systemctl daemon-reload
// enable表示该服务开机自启,start表示启动该服务
systemctl enable kube-apiserver.service
systemctl start kube-apiserver.service
systemctl enable kube-controller-manager.service
systemctl start kube-controller-manager.service
systemctl enable kube-scheduler.service
systemctl start kube-scheduler.service
然后我们分别运行systemctl status <service_name>
来验证服务的状态,“running”表示启动成功。如果未成,也可看到错误日志。
部署Node
Node上面运行三个模块:kubelet、kube-proxy、runtime。其中runtime目前指的是docker或者rkt,这里我们使用docker,docker的安装这里就不赘述了,最好安装最新版本的docker。
部署kubelet
kubelet对应的二进制文件是kubelet
,且其依赖Docker服务。
配置systemd服务文件/lib/systemd/system/kubelet.service
:
[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://github.com/kubernetes
After=docker.service
Requires=docker.service[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=/etc/kubernetes/kubelet
ExecStart=/opt/bin/kubelet $KUBELET_ARGS
Restart=on-failure[Install]
WantedBy=multi-user.target
在配置文件/etc/kubernetes/kubelet
中设置参数$KUBELET_ARGS
KUBELET_ARGS=”–api-servers=http://192.168.67.133:8080 –hostname-override=192.168.56.101 –logtostderr=false –log-dir=/var/log/kubernetes –v=2”
其中--hostname-override
设置本Node的名称。
部署kube-proxy
kube-proxy对应的二进制文件为kube-proxy
,且该服务依赖于network服务。
配置systemd服务文件/lib/systemd/system/kube-proxy.service
:
[Unit]
Description=Kubernetes Kube-Proxt Server
Documentation=https://github.com/kubernetes
After=network.target
Requires=network.target[Service]
EnvironmentFile=/etc/kubernetes/proxy
ExecStart=/opt/bin/kube-proxy $KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
在配置文件/etc/kubernetes/proxy
中设置参数$KUBE_PROXY_ARGS
KUBE_PROXY_ARGS=”–master=http://192.168.67.133:8080 –logtostderr=false –log-dir=/var/log/kubernetes –v=2”
然后我们依次启动Node上的服务(Docker安装好以后默认开机自启且已经启动,这里不再启动):
systemctl daemon-reload
systemctl enable kubelet.service
systemctl start kubelet.service
systemctl enable kube-proxy.service
systemctl start kube-proxy.service
待服务都成功启动后,kubelet会主动向Master注册自己所在的Node。如果所有服务都启动成功,我们就可以看到可用的Node了:
ubuntu➜ system kubectl get node
NAME | STATUS | AGE
192.168.67.133 | Ready | 1h
再在另外一台Node上面也部署一下,就可以看到两个节点了。
至此,本文就介绍完了。不过要应用到生产环境中,我们还有一些安全项和网络项需要配置,后面再介绍。