共计 6858 个字符,预计需要花费 18 分钟才能阅读完成。
简介
本文次要目标是为摸索学习 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=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
其次是软件的装置和一些配置,这里先把 docker 和 kubelet 配置为开机启动。而后敞开 SELinux、敞开 swap、批改内核参数、敞开防火墙。
## 装置
sudo yum install -y kubelet kubeadm kubectl docker #这里也要装置 docker
sudo systemctl enable docker && sudo systemctl start docker #先启动 docker
sudo systemctl enable kubelet #这里只配置主动启动,不必理论启动(此时还缺配置文件)## 配置
sudo setenforce 0 #敞开 SELinux
sudo swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab #敞开 swap,更改 fstab
sudo 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.8
k8s.gcr.io/kube-controller-manager:v1.18.8
k8s.gcr.io/kube-scheduler:v1.18.8
k8s.gcr.io/kube-proxy:v1.18.8
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.3-0
k8s.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"
end
config.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 interface
I0821 09:33:17.131896 1 main.go:531\] Using interface with name eth0 and address 10.0.2.15
I0821 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=kubectl
source <(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 组件泛滥,首次上手以疾速搭建学习环境为主,后续能够持续深刻理解,尝试部署更简单的环境。