Kubernetes(2) 搭建Kubernetes集群

0. 回顾Kubernetes架构

kubeadm使用简介

  • apt-get install kubeadm( 宿主机上安装kubeadm,kubelet,kubectl)
  • Kubeadm init
    • 做一些列的检查工作,确认是否可以部署k8s,被称为Preflight checks
  • 生成k8s对外提供服务所需的各种证书和对应的目录,注意,我们可以选择不让kubeadm生成这些证书,而是拷贝现有证书到/etc/kubernetes/pki/目录下
    • 为其他组件生成访问kube-apiserver所需的配置文件,存储路径是/etc/kubernets/xxx.conf
    • 为master组件,kube-apiserver,kube-controller-manager,kube-scheduler,生成pod配置文件(yaml文件),被保存在/etc/kubernetes/mainfests下
    • 在4中节点上的kubelet启动后,通过static pod的方式加载4中目录下的pod yaml文件,并启动kube-apiserver这些master组件
    • kubeadm会生成一个etcd的pod yaml文件,同样通过static pod的方式启动etcd,所以master组件的pod yaml文件如下
      $ ls /etc/kubernetes/manifests/
      etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
    • 检查Locallhost:6443/healthz 这个健康检查url,等待master组件完全运行起来
    • 为集群生成bootstrap token,为之后kubeadm join命令做验证
    • 将master节点的重要信息,通过configmap的方式保存在etcd中,共后续安装Node节点使用
    • 安装默认插件,k8s默认安装kube-proxy和dns,提供集群发现和dns功能。
  • Kubeadm join
    • 新的worker节点上kubeadm发起一次“不安全的”请求道kube-apiserver获取etcd中存储的cluster-info中的地址,端口,证书,bootstrap token扮演了安全验证的角色
    • 通过证书建立起worker节点和master节点的 关系

1. 在所有节点上安装Docker和kubeadm

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat < /etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ apt-get update
$ apt-get install -y docker.io kubeadm

通过这个步骤,kubeadm、kubelet、kubectl、kubernetes-cni这几个二进制文件都会被自动安装好。

2. 部署Kubernetes Master

2.1 编写kubeadm.yaml配置文件

示例如下:

apiVersion: kubeadm.k8s.io/v1alpha1
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"

执行kubeadm init --config kubeadm.yaml, 稍等一会儿,部署完成后,kubeadm会生成一条指令,如下

kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711

记录下来上面这条指令,这是用来给这个master节点添加更多工作节点(worker)的命令。

通过kubectl describe node master和kubectl get pods -n kube-system查看到的是因为网络相关的配置没有进行导致nodenotready

2.2 安全文件配置

此外,Kubernetes默认需要加密方式访问。所以,需要把刚刚部署生成的Kubernetes集群的安全配置文件,保存到当前用户的.kube目录下,kubectl默认会使用这个目录下信息授权访问Kubernetes集群。

 mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

2.3 检查节点状态

  • kubectl describe node master
$ kubectl describe node master

...
Conditions:
...

Ready   False ... KubeletNotReady  runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
  • kubectl get pods -n kube-system
$ kubectl get pods -n kube-system

NAME               READY   STATUS   RESTARTS  AGE
coredns-78fcdf6894-j9s52     0/1    Pending  0     1h
coredns-78fcdf6894-jm4wf     0/1    Pending  0     1h
etcd-master           1/1    Running  0     2s
kube-apiserver-master      1/1    Running  0     1s
kube-controller-manager-master  0/1    Pending  0     1s
kube-proxy-xbd47         1/1    NodeLost  0     1h
kube-scheduler-master      1/1    Running  0     1s

可以看出,是CoreDNS、kube-controller-manager等依赖网络的Pod都处于Pending状态,即调度失败。

3. 部署容器网络插件

部署网络插件,以Weave为例,

$ kubectl apply -f https://git.io/weave-kube-1.6

部署完成后,重新kubectl get pods -n kube-system检查Pod的状态,全部都启动成功,保持running状态。
目前,Kubernetes支持容器网络插件,使用的是CNI的通用接口,也是当前容器网络的实施标准,市面上Flannel、Calico、Canal、Romana等一键部署项目都是通过CNI接口Kubernetes。

至此,Master节点部署完成,如果只需要一个Kubernetes,现在就可以使用了,但是默认情况下,Kubernetes的Master节点是不能运行用户Pod的,所以还需要额外做一个小操作,最后介绍。

4. 部署Kubernetes Worker节点

master节点和worker节点几乎是相同的,都运行着一个kubulet的组件。唯一的区别是Master节点会额外在kubeadm init过程中自动运行kube-apiserver, kube-scheduler, kube-controller-manager。
分两步执行部署:

  • 在所有节点上执行第一小节“安装kubeadm和Docker”
  • 执行部署Master节点是生成的kubeadm join指令
$ kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711

5. 通过Taint/Toleration调整Master执行Pod的策略

[规定]默认情况下Master节点是不运行Pod。
[实现方式]Taint/Toleration机制
Taint(污点):通过命令给node节点加上Taint之后,所有的Pod就不能再在这个node上运行了。---Pod有洁癖
Toleration(容忍):个别Pod可以特别声明自己可以容忍这个污点,那么就可以在对应打了污点的节点上运行。
[Taint使用方法]

$ kubectl taint nodes node1 foo=bar:NoSchedule

这样在node1上上城了一个键值对格式的Taint,其中里面的NoSchedule字段,意味着这个污点只会在调度新的Pod的时候产生作用,不会影响已经运行在Node1上的POD。
这么看来,给Node打上Taint的内容即foo=bar:NoSchedule部分还是有多种使用方法,这个还是要再研究下。
[Toleration使用方法]
在Pod对应的Yaml文件中加入字段:

apiVersion: v1
kind: Pod
...
spec:
  tolerations:
  - key: "foo"
    operator: "Equal"
    value: "bar"
    effect: "NoSchedule"

6. 部署Dashboard可视化插件

安装可视化插件并查看对应Pod详情

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
$ kubectl get pods -n kube-system
kubernetes-dashboard-6948bdb78-f67xk   1/1       Running   0          1m

注意,dashboard是一个web service,1.7 版本之后dashboard项目部署完成后,只能通过Proxy在本地访问,需要用到Ingress。

7. 部署容器存储插件

容器持久化存储是解决容器的典型特征“无状态”的。
通过网络或者其他机制的远程数据卷,将其和容器中某个目录进行绑定挂载,进而使得在容器中创建的文件能够保存在远程存储服务器上、或以分布式的方式保存在多个节点上。
可用的,如Ceph,NFS,GlusterFS等,都可以为Kubernetes提供持久化存储能力。

8. 踩坑

  • 离线安装kubelet
systemctl daemon-reload
systemctl start kubelet.service //启动失败,通过journalctl查看具体原因(systemctl起服务失败时候可以采用该日志定位方式)

ref: https://github.com/kubernetes/kubernetes/issues/54542

你可能感兴趣的:(Kubernetes(2) 搭建Kubernetes集群)