1 概述

k8s的部署常见的工具和环境:

1,IaaS(虚拟机):

     1.1托管模型,部署在公有云上,K8SaaS,目前没有用于生产环境

     1.2VPS,和本地物理机搭建一样,但是这里网络是虚拟网络了

2,物理机:

     3.1 构建工具 Rancher 2.0

     3.2 OpenShift(PaaS),红帽的官方发行版,在这个版本里有k8s相关的包

     还有很多工具可以实现

3,kubeadm部署

4,借助于工具kubespray,kopts部署

5,ansible,基于roles实现部署

k8s的两种部署方式

1.kubeadm方式部署,k8s可以把k8s自身的大部分应用管控起来,即运行于pod上,但是kubelet和docker不能这样实现自托管,这两个主机运行为守护进程,因此,只需要在所有主机都安装kubelet和docker,构建k8s集群。相当于是自举。etcd也是托管于pod上运行,使用kubeadm进行部署,安装过程相对简单。这些主件的pod一般为静态pod(不属于k8s管理),也可以运行为自托管的pod.每个主机都要运行flannel这个主件,可以运行为pod。flannel为动态pod

kubeadm的介绍可以查看如下链接

https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.md

通过kubeadm init 完成集群master节点的初始化,用kubeadm join加入集群

2:手动配置,主节点和node都主要组件运行为系统级的守护进程,每一步都需要手动处理,如证书和配置过程都是用手动配置的。另外,这种方式在github上有playbook自动化实现

    a).master:安装apiserver,scheduler,controller-manager,etcd,flanel

    b).node:安装kublet,kub-proxy,docker(container engine),flannel,需要多个节点

    c).etcd:安装etcd存储服务器,建议配置为高可用

这种方式,可以到https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md#downloads-for-v1112下载相关的安装包,注意,master或者node都是要安装server端的包。client是交互时使用,也需要安装,不建议使用这种方式安装,难度较高

本文仅介绍使用kubeadm实现k8s集群安装

2 集群安装

最关键,服务器的资源至少为2G内存,否则初始化k8s会报错

默认情况下,会到google托管的站点下载所有的镜像

使用kubeadm安装,默认网络如下:

pod的默认ip 为 10.244.0.0/16

service的默认ip  10.92.0.0/12

节点网络为:172.20.0.0/16

docker要和k8s结合使用,首先要先通过k8s认证,否则会报警。目前k8s只认证到17.03.02之前的版本

准备三台主机,分别安装docker和kubelet,其他服务都是通过自托管实现

安装步骤如下三步

1.master和node 安装 kubelet,kubeadm,docker

2.mster:kubeadm init

3.nodes:kubeadm join

第2和3步,相关步骤查看https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.md

所有服务器需要安装docker-ce,kubeadm,kubelet,kubectl这四个包

2.1 环境准备

关闭防火墙,selinux,基于主机名访问(dns或者dns),同步时间(时间不一致,集群运行异常,如不能启动),关闭swap分区

三台主机的hosts文件如下

vim /etc/hosts
10.10.10.74 server74
10.10.10.75 server75
10.10.10.76 server76

所有的主机,内存至少2G以上

关闭swap分区

swapoff -a

关闭防火墙

systemctl stop firewalld
systemctl disable firewalld


使用时间服务器同步所有的k8s集群服务器,防止出现异常,centos7使用chrony来同步时间

2.2 安装docker-ce

使用清华或者阿里云的镜像源

wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo


安装命令

yum -y install docker-ce

配置docker镜像加速

mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
 "registry-mirrors": ["https://eyg9yi6d.mirror.aliyuncs.com"]
}


阿里云上有大量的镜像,所以建议使用阿里云进行加速

由于k8s安装有很多镜像国内下载不到,因为编辑如下的配置文件可以找到需要的镜像,启动docker前,在Service配置段里定义环境变量,Environment,表示通过这个代理去加载k8s所需的镜像,加载完成后,可以注释掉,仅使用国内的加速器来拉取非k8s的镜像,后续需要使用时,再开启。

#以下的NO_PROXY表示对这些网段的服务器不使用代理,如果不需要用到代理服务器,以下的配置可以不写,注意,以下的代理是不通的。不建议使用代理,因为国内有资源可以访问到gcr.io需要的镜像,下文会介绍
vim /usr/lib/systemd/system/docker.service
Environment="HTTPS_PROXY=http://www.ik8s.io:10080"
Environment="HTTP_PROXY=http://www.ik8s.io:10080"
Environment="NO_PROXY=127.0.0.0/8,172.20.0.0/16"
#保存退出后,执行
systemctl  daemon-reload
#确保如下两个参数值为1,默认为1。
 cat /proc/sys/net/bridge/bridge-nf-call-ip6tables
 cat /proc/sys/net/bridge/bridge-nf-call-iptables
#启动docker-ce
systemctl start docker
#设置开机启动
systemctl enable docker.service


2.3 k8s集群master节点安装

k8s集群节点都要安装kubeadm,kubelet,kubectl

使用kubeadm官方文档:https://kubernetes.io/docs/setup/independent/install-kubeadm/

官方的k8s包仓库为https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86-64,这个站点国内目前打不开,建议使用国内具有k8s包的站点,这里建议使用阿里云站点

https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/

编辑k8s仓库源文件

vim k8s.repo
[k8s]
name=aliyun_k8s
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
#这里,如果要使用key认证,配置如下
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
#保存退出后,需要下载key然后导入
wget  https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
wget https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
rpm --import yum-key.gpg
rpm --import rpm-package-key.gpg

然后再安装即可

安装软件

yum -y install kubeadm kubelet kubectl

当前,这边安装的版本为1.11.2

安装k8s集群,kubeadm会读取/etc/systemd/system/kubelet.service.d/10-kubeadm.conf文件的配置信息,更改cgroup的驱动,这里的驱动要要docker一致,因此用docker info| grep Cgroup命令查看docker的驱动类型,如这里查到的结果为 cgroupfs.因此修改kubeadm的配置文件如下

vim  /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

#添加如下配置

Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"

启动kubelet

systemctl start kubelet

注意,此时启动会出现报错,查看/var/log/messages的日志

tail -f /var/log/messages

如果出现如下的报错

failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file "/var/lib/kubelet/config.yaml", error: open /var/lib/kubelet/config.yaml: no such file or directory

忽略以上的报错,设置为开机自启动即可,因为此时的配置还没初始化完成,所以此时不能启动kubelet,等后续kubeadm启动成功后再查看

设置开机启动

systemctl enable kubelet.service

初始化kubeadm

查看kubeadm相关的参数

 kubeadm init --help

#注意,需要关闭swap分区,或者在如下的配置文件里修改,表示添加而且的启动选项
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=false"

建议执行 swapoff -a 关闭swap分区,不用配置上述选项

开始初始化

kubeadm init --kubernetes-version=v1.11.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12

初始化过程的报错

/var/log/messages日志出现如下的报错,很有可能是服务器的资源,尤其是内存太小,导致节点启动不成功

eviction_manager.go:243] eviction manager: failed to get get summary stats: failed to get node info: node "server74" not found

添加内存资源,centos7建议最后为2G内存

只有遇到如下的日志,k8s才是安装成功

Successfully registered node server74

镜像加载注意事项

初始化过程,默认会到gcr.io/google_containers站点拉取相关k8s的镜像信息,当前国内不能进行这些站点的访问,如果网络不能访问google,则会出现镜像录取失败的报错

https://console.cloud.google.com/gcr/images/google-containers?project=google-containers

v1.11.2版本初始化需要的镜像如下

k8s.gcr.io/kube-apiserver-amd64:v1.11.2

k8s.gcr.io/kube-controller-manager-amd64:v1.11.2

k8s.gcr.io/kube-scheduler-amd64:v1.11.2

k8s.gcr.io/kube-proxy-amd64:v1.11.2

k8s.gcr.io/pause:3.1

k8s.gcr.io/etcd-amd64:3.2.18

k8s.gcr.io/coredns:1.1.3

有个技术大牛把gcr.io的镜像每天同步到https://github.com/anjia0532/gcr.io_mirror这个站点,因此,如果需要用到gcr.io的镜像,可以执行如下的脚本进行镜像拉取

执行如下的脚步进行安装

vim pullimages.sh
#!/bin/bash
images=(kube-proxy-amd64:v1.11.2 kube-scheduler-amd64:v1.11.2 kube-controller-manager-amd64:v1.11.2 kube-apiserver-amd64:v1.11.2
etcd-amd64:3.2.18 coredns:1.1.3 pause:3.1 )
for imageName in ${images[@]} ; do
docker pull anjia0532/google-containers.$imageName
docker tag anjia0532/google-containers.$imageName k8s.gcr.io/$imageName
docker rmi anjia0532/google-containers.$imageName
done

镜像拉取成功后再重新执行init命令

初始化命令执行成功后,执行如下的命令,启动集群

[root@server76 ~]# mkdir -p $HOME/.kube
[root@server76 ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@server76 ~]# chown $(id -u):$(id -g) $HOME/.kube/config
[root@server76 ~]#


获取组件的健康状态

[root@server76 ~]# kubectl get cs
NAME                 STATUS    MESSAGE              ERROR
controller-manager   Healthy   ok                   
scheduler            Healthy   ok                   
etcd-0               Healthy   {"health": "true"}

 

查看节点信息

root@server76 ~]# kubectl get nodes
NAME       STATUS     ROLES     AGE       VERSION
server76   NotReady   master    16m       v1.11.2

这里status未就绪,是因为没有网络插件,如flannel.地址https://github.com/coreos/flannel可以查看flannel在github上的相关项目,执行如下的命令自动安装flannel

[root@server76 ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created
[root@server76 ~]#


执行完上述命令后,会拉取flannel的镜像,可用docker image ls查看flannel镜像是否成功拉取,如quay.io/coreos/flannel :v0.10.0-amd64

镜像拉取成功后,一般会把启动起来。此时默认的node状态为Ready,如下

[root@server76 docker]# kubectl get nodes
NAME       STATUS    ROLES     AGE       VERSION
server76   Ready     master    33m       v1.11.2
[root@server76 docker]#


执行如下的命令,获取当前系统上所有在运行的pod的状态,指定名称空间为kube-system,为系统级的pod,命令如下

[root@server76 docker]# kubectl get pods -n kube-system
NAME                               READY     STATUS    RESTARTS   AGE
coredns-78fcdf6894-mbs8h           1/1       Running   0          35m
coredns-78fcdf6894-twkj6           1/1       Running   0          35m
etcd-server76                      1/1       Running   1          34m
kube-apiserver-server76            1/1       Running   1          34m
kube-controller-manager-server76   1/1       Running   1          34m
kube-flannel-ds-amd64-f8mf2        1/1       Running   0          13m
kube-proxy-vpb6x                   1/1       Running   1          35m
kube-scheduler-server76            1/1       Running   1          34m
[root@server76 docker]#


执行如下命令,获取当前系统的名称空间

[root@server76 docker]# kubectl get ns
NAME          STATUS    AGE
default       Active    36m
kube-public   Active    36m
kube-system   Active    36m
[root@server76 docker]#
2.4 node节点操作

yum仓库准备好后,在以下的两个节点上执行安装如下包,

yum -y install kubeadm kubelet kubectl docker-ce

关闭swap

swapoff -a

开启转发的参数,根据实际报错情况开启,一般有如下三项


echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables


安装完成后

启动docker-ce

systemctl start docker

注意,kubelet此时不启动,因为缺配置文件,启动也会报错,所以不启动

设置开机启动,必须的操作

systemctl enable docker.service
systemctl enable kubelet.service

把配置文件拷贝到要加入该master节点的node上,保持配置一致。不是必须,建议操作

[root@server76 ~]# for i in 74 75;do scp /usr/lib/systemd/system/docker.service  server$i:/usr/lib/systemd/system/;done
[root@server76 ~]# for i in 74 75;do scp /etc/sysconfig/kubelet server$i:/etc/sysconfig/;done

在server74 和 75 节点上,要执行如下的命令,加入master节点,注意,如下命令token和discovery-token-ca-cert-hash是随机生成,可以用命令查找,比较麻烦,建议安装成功后,在成功的信息中,如下的命令需要保存,后期方便加入主节点。

  kubeadm join 192.168.137.134:6443 --token wbg1tk.dwg75846yjjsa22f --discovery-token-ca-cert-hash sha256:29e3babf8235abfff5bb522bdb0fa5ab068d31ed3221f18999f3c5cfc8527488

在node上执行上述命令成功后,信息如下

This node has joined the cluster:
* Certificate signing request was sent to master and a response
  was received.
* The Kubelet was informed of the new secure connection details.
 
Run 'kubectl get nodes' on the master to see this node join the cluster.

注意,可以忽略如下的报错,只要看到以上成功的信息即表搭建成功

[root@server75 ~]#  kubeadm join 192.168.137.134:6443 --token wbg1tk.dwg75846yjjsa22f --discovery-token-ca-cert-hash sha256:29e3babf8235abfff5bb522bdb0fa5ab068d31ed3221f18999f3c5cfc8527488
[preflight] running pre-flight checks
[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs_rr ip_vs_wrr ip_vs_sh ip_vs] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}]
you can solve this problem with following methods:
 1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support

到这里从节点配置完成

2.5 验证

上述命令执行完成后,从节点同样需要到互联网上拉取flannel的镜像,并启动,因此需要一点时间,用docker images 查看是否成功拉取flannel镜像到本地,等flannel拉取成功启动后,在master上可以看到node的状态为Ready.

需要在主节点上执行如下的命令,查看node的信息

[root@server76 docker]# kubectl get nodes
NAME       STATUS    ROLES     AGE       VERSION
server74   Ready     <none>    6m        v1.11.2
server76   Ready     master    1h        v1.11.2

需要查看pod的详细信息,则添加选项-o wide

[root@server76 docker]# kubectl get pods -n kube-system -o wide
NAME                               READY     STATUS    RESTARTS   AGE       IP            NODE       NOMINATED NODE
coredns-78fcdf6894-mbs8h           1/1       Running   0          1h        10.244.0.2    server76   <none>
coredns-78fcdf6894-twkj6           1/1       Running   0          1h        10.244.0.3    server76   <none>
etcd-server76                      1/1       Running   1          1h        10.10.10.76   server76   <none>
kube-apiserver-server76            1/1       Running   1          1h        10.10.10.76   server76   <none>
kube-controller-manager-server76   1/1       Running   1          1h        10.10.10.76   server76   <none>
kube-flannel-ds-amd64-f8mf2        1/1       Running   0          43m       10.10.10.76   server76   <none>
kube-flannel-ds-amd64-xql2h        1/1       Running   0          10m       10.10.10.74   server74   <none>
kube-proxy-tb496                   1/1       Running   0          10m       10.10.10.74   server74   <none>
kube-proxy-vpb6x                   1/1       Running   1          1h        10.10.10.76   server76   <none>
kube-scheduler-server76            1/1       Running   1          1h        10.10.10.76   server76   <none>
[root@server76 docker]#

以上信息有server74这个从节点的信息,flannel和proxy都有两个pod

把server75也加进去后,在master server76上查看如下信息

[root@server76 ~]# kubectl get nodes
NAME       STATUS    ROLES     AGE       VERSION
server74   Ready     <none>    41m       v1.11.2
server75   Ready     <none>    4m        v1.11.2
server76   Ready     master    1h        v1.11.2
[root@server76 ~]#

到这里,k8s通过kubeadm搭建集群成功