Google云上用kubeadm搭建kubernetes集群

1、环境准备
首先个人三个ubuntu云主机的配置以下node

cpu数量 内存 磁盘 Ubuntu
2 8G 20G 18.04LTS

并且能保证三台机器都能链接外网,这里用的谷歌云主机,因此不用担忧访问外网问题,若是是本地搭建请参考另外一篇博文本地kubeadm搭建kubernetes集群https://blog.51cto.com/13670314/2397626git

这里的全部命令都是在root用户下操做的github

2、安装docker

1.在全部的节点上安装Docker和kubeadmubuntu

root@instance-ubuntu-1:~# apt-get install curl -y 
root@instance-ubuntu-1:~# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
root@instance-ubuntu-1:~#  cat <<EOF > /etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
root@instance-ubuntu-1:~# apt-get update
root@instance-ubuntu-1:~# apt-get install -y docker.io kubeadm
上述安装过程当中,kubeadm,kubectl,kubelet,kubernetes-cni这几个二进制文件都会被自动安装好。
直接使用+Ubuntu+的+docker.io+的安装源,缘由是+Docker+公司每次发布的最新的+Docker+CE(社区版)产品每每尚未通过+Kubernetes+项目的验证,可能会有兼容性方面的问题。

2.部署kubernetes的Master节点vim

root@instance-ubuntu-1:~# vim kubeadm.yaml
apiVersion: kubeadm v1.11
kind: MasterConfiguration
controllerManagerExtraArgs:
horizontal-pod-autoscaler-use-rest-clients: "true"
horizontal-pod-autoscaler-sync-period: "10s"
node-monitor-grace-period: "10s"
apiServerExtraArgs:
runtime-config: "api/all=true"
kubernetesVersion: "stable-1.11"后端

root@instance-ubuntu-1:~# kubeadm init --config kubeadm.yamlapi

若是有报错安全

your configuration file uses an old API spec: "kubeadm.k8s.io/v1alpha1". Please use kubeadm v1.11 instead and run 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.服务器

把apiServer改为你对应的版本

再次运行kubeadm init --config kubeadm.yaml

这样就能够完成Master的部署了,稍等片刻,部署完成后,kubeadm会生成一条指令

kubeadm join 10.168.0.6:6443 --token k0jhnn.a7l33i18ehbl1aze \
--discovery-token-ca-cert-hash sha256:064420e731f201b1601bb0bb39ccfef0e581a83449a043b60036cfb4537e5c67

kubeadm join 命令是用来给Master节点添加更多的Work节点的,记住此命令,下面会用到。

此外,kubeadm会提示提示第一次使用集群所须要的配置命令。

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

由于Kubernetes 集群默认须要加密方式访问。因此,这几条命令,就是将刚刚部署生成的 Kubernetes 集群的安全配置文件,保存到当前用户的.kube 目录下,kubectl 默认会使用这个目录下的受权信息访问 Kubernetes 集群。若是不这么作的话,咱们每次都须要经过 export KUBECONFIG 环境变量告诉 kubectl 这个安全配置文件的位置。
如今,咱们就可使用 kubectl get命令来查看当前惟一一个节点的状态了

root@instance-ubuntu-1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
instance-ubuntu-1 NotReady master 3h52m v1.14.1

主节点的状态为何会是NotReady,咱们查看一下master节点的详细信息

root@instance-ubuntu-1:~# kubectl describe node instance-ubuntu-1

会显示

Ready False ... KubeletNotReady runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

这是由于咱们尚未部署任何网络插件

3.部署网络插件

在 Kubernetes 项目“一切皆容器”的设计理念指导下,部署网络插件很是简单,只须要执行一句 kubectl apply 指令,以 Weave 为例:

root@instance-ubuntu-1:~# kubectl apply -f https://git.io/weave-kube-1.6

部署完成后检查一下

root@instance-ubuntu-1:~# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-fb8b8dccf-lc69z 1/1 Running 0 3h57m
coredns-fb8b8dccf-p2p4k 1/1 Running 0 3h57m
etcd-instance-ubuntu-1 1/1 Running 0 3h56m
kube-apiserver-instance-ubuntu-1 1/1 Running 0 3h56m
kube-controller-manager-instance-ubuntu-1 1/1 Running 0 3h56m
kube-proxy-pksmg 1/1 Running 0 3h47m
kube-proxy-qb2cl 1/1 Running 0 3h57m
kube-proxy-z6q42 1/1 Running 0 3h47m
kube-scheduler-instance-ubuntu-1 1/1 Running 0 3h56m
kubernetes-dashboard-5f7b999d65-rkkqq 1/1 Running 0 3h29m
weave-net-f5kgb 2/2 Running 1 3h47m
weave-net-fxxq2 2/2 Running 0 3h47m
weave-net-nplfj 2/2 Running 0 3h50m

能够看到全部pod都运行起来了 而刚刚部署的 Weave 网络插件则在 kube-system 下面新建了一个名叫 weave-net-cmk27 的 Pod,通常来讲,这些 Pod 就是容器网络插件在每一个节点上的控制组件。 Kubernetes 支持容器网络插件,使用的是一个名叫 CNI 的通用接口,它也是当前容器网络的事实标准,市面上的全部容器网络开源项目均可以经过 CNI 接入 Kubernetes,好比 Flannel、Calico、Canal、Romana 等等,它们的部署方式也都是相似的“一键部署”。至此,Kubernetes 的 Master 节点就部署完成了。若是你只须要一个单节点的 Kubernetes,如今你就可使用了。不过,在默认状况下,Kubernetes 的 Master 节点是不能运行用户 Pod 的,第4部分会讲到如何处理。

4.部署 Kubernetes 的 Worker 节点
Kubernetes 的 Worker 节点跟 Master 节点几乎是相同的,它们运行着的都是一个 kubelet 组件。惟一的区别在于,在 kubeadm init 的过程当中,kubelet 启动后,Master 节点上还会自动运行 kube-apiserver、kube-scheduler、kube-controller-manger 这三个系统 Pod。 因此,相比之下,部署 Worker 节点反而是最简单的,只须要两步便可完成。
第一步,在全部 Worker 节点上执行2、安装,第1节的全部步骤。
第二步,执行部署 Master 节点时生成的 kubeadm join 指令:

>kubeadm join 10.168.0.6:6443 --token k0jhnn.a7l33i18ehbl1aze \
--discovery-token-ca-cert-hash sha256:064420e731f201b1601bb0bb39ccfef0e581a83449a043b60036cfb4537e5c67

经过 Taint/Toleration 调整 Master 执行 Pod 的策略 前面提到过,默认状况下 Master 节点是不容许运行用户 Pod 的。而 Kubernetes 作到这一点,依靠的是 Kubernetes 的 Taint/Toleration 机制。 它的原理很是简单:一旦某个节点被加上了一个 Taint,即被“打上了污点”,那么全部 Pod 就都不能在这个节点上运行,由于 Kubernetes 的 Pod 都有“洁癖”。 除非,有个别的 Pod 声明本身能“容忍”这个“污点”,即声明了 Toleration,它才能够在这个节点上运行。 其中,为节点打上“污点”(Taint)的命令是:

root@instance-ubuntu-1:~# kubectl taint nodes instance-ubuntu-1 foo=bar:NoSchedule

这时,该 node1 节点上就会增长一个键值对格式的 Taint,即:foo=bar:NoSchedule
。其中值里面的 NoSchedule,意味着这个 Taint 只会在调度新 Pod 时产生做用,而不会影响已经在 node1 上运行的 Pod,哪怕它们没有 Toleration。

如今回到咱们已经搭建的集群上来。这时,若是你经过 kubectl describe 检查一下 Master 节点的 Taint 字段,就会有所发现了:

root@instance-ubuntu-1:~# kubectl describe node master

5.部署Dashboard可视化插件
在 Kubernetes 社区中,有一个很受欢迎的 Dashboard 项目,它能够给用户提供一个可视化的 Web 界面来查看当前集群的各类信息。绝不意外,它的部署也至关简单

kubectl create -f
https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

部署完成以后,咱们就能够查看+Dashboard+对应的+Pod+的状态了

root@instance-ubuntu-1:~# kubectl get pods -n kube-system

kubernetes-dashboard-6948bdb78-f67xk 1/1 Running 0 1m

须要注意的是,因为 Dashboard 是一个 Web Server,不少人常常会在本身的公有云上无心地暴露+Dashboard 的端口,从而形成安全隐患。因此,1.7 版本以后的 Dashboard 项目部署完成后,默认只能经过 Proxy 的方式在本地访问。具体的操做,你能够查看 Dashboard+项目的官方文档。 而若是你想从集群外访问这个 Dashboard 的话,就须要用到 Ingress

6.部署容器存储插件

为何要部署Rook呢?
一般咱们创建容器的时候须要把数据卷挂在到宿主机上的目录,或者文件挂在到容器的Mount Namespace中,
从而实现主机和容器共享这些目录,可是,若是你在另外一台机器上启动一个容器,就没有办法看到其它机器上的容器挂载的数据卷,这就是所谓的容器典型特征:无状态。
这时候容器就须要持久化存储,就是用来保存容器的状态,存储插件会在容器里挂载一个基于网络或者其余机制的远程数据卷,使得在容器里建立的文件其实是保存在远程存储服务器上,或者是以分布式的方式保存在多个节点上,与当前宿主机没有任何绑定关系。这样,不管你在其余哪一个宿主机上启动新的容器,均可以请求挂载指定的持久化存储卷,从而访问到数据卷里保存的内容。这就是所谓持久化。

Rook 项目是一个基于 Ceph 的 Kubernetes 存储插件(它后期也在加入对更多存储实现的支持)。不过,不一样于对 Ceph 的简单封装,Rook 在本身的实现中加入了水平扩展、迁移、灾难备份、监控等大量的企业级功能,使得这个项目变成了一个完整的、生产级别可用的容器存储插件。

部署Ceph存储后端

kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/operator.yaml

kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/cluster.yaml

在部署完成后,能够看到Rook项目会将本身的Pod防止在由它管理的两个Namesoace当中:

>root@instance-ubuntu-1:~# kubectl get pods -n rook-ceph-system
NAME                                                           READY     STATUS    RESTARTS   AGE
rook-ceph-agent-7cm42                                 1/1           Running          0             18s
rook-ceph-operator-78d4587c68c-7fj72         1/1           Running          0             44s
rook-discover-2ctcv                                        1/1           Running          0             18s

>root@instance-ubuntu-1:~# kubectl get pods -n rook-ceph
NAME                              READY     STATUS    RESTARTS   AGE
rook-ceph-mon0-kxrgh        1/1         Running          0              13s
rook-ceph-mon1-7dk2t        1/1         Running          0               5s

这样,一个基于 Rook 持久化存储集群就以容器的方式运行起来了,而接下来在 Kubernetes 项目上建立的全部 Pod 就可以经过 Persistent Volume(PV)和 Persistent Volume Claim(PVC)的方式,在容器里挂载由 Ceph 提供的数据卷了。