Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程

近年来,随着技术架构的演进,从单体到SOA,再由SOA到微服务的架构演变,而大规模的应用给开发和运维带来的很多麻烦。容器化技术的产生,使得我们可以利用镜像不可变性通过快速简单的回滚,提供可靠且频繁的容器镜像构建和部署在生产环境中,可以使得我们以松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分,并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。随着应用规模的不断扩大,就需要一个自动化的管理运行应用程序的容器,实现自动伸缩的系统,具体kubernetes 如何的好,能做什么这里闲话少絮,想了解的参考官网:https://kubernetes.io/zh/docs/concepts/overview/what-is-kubernetes/。 这里也是为了更好了解其中的原理,参考官方文档在本地搭建一套单主节点的集群,并记录下过程中遇到的问题,希望小伙伴可以避免这些问题,快速处理问题,节省时间到研究 kubernetes 本身的原理和实践中去。

同时也给出几篇文章供参考:

centos 8 环境搭单主节点 kubernetes 建集群的文章(英文):

https://www.tecmint.com/install-a-kubernetes-cluster-on-centos-8/

https://upcloud.com/community/tutorials/install-kubernetes-cluster-centos-8/

kubernetes 官方文档的参考(中文):

https://kubernetes.io/zh/docs/setup/independent/create-cluster-kubeadm/

环境准备

我先说一下我的环境:

vagrant+virtual box 创建3台虚拟机,分配 2CPU、2G内存,系统采用 centos 8.1

官网给出的环境要求如下:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第1张图片

虚拟机准备

至于vagrant 和 virtual box 创建虚拟机的过程这里就不写了,给出官网下载地址 和 Vagrantfile 配置即可,需要注意的是要保证虚拟机之间的互相通信,和mac地址的唯一性,这也在上面的要求中列出来了

vagrant 下载地址:https://www.vagrantup.com/downloads.html

virtual box 下载地址:https://www.virtualbox.org/wiki/Downloads

virtual box 虚拟机 centos 镜像地址:https://cloud.centos.org/centos/8/x86_64/images/

最好先下载到本地磁盘保存,然后通过 vagrant 把这个镜像添加到镜像库中:

vagrant box add --name centos/8.1 F:\boxes\CentOS-8-Vagrant-8.1.1911-20200113.3.x86_64.vagrant-virtualbox.box

添加成功之后可以用命令 vagrant box list 查看镜像。

这里给出 Vagrantfile 虚拟机配置文件内容供参考,当然也可以手动创建虚拟机:

Vagrant.configure("2") do |config|
  config.vm.box = "centos/8.1"
  config.vm.box_check_update = false

  (1..3).each do |i|
    config.vm.define "node-#{i}" do |node|
      node.vm.network "public_network"
      node.vm.provider "virtualbox" do |vb|
        vb.name = "node-#{i}"
        vb.memory = "2048"
        vb.cpus = 2
      end
      node.vm.synced_folder "./node-#{i}", "/vagrant"
    end
  end
end

这里虚拟机的名称和同步文件夹名称可以自己修改(我的在Vagrantfile 同级目录下),我把网络设置成 public_network 保证虚拟机可以上公网,因为需要下载镜像。然后运行 vagrant up 启动这三个虚拟机,不放心的话可以互相ping一下,检查网络。

下面正式进入搭建工作,需要在三个节点中安装 kubeadm、kubectl、kubelet、docker组件),在主节点安装控制面板组件(下图中的 kubernetes control plane 部分的组件,用于集群控制)。下图是 kubernetes 官方网站的组件图:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第2张图片

有了这个总体印象后,话不多说,just do it!

安装 docker 环境

docker 运行时环境安装

由于 kubernetes 是容器编排工具,操作的主要对象是容器,需要容器运行时环境,这里选择docker作为容器运行时。kubernetes 不要求特殊容器运行时,只要满足 OCI (Open Container Initiative)的标准即可。可以先安装,也可以安装 kubeadm 之后再安装。

docker 的具体安装过程这里略掉,可以参考官方网站:https://docs.docker.com/engine/install/centos/

这里给出两点需要注意的:

1) 在安装过程中,会出现如下的错误:

 requires containerd.io >= 1.2.2-3, but none of the providers can be installed

这是由于 containerd.io 的版本过低导致的,可以采用官方的

yum list docker-ce --showduplicates | sort -r

选择合适的版本进行安装,也可以升级 containerd.io 的版本,手动安装 containerd.io 之后再安装 docker (推荐使用新版本)

这里给出 containerd.io 的1.2.6 版本 rpm 包下载地址:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm

2)给docker配置阿里云的镜像加速,但是这里只是针对一般的镜像有效,对后面的 k8s.gcr.io 的镜像不起作用:

// 配置使用阿里云镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://md4nbj2f.mirror.aliyuncs.com"]
}
EOF

// 重载配置文件
sudo systemctl daemon-reload   

// 重启docker  
sudo systemctl restart docker

安装完成后可以用如下命令测试:

$ sudo docker run hello-world

安装 kubeadm

kubeadm 是创建 kubernetes 集群的工具,可以通过简单的命令来完成kubernetes集群的构建工作。这也是本次创建kubernetes集群的重点。因为这个过程中,需要安装网络插件,是各个pod能够在多个节点上调度的通信基础。

kubernetes 官网安装 kubeadm 参考:https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

可根据官网步骤来操作:

安装环境准备和检查

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第3张图片

1)检查网络(适配器)连接情况,上面已经提到过,首先需要保证各个虚拟机之间互通,并且能保证连接公网(下载镜像)。

2)检查iptables设置,这个页面不知道是不是工具翻译的,好多翻译不准确,甚至没法理解,所以还是建议参考因为原文。

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第4张图片

就是说要保证 iptables 能够正确的监控桥接网络的流量。并且给出了配置方法。

3)检查开放端口,centos 8.1 默认防火墙是关闭状态的,所以这些端口应该是可以用的。如果系统开启了 firewalld 服务,可以使用如下命令设置:

firewall-cmd --permanent --add-port=6443/tcp
firewall-cmd --permanent --add-port=2379-2380/tcp
firewall-cmd --permanent --add-port=10250/tcp
firewall-cmd --permanent --add-port=10251/tcp
firewall-cmd --permanent --add-port=10252/tcp
firewall-cmd --permanent --add-port=10255/tcp
firewall-cmd –reload

4)安装容器运行时环境

这个过程上面已经安装过了,这里略。

安装 kubeadm、kubelet 和 kubectl

 1) 先决条件设置,下面是官方给出的CentOS、 REHL、 Fedora 系统的配置,但是这个地址国内无法访问

cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

yum install -y kubelet kubeadm kubectl –disableexcludes=kubernetes

systemctl enable –now kubelet

上面的源国内无法访问,所以,修改kubernetes源地址为阿里云地址,保证 kubeadm、kubectl、kubelet 正确安装。

cat < /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

setenforce 0
yum install -y kubelet kubeadm kubectl

systemctl enable kubelet

注意:这里需要修改 kubelet 的驱动,默认为cgroupfs,这与docker 的 cgroup 驱动的 systemd 不一致导致的,如果不修改会导致出现如下错误:

error: failed to run Kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"

解决方法是修改 /ect/docker/daemon.json

#修改daemon.json
vim /etc/docker/daemon.json
#添加如下属性
"exec-opts": ["native.cgroupdriver=systemd"]

然后再将kubelet设置为启动服务:

systemctl enable kubelet && systemctl start kubelet

2)检查 kubelet 使用的 cgroup 驱动,这个是针对不同的 CRI 的,使用docker这里可以忽略。

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第5张图片

初始化主节点

当 kubeadm 成功安装之后,我们就可以用它来初始化集群主节点了。

kubernetes 相关组件镜像下载

输入如下命令,可以查看在初始化kubernetes节点时需要的镜像信息:

kubeadm config images list

可以看到如下信息:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第6张图片

可以看到最新的组件版本是1.18.3,但是在阿里云的镜像中,还没有同步过来(可以先执行下面的脚本文件,没有镜像在换成 1.18.2版本)。

为了避免初始化过程中因为下载镜像时间过长,我们可以在初始化之前先将这些镜像下载到本地,但是我们可以看到它的镜像地址是:k8s.gcr.io 这个地址,国内无法访问,所以需要从阿里云镜像地址下载,这里给出一个镜像下载脚本:

#!/bin/bash

set -e

KUBE_VERSION=v1.18.2
KUBE_PAUSE_VERSION=3.2
ETCD_VERSION=3.4.3-0
CORE_DNS_VERSION=1.6.7

GCR_URL=k8s.gcr.io
ALIYUN_URL=registry.cn-hangzhou.aliyuncs.com/google_containers

images=(kube-proxy:${KUBE_VERSION}
kube-scheduler:${KUBE_VERSION}
kube-controller-manager:${KUBE_VERSION}
kube-apiserver:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd:${ETCD_VERSION}
coredns:${CORE_DNS_VERSION})

for imageName in ${images[@]} ; do
  docker pull $ALIYUN_URL/$imageName
  docker tag  $ALIYUN_URL/$imageName $GCR_URL/$imageName
  docker rmi $ALIYUN_URL/$imageName
done

原理就是把k8s.gcr.io库换成阿里云镜像地址(registry.cn-hangzhou.aliyuncs.com/google_containers ),然后重新打标签,最后删掉阿里的镜像。将上面的脚本保存 kubeadm.sh(注意组件镜像版本的匹配与上面列表相同,最好不要超过一个小版本号) ,然后运行脚本进行下载。

当然也可以在kubeadm init 命令的 --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers 参数替换调默认的 k8s.gcr.io 的地址,为了保证初始化过程的速度建议先下载下来。

kubeadm init 初始化节点

先关闭 swap,执行 swapoff -a 命令;

在主节点上执行如下命令进行集群初始化:

kubeadm init --kubernetes-version=1.18.2 --apiserver-advertise-address=192.168.5.75 --pod-network-cidr=10.10.0.0/16 --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --node-name=master

--kubernetes-version=1.18.2:指定组件的版本,防止去拉取最新镜像(有可能不成功,因为这个版本镜像以及下载到本地)

 --apiserver-advertise-address:表示的是主节点的ip地址。

--pod-network-cidr=10.10.0.0/16:表示之后建立的pod的网段范围

--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers:表示下载组件镜像地址(替换 k8s.gcr.io)

等待一会,出现如下所示的信息,表示主节点已经初始化完成了。

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第7张图片

 如果需要让普通用户可以运行 kubectl,请运行如下命令:

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

如果是 root 用户,运行:

export KUBECONFIG=/etc/kubernetes/admin.conf

查看集群主节点相关组件,输入如下命令:kubectl get pods -n kube-system

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第8张图片

我们可以看到,coredns 的两个pod没有运行,是因为还没有安装网络插件,官网也给出了相关新消息:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第9张图片

安装网络插件

kubernetes(kubeadm) 只支持基于容器网络接口(CNI)的网络,这也提供了很大的灵活性,官网给出了支持的网络列表:

https://kubernetes.io/docs/concepts/cluster-administration/addons/

具体的网络插件可以自己选择,各个网络插件的对比可参考如下网站:

Flannel、Calico、Weave 网络分析: https://network.51cto.com/art/201907/598970.htm

kubernetes 网络模型:https://feisky.gitbooks.io/kubernetes/network/network.html

我们采用 calico 网络插件,参考 calico 官网:https://docs.projectcalico.org/getting-started/kubernetes/quickstart

由于前面的部分我们在 kubeadm init 过程中已经完成了,所以可以直接执行第4步:

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

这时,会根据calico.yaml 文件创建所需的 pod,我们可以观察创建过程:

watch kubectl get pods --all-namespaces

这个过程有些慢,要进行相关的网络设置,而且calico 模型比较复杂,所以需要花费 2~ 3分钟的时间,过程如下图:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第10张图片

 当全部pod运行完成后,我们就可以用 kubeadm join 使其他节点加入集群了。

kubeadm join 加入其他节点到集群

在执行 kubeadm init 命令的输出日志中,会给出加入到主节点的方法:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第11张图片

我们分别在另外两个节点上执行 kubeadm join 命令加入到集群中 :

kubeadm join 192.168.5.75:6443 --token ddet0m.akeearcmtu9jzyas \
>     --discovery-token-ca-cert-hash sha256:0618db7177783f323856898344a2c65080938fb0d9a01f6940ee8c5531ee0a89 --node-name=node-2

--node-name:是加入这个节点在集群中的名字 。

两个节点都执行完成后,我们运行如下命令查看集群节点信息:

kubectl get nodes

此时,集群已经建立完成,如下图所示:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第12张图片

如果希望在没有 control palne 的节点上也能查看集群信息,复制主节点的 .kube/config 文件到其他节点的相同目录即可。

故障排除

按照上面的步骤搭建,在每个步骤需要注意的事情我已经标明了,如果你细心一些的话,应该不会出现问题。

官网上也给出了一些场见故障的一些处理方法:https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/

下面是我在搭建过程中遇到的问题,话费了一些时间,下面就列举几个典型的问题的处理方法:

节点加入集群时报错

错误信息:[ERROR Swap]: running with swap on is not supported. Please disable swap

不支持开启 swap 下运行,执行命令: swapoff - a 将 swap 关闭即可。

节点加入集群后状态 NotReady

1) 网络环境没有准备好

首先,我们看这个节点的 kubelet 的状态:

service kubelet status -l

结果如下:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第13张图片

这是因为网络环境没有准备好,所以要等待 calico 插件的 pod 全部启动成功后,再执行。可以用 kubeadm reset 后再重新加入。

2)pod 的 pause 镜像没有成功拉取

我们执行如下命令查看当前集群中的pod状态:

kubectl get pods -n kube-system

结果如图所示:

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第14张图片

查看这种 ContainerCreating 状态的 pod ,执行命令:

kubectl describe pods kube-proxy-g6zj5 -n kube-system

 如下图所示,是由于k8s.gcr.io/pause:3.2镜像未能成功下载导致的。所以,在kubeadm init 的时候加上 --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers 参数替换 k8s.gcr.io 镜像。

Centos 8.1 搭建单主kubernetes(k8s)集群及故障排除过程_第15张图片

好了,到此为止一个单主的 kubernetes 集群搭建完毕了,主要是安装过程中镜像拉取和网络问题比较多。希望小伙伴们细心一些,希望这篇文章对你有所帮助,节省下宝贵时间来做更有意义的事情。

你可能感兴趣的:(docker,kubernetes,centos)