以前在《Kubernetes初体验》中咱们使用Minikube快速体验了一把Kubernetes,而后在《Kubernetes架构及资源关系简单总结》一文中咱们又简单介绍了Kubernetes的框架以及Kubernetes中的一些关键术语和概念,或者称之为资源、对象。本文主要讲Kubernetes的一种原始部署方式。Kubernetes从开发至今,其部署方式已经变得愈来愈简单。常见的有三种:html
kube-up.sh
就能够部署一个Kubernetes集群。可参见官方文档《Manually Deploying Kubernetes on Ubuntu Nodes》。PS:目前,该文档部署Kubernetes 1.5.3版本会有些问题,可关注#39224。其实,除了上面三种方式外,有些Linux发行版已经提供了Kubernetes的安装包,好比在CentOS 7上面,直接执行yum install -y etcd kubernetes
便可安装Kubernetes,而后作些配置就能够完成部署了。我相信对于Google这种追求自动化、智能化的公司,他们会让Kubernetes部署方式还会更加简化。但这些都不是本文的重点,本文要讲述的是如何像堆积木同样一个模块一个模块的部署Kubernetes。为何要这样作?node
为了更好的理解学习Kubernetes。前面咱们已经简单介绍过Kubernetes的架构,知道它实际上是由几大模块组成,各个模块间合做构成一个集群。如今简单化的部署方式屏蔽了不少细节,使得咱们对于各个模块的感知少了不少。并且很容器以为Kubernetes的内部部署细节很是的麻烦或者复杂,但其实并不是如此,其实Kubernetes集群就是由为数很少的几个二进制文件组成,部署一个基本的集群也非难事。由于是使用Go开发的,这些二进制文件也没有任何依赖,从别的地方拷贝过来就可以使用。本文就介绍如何从这些二进制文件搭建一个Kubernetes集群, 以加深对Kubernetes的理解。并且,其余部署方式其实也只是对这种方式的一种封装。linux
如今Systemd逐渐替代了Upstart,有的部署方式也只支持Systemd的Linux发行版,若是是Upstart,还得作适配。至于什么是Systemd和Upstart,不是本文要讨论的,后续会总结发出来。这里我使用的Linux发行版是Ubuntu 16.04。固然Ubuntu 15.04+的都使用的是Systemd,应该都是适用的,其余使用Systemd的系统应该也是适用的,但可能须要作些小的改动。另外,前文介绍了Kubernetes集群分为Master和Node,因此咱们部署也同样,分为Master的部署和Node的部署。git
个人环境是用Virtualbox虚拟了两台Ubuntu 16.04,虚拟机和主机的通讯方式是NAT和host-only方式。NAT用于访问外网,host-only用于两台虚拟机之间访问,IP分别为192.168.56.101和192.168.56.102.其中101这台机器机器既是Master,又是Node;102是Node。本文只装了101,后面再测试网络等须要多台的时候再安装102.由于Kubernetes里面Node是主动向Master注册的(经过Node上面的kubelet),因此要扩展Node的话也很是容易。github
咱们都须要哪些二进制文件呢?回想一下《Kubernetes架构及资源关系简单总结》中,Kubernetes集群内主要包含这些模块:Master中:APIServer、scheduler、controller manager、etcd;Node中:kubelet、kube-proxy、runtime(这里指Docker)。docker
上面每一个模块都由一个二进制文件实现,因此咱们须要上面每一个模块对应的那个二进制文件。获取方式有不少。最直观的方式就是去github上面下载release的包,里面有二进制文件。但那个包有1GB+大小,特别对于中国用户就呵呵了,固然还有许多其余获取的方式。shell
注意:源代码目录里面也有不少名字和二进制名字相同的文件,但那些不是二进制文件,而是一些去掉后缀的shell脚步,都只有KB级别的大小,而真正的二进制文件都是MB级别的,注意别搞错了。ubuntu
推荐使用下面的命令下载kubernetes-server-linux-amd64.tar.gz
包:api
curl -L https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/kubernetes-server-linux-amd64.tar.gz -o kubernetes-server-linux-amd64.tar.gz
这个包解压后的kubernetes/server/bin
目录下就有咱们须要的二进制文件(只使用了其中6个):安全
Bash
ubuntu➜ bin ll total 1.3G -rwxr-x--- 1 root root 145M Dec 14 09:06 hyperkube -rwxr-x--- 1 root root 118M Dec 14 09:06 kube-apiserver -rw-r----- 1 root root 33 Dec 14 09:06 kube-apiserver.docker_tag -rw-r----- 1 root root 119M Dec 14 09:06 kube-apiserver.tar -rwxr-x--- 1 root root 97M Dec 14 09:06 kube-controller-manager -rw-r----- 1 root root 33 Dec 14 09:06 kube-controller-manager.docker_tag -rw-r----- 1 root root 98M Dec 14 09:06 kube-controller-manager.tar -rwxr-x--- 1 root root 6.6M Dec 14 09:06 kube-discovery -rwxr-x--- 1 root root 44M Dec 14 09:05 kube-dns -rwxr-x--- 1 root root 44M Dec 14 09:05 kube-proxy -rw-r----- 1 root root 33 Dec 14 09:06 kube-proxy.docker_tag -rw-r----- 1 root root 174M Dec 14 09:06 kube-proxy.tar -rwxr-x--- 1 root root 51M Dec 14 09:06 kube-scheduler -rw-r----- 1 root root 33 Dec 14 09:06 kube-scheduler.docker_tag -rw-r----- 1 root root 52M Dec 14 09:06 kube-scheduler.tar -rwxr-x--- 1 root root 91M Dec 14 09:06 kubeadm -rwxr-x--- 1 root root 49M Dec 14 09:06 kubectl -rwxr-x--- 1 root root 46M Dec 14 09:06 kubefed -rwxr-x--- 1 root root 103M Dec 14 09:06 kubelet
我将这些二进制文件都放到了/opt/bin
目录下,而且将该目录加到了PATH中。你也能够直接将这些文件放到系统的PATH路径中,好比/usr/bin
。
OK,有了这些二进制文件,咱们就能够开始部署了。
前文介绍过,Master上面主要四个模块:APIServer、scheduler、controller manager、etcd,咱们一一来部署。
我建议直接使用apt install etcd
命令去安装,这样同时也会安装etcdctl。安装完后etcd的数据默认存储在/var/lib/etcd/default
目录,默认配置文件为/etc/default/etcd
,可经过/lib/systemd/system/etcd.service
文件进行修改。
Kubernets新版本(我记得好像是1.6开始吧,记不清了)已经不支持etcd 2.x版本了,可是在Ubuntu 16.04上面经过apt install
装的是2.2版本,这样会致使api-server没法和etcd通信,而致使一些问题,因此建议从github下载最新etcd 3.x(https://github.com/coreos/etcd/releases),而后手动安装。建立/lib/systemd/system/etcd.service
文件:
[Unit] Description=Etcd Server Documentation=https://github.com/coreos/etcd After=network.target [Service] User=root Type=simple EnvironmentFile=-/etc/default/etcd ExecStart=/opt/k8s/v1_6_9/etcd-v3.2.7-linux-amd64/etcd # 改成你本身路径 Restart=on-failure RestartSec=10s LimitNOFILE=40000 [Install] WantedBy=multi-user.target
安装好之后,执行如下命令:
Bash
# 从新加载systemd配置管理,切记增长`*.service`后必定要先执行该命令,不然启动服务时会报错 systemctl daemon-reload systemctl enable etcd.service # 将etcd加到开机启动列表中 systemctl start etcd.service # 启动etcd
安装好之后,etcd默认监听http://127.0.0.1:2379
地址供客户端链接。咱们可使用etcdctl
来检查etcd是否正确启动:
Bash
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对应的二进制文件是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
重点项简单说明:
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对应的二进制文件是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.56.101:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
--master
指的是APIServer的地址。
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.56.101: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上面运行三个模块:kubelet、kube-proxy、runtime。其中runtime目前指的是docker或者rkt,这里咱们使用docker,docker的安装这里就不赘述了,最好安装最新版本的docker。
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.56.101:8080 --hostname-override=192.168.56.101 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
其中--hostname-override
设置本Node的名称。
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.56.101: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.56.101 Ready 1h
再在另一台Node上面也部署一下,就能够看到两个节点了。
至此,本文就介绍完了。不过要应用到生产环境中,咱们还有一些安全项和网络项须要配置,后面再介绍。