简介

本文次要目标是为摸索学习k8s提供一个简略的环境。学习如何应用kubeadm,在Vagrant治理的虚拟机上,装置一个繁难的3节点k8s集群。当然,理论环境的k8s集群不会这么简略,然而从能跑起来的最简装置学起更容易,也能理解k8s的根本组成部分。

1、根底软件装置

k8s软件局部的装置次要是kubelet和kubectl,前者装置于每个节点上,用于连贯master节点获取信息,治理Pod,治理容器等。后者为查看、操作k8s的命令行工具。k8s反对多种容器运行环境,这里咱们抉择相熟的docker。最初,还须要装置kubeadm,用于构建一个最小化可用的k8s集群,蕴含了若干最佳化实际的内容。
总之 kubelet kubeadm kubectl docker 这4个软件,就是k8s繁难装置须要的内容了。

kubelet 其实就有点像agent,每个节点都须要有,用于连贯server。

装置步骤次要参考:https://developer.aliyun.com/mirror/kubernetes

首先是k8s yum源的增加,这里抉择阿里云的镜像源,国内装置会快很多。

cat <<EOF > /etc/yum.repos.d/kubernetes.repo[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/enabled=1gpgcheck=1repo_gpgcheck=1gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpgEOF

其次是软件的装置和一些配置,这里先把docker和kubelet配置为开机启动。而后敞开SELinux、敞开swap、批改内核参数、敞开防火墙。

## 装置sudo yum install -y kubelet kubeadm kubectl docker #这里也要装置dockersudo systemctl enable docker && sudo systemctl start docker #先启动dockersudo systemctl enable kubelet #这里只配置主动启动,不必理论启动(此时还缺配置文件)## 配置sudo setenforce 0 #敞开SELinuxsudo swapoff -a && sed  -i '/swap/s/^/#/' /etc/fstab  #敞开swap,更改fstabsudo sysctl net.bridge.bridge-nf-call-iptables=1 sudo systemctl disable firewalld && sudo systemctl stop firewalld #敞开防火墙

须要留神的是,kubelet在装置实现后,并不能间接启动,短少若干配置。(执行kubeadm时会生成),间接start可能会出各种问题,前面kubeadm init的时候会自行启动kubelet。这部分问题在本文最初对立提及。

2、k8s所需docker镜像获取

k8s的控制面板次要由apiserver、controller-manager、scheduler、etcd四局部组成,部署在master节点上。coredns是k8s默认的DNS服务。
kube-proxy,pause则部署在所有k8s节点上,kube-proxy与Service相干,而pause则是用来实现Pod内的命名空间共享等性能。
上述这些组件在init初始化master节点时都会用到,能够应用 kubeadm config images list 查看镜像的具体需要,版本。

k8s.gcr.io/kube-apiserver:v1.18.8k8s.gcr.io/kube-controller-manager:v1.18.8k8s.gcr.io/kube-scheduler:v1.18.8k8s.gcr.io/kube-proxy:v1.18.8k8s.gcr.io/pause:3.2k8s.gcr.io/etcd:3.4.3-0k8s.gcr.io/coredns:1.6.7

间接从源拉取镜像,大概率会超时。个别的计划均为举荐应用docker的register mirror或者间接给docker配置代理,然而我集体体验并不好。(也可依据本人状况抉择各种计划,只有能把镜像拉下来就行)
起初发现了新的解决方案:https://www.cnblogs.com/flhs/p/12383895.html

具体原理就是借助阿里云的镜像仓库性能,手动创立若干个仓库(与k8s的每个组件名称雷同),每个仓库绑定Dockerfile(从git获取),内容只有一行FROM k8s.gcr.io/kube-apiserver:v1.18.8,再应用构建性能,一个自制仓库就制作实现了。随后就能够拉取我的项目到本地了,再改tag了。

eg:先sudo docker pull http://registry.ap-southeast-1.aliyuncs.com/xxxxx/kube-apiserver:v1.18.8拉取镜像到本地,再sudo docker tag http://registry.ap-southeast-1.aliyuncs.com/xxxxx/kube-apiserver:v1.18.8 k8s.gcr.io/kube-apiserver:v1.18.8 改tag即可。

3、应用Vagrant做本地配置化

k8s所需软件和镜像就是装置所需的全副资源了,前两个步骤能够思考进行打包,便于多次重复练习。
因为是学习阶段,软件装置和镜像获取我都是在本地虚拟机上进行的,应用Vagrant来治理装置内容,步骤,以及多虚拟机的治理。这样就能够实现轻松的从新来过,屡次练习。

当然,如果是理论应用,Ansible或者自动化工具来实现这些初始化工作也很不便,只不过调用本地虚拟机,Vagrant就够了。

在一台虚构机上安装好所有软件,拉取了所有镜像后。能够用vagrant将这台虚拟机打包成一个box,后续基于这个box进行操作。
其次,vagrant反对单Vagrantfile定义多个虚拟机,应用vm.define能够别离对每个虚拟机配置IP地址,主机名等其余内容。对于共通内容不做改变。

config.vm.define "master00" do |m0|  m0.vm.network "public_network", ip: "192.168.1.10"endconfig.vm.define "worker00" do |w0|  m0.vm.network "public_network", ip: "192.168.1.11"end

通过这样的步骤,能够用一个配置文件治理多个虚拟机,能够别离对任意一个虚拟机进行删除重建,非常不便。

vagrant Provision不执行问题:
如果应用过provision再打包,再执行vagrantfile时,默认就不会执行provision,须要手动指定。
https://www.vagrantup.com/docs/provisioning/basic_usage

4、应用kubeadm初始化master/worker节点

筹备工作都做好之后,就能够开始进行节点的初始化了。

4.1、init

kubeadm init是初始化master节点,管制立体。
init之前的确认事项:

sudo sysctl net.bridge.bridge-nf-call-iptables=1;sudo setenforce 0;sudo systemctl stop firewalld && sudo systemctl disable firewalld;sudo swapoff -a;

除了内核参数,SELinux,防火墙,swap这4部份外,/etc/hosts文件,以及主机名的批改也须要确认,保障每个节点之间能够应用域名解析。

init参数:
init时,能够依据须要抉择关上一些参数。

  • 如果有多网卡,要留神应用--apiserver-advertise-address=xxx.xxx.xxx.xxx参数指定冀望的IP。

    --apiserver-advertise-address string   The IP address the API Server will advertise it's listening on. If not set the default network interface will be used.
  • init能够关上参数,查看更加具体的日志:--v=6

init失败时,能够抉择reset重来sudo kubeadm reset
init胜利页面如下图所示:

3.2、join

master节点init初始化实现后,最初会给出增加worker节点的信息。在worker节点上join即可增加到集群中。

3.3、k8s状态确认

kubectl须要进行一些简略的配置能力连贯上集群,内容参照init时的胜利页面。能够应用 kubectl get nodes 来确认整体装置状况。

kubectl get pods也会呈现localhost:8080 was refused 这种状况,其实就是配置问题。本文最初会解说这个问题。

4、网络插件/网卡配置

网络插件有几个可选项,最终选用了flannel:
https://github.com/coreos/flannel

4.1 kubelet 多网卡配置解决 node-ip

k8s的默认node ip也是取的默认网卡eth0,然而vagrant本人配置的桥接网卡位于eth1,就须要批改kubelet配置来进行适配,改为冀望的网卡IP。
批改--node-ip即可实现这一需要:
在/etc/sysconfig/kubelet 这个文件做如下编辑:
KUBELET_EXTRA_ARGS=--node-ip=192.168.x.xx
增加实现后重启kubelet即可。

能够通过 $(ip a|egrep "inet.\*eth1"|awk -F"/" '{print$1}'|awk '{print$2}') 来获取本机指定网卡的IP,也可运行脚本写入/etc/sysconfig/kubelet。

参考:
能够通过查看node-ip来确认是否合乎预期:https://cloud.tencent.com/developer/article/1440852
k8s 如何批改node IP? 或者说如何指定网卡获取node IP? https://yanbin.blog/kubernetes-cluster-internal-ip-issue/#more-10102

4.2、flannel 多网卡配置及cidr参数配置

和上述问题一样,flannel也要减少网卡配置。不然就会呈现

I0821 09:33:17.131354       1 main.go:518\] Determining IP address of default interfaceI0821 09:33:17.131896       1 main.go:531\] Using interface with name eth0 and address 10.0.2.15I0821 09:33:17.131908       1 main.go:548\] Defaulting external address to interface address (10.0.2.15)

这种问题,vagant默认网卡是不能用的,须要想方法指定网卡。
这个参数能够在flannel的yaml配置文件里更改。更改后,apply -f即可。

在/opt/bin/flanneld的参数中,增加一个--iface=ethx
      - name: kube-flannel        image: quay.io/coreos/flannel:v0.12.0-arm        command:        - /opt/bin/flanneld        args:        - --ip-masq        - --kube-subnet-mgr        - --iface=eth1

其次 kubeadm init的时候,如果要应用flannel,须要减少cidr参数。--pod-network-cidr=10.244.0.0/16,可参考:https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md

flannel网卡参考:
https://blog.csdn.net/ygqygq2/article/details/81698193?utm_source=blogxgwz3

网络插件参考:
https://www.dazhuanlan.com/2019/11/20/5dd4549077148/
https://blog.csdn.net/kwame211/article/details/100335273
http://www.linuxe.cn/post-580.html

5、其余留神点

5.0、kubectl操作优化

alias k=kubectlsource <(kubectl completion bash | sed s/kubectl/k/g) #这里也须要替换成k能力补全
应用k来简化操作,同时关上kubectl的bash 补全。

5.1、kubelet启动问题

首先,没有进行kubeadm和其余配置之前,kubectl短少配置,启动会报错,繁难装置实现后再看。
次要会遇到2个问题:1、cgroup不对,2、system.slice报错。

kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"

这个问题其实就是kubelet和docker的默认cgoupfs不一样,须要批改其中一方。查阅文档批改其中一方即可,参考:https://blog.csdn.net/russle/article/details/104954408

Failed to get system container stats for "/system.slice/docker.service": failed to get cgroup stats for "/system.slice/docker.service": failed to get container info for "/system.slice/docker.service": unknown container "/system.slice/docker.service"

https://stackoverflow.com/questions/46726216/kubelet-fails-to-get-cgroup-stats-for-docker-and-kubelet-services
这个报错,就是短少参数,手动增加上即可。--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice

5.3、kubeadm init失败的简略排查

kubeadm init报错:

kubelet报错:

kubelet的报错,只是一个后果(连不上6443),要去查真正的起因。其实init之后,docker容器曾经都启动了,要去查容器有没有问题。

发现3个容器有问题。
【容器有问题->6443没起来-->kubelet连不上 -->master节点找不到-->init失败】(要去查本源才行)
https://blog.csdn.net/sanpic/article/details/87084779
确认SELinux
https://blog.51cto.com/bguncle/957315
【其实就是SELinux开机自启了。。。。。

5.4、kubectl端口refused问题

尝试可能会发现,Master节点8080都没监听(其实是网络环境隔离了)
问题其实就是,不容许Master节点的root用户拜访,能够用其余普通用户拜访
https://www.jianshu.com/p/98c22ca2d9ab

小结

本文次要解说了kubeadm装置繁难3节点k8s集群的过程以及遇到的一些问题,应用kubeadm装置3节点k8s集群曾经是相当繁难的形式,对于学习摸索来说根本够用,然而理论生产环境须要更高的可用性,比方etcd独自部署,master节点多实例等等。
总之k8s组件泛滥,首次上手以疾速搭建学习环境为主,后续能够持续深刻理解,尝试部署更简单的环境。