基于kubeadm在3台CentOS 7.6虚拟机上搭建K8s集群

温馨提示:若将此教程作为搭建K8s集群的参考,建议先纵览所有流程,因为本文所展示并非最简步骤,而是按照本人的安装步骤组织,其中穿插了本人踩过的坑。所以为求思路清晰,提高搭建效率,建议首先纵览一遍!

1.准备工作——搭建分布式虚拟机集群

1.1安装VMware workstation

  此处略去XXX个字以及XXX张图!

1.2安装虚拟机CentOS 7

  • 在VMware workstation中创建虚拟机
    • 此处略去XXX个字!
  • 问题记录
    • 虚拟机无法访问外网,网络需要配置为NAT;编辑/etc/sysconfig/networ-scripts/目录下的ifcfg-ens33文件,修改其中的ONBOOT=noONBOOT=yes。然后重启即可。
    • 此时yum源可以正常使用,安装网络工具net-tools,就可以使用ifconfig查看网络配置。
yum install -y net-tools

1.3虚拟机克隆

  • 形成一个master和两个node的模式。当然也可以在一个集群上做安装和配置,等到需要差异化配置之前再进行克隆,后者更高效。

2.搭建K8s集群

  我们最终搭建的集群及其配置情况如下表所示:

hostnameOSIPplug-ins
k8s-masterCentOS 7.6192.168.140.134docker-1.13.1; kubelet-1.18.3; kubeadm-1.18.3;kubectl-1.18.0
k8s-node1CentOS 7.6192.168.140.136docker-1.13.1; kubelet-1.18.3; kubeadm-1.18.3
k8s-node2CentOS 7.6192.168.140.135docker-1.13.1; kubelet-1.18.3; kubeadm-1.18.3

2.1安装kubeadm,kubelet(master和node都需要)

关闭防火墙

systemctl disable firewalld
systemctl stop firewalld

禁用SELinux

setenforce 0
vi /etc/sysconfig/selinux
## 设置SELINUX=enforcing 为 SELINUX=disabled
reboot #使修改生效

配置yum
  在目录/etc/yum.repo.d/下创建文件kubernetes.repo,在其中添加如下内容:

[kubernetes]
name=Kubernetes
baseurl = https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled = 1
gpgcheck = 1
gpgkey = http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
		 http://mirrors.aliyun.com/kubernetes/yum/doc/yum-package-key.gpg

  在此处踩了一个很大又很傻逼的坑,我是在虚拟机中配置的,在配置yum源镜像时,将字母“l”写成了数字“1”,集群搭建进度就被拖慢了半天!
安装kubeletkubeadm

yum install -y kubelet kubeadm

启动kubelet服务并使能开机启动:

systemctl start kubelet
systemctl enable kubelet

2.2 安装docker(master和node都需要)

配置yum

yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo
yum clean all
yum makecache
yum update -y

安装

yum install docker -y

开启docker服务并使能开机启动

systemctl start docker
systemctl enable docker

2.3虚拟机克隆

  我选择进行到这一步之后再进行虚拟机克隆,避免在每台虚拟机上进行重复的安装工作。此时形成了一个master两个node的局面,但其实此时三台虚拟机的配置情况完全相同。
在这里插入图片描述
  细心的读者在这一步应该会注意到,还需要在master几点上安装kubectl组件,但其实在之前安装kubeadmkubelet的过程中,kubectl已经被默认安装了,所以此处无需另外的操作。

2.4 kubeadm配置以及Master节点安装

  在这一步,我们想做的事情就是借kubeadm在一台节点上做初始化,使其能够承担k8s集群中master的角色。所以主要使用到的工具是kubeadm,那么先要对它所有了解,否则如果稀里糊涂按照教程运行一堆指令之后,运行结果正确是万幸,不正确的话便不知从何下手做改正。
kubeadm相关指令了解

kubeadm init ## 启动一个 Kubernetes 主节点
kubeadm join ## 启动一个 Kubernetes 工作节点并且将其加入到集群
kubeadm upgrade ## 更新一个 Kubernetes 集群到新版本
kubeadm config ## 如果使用 v1.7.x 或者更低版本的 kubeadm 初始化集群,您需要对集群做一些配置以便使用 kubeadm upgrade 命令
kubeadm token ## 管理 kubeadm join 使用的令牌
kubeadm reset ## 还原 kubeadm init 或者 kubeadm join 对主机所做的任何更改

kubeadm init的参数

--apiserver-advertise-address string
## API Server将要广播的监听地址。如指定为 `0.0.0.0` 将使用缺省的网卡地址。
--apiserver-bind-port int32     缺省值: 6443
## API Server绑定的端口
--apiserver-cert-extra-sans stringSlice
## 可选的额外提供的证书主题别名(SANs)用于指定API Server的服务器证书。可以是IP地址也可以是DNS名称。
--cert-dir string     缺省值: "/etc/kubernetes/pki"
## 证书的存储路径。
--config string
## kubeadm配置文件的路径。警告:配置文件的功能是实验性的。
--cri-socket string     缺省值: "/var/run/dockershim.sock"
## 指明要连接的CRI socket文件
--dry-run
## 不会应用任何改变;只会输出将要执行的操作。
--feature-gates string
## 键值对的集合,用来控制各种功能的开关。可选项有:
Auditing=true|false (当前为ALPHA状态 - 缺省值=false)
CoreDNS=true|false (缺省值=true)
DynamicKubeletConfig=true|false (当前为BETA状态 - 缺省值=false)
-h, --help
## 获取init命令的帮助信息
--ignore-preflight-errors stringSlice
## 忽视检查项错误列表,列表中的每一个检查项如发生错误将被展示输出为警告,而非错误。 例如: 'IsPrivilegedUser,Swap'. 如填写为 'all' 则将忽视所有的检查项错误。
--kubernetes-version string     缺省值: "stable-1"
## 为control plane选择一个特定的Kubernetes版本。
--node-name string
## 指定节点的名称。
--pod-network-cidr string
## 指明pod网络可以使用的IP地址段。 如果设置了这个参数,control plane将会为每一个节点自动分配CIDRs。
--service-cidr string     缺省值: "10.96.0.0/12"
## 为service的虚拟IP地址另外指定IP地址段
--service-dns-domain string     缺省值: "cluster.local"
## 为services另外指定域名, 例如: "myorg.internal".
--skip-token-print
## 不打印出由 `kubeadm init` 命令生成的默认令牌。
--token string
## 这个令牌用于建立主从节点间的双向受信链接。格式为 [a-z0-9]{6}\.[a-z0-9]{16} - 示例: abcdef.0123456789abcdef
--token-ttl duration     缺省值: 24h0m0s
## 令牌被自动删除前的可用时长 (示例: 1s, 2m, 3h). 如果设置为 '0', 令牌将永不过期。

  在了解完kubeadm的指令和相关参数后,我们就可以在k8s-master节点上做配置了。在进行kubeadm初始化时,需要指定多项参数,包括k8s的版本信息等,我们使用到的命令如下:
初始化master节点

 kubeadm init --kubernetes-version=v1.18.0 \
 --pod-network-cidr=10.244.0.0/16 \
 --apiserver-advertise-address=192.168.140.134

  由于master正常工作,所需的组件较多,而且各组件都以pod的形式运行在节点之上,所以初始化的过程中,系统就会自动到默认的仓库拉取所需组件的镜像,可惜的是默认仓库的链接国内网络无法访问,所以就会爆出如下图的错误:
在这里插入图片描述
拉取镜像
  尽管如此,我们依然可以曲线救国。首先要清楚该过程中拉取的镜像都有哪些,包括apiserveretcdschedulercontroller-managerkube-proxypausecoredns,但是默认的源来自k8s.gcr.io,不能访问。为此,下文展示了使用国内阿里云的镜像源来拉去镜像的脚本。值得注意的是,需要手动配置各组件的版本,并匹配pauseetcdcoredns对应的版本、版本出错的话,配置过程依然不能完成。此处我有一个确认版本的方法,就是输入kubeadm init指令后,等待错误信息打印到终端,按照错误信息中的提示,选择对应的镜像版本。

images=(  # 下面的镜像应该去除"k8s.gcr.io/"的前缀,版本换成上面获取到的版本
    kube-apiserver:v1.18.0
    kube-controller-manager:v1.18.0
    kube-scheduler:v1.18.0
    kube-proxy:v1.18.0
    pause:3.2
    etcd:3.4.3-0
    coredns:1.6.7
)

for imageName in ${images[@]} ; do
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
    docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
    docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done

  按照以上脚本,我们就可以下载所需的景象了,查看成功拉取的镜像:
在这里插入图片描述
重新开始初始化

kubeadm init --kubernetes-version=v1.18.0 \
 --pod-network-cidr=10.244.0.0/16 \
 --apiserver-advertise-address=192.168.140.134

  等待一段时间后,KubernetesMaster安装成功,显示如下信息:
在这里插入图片描述

  按照提示执行下面的命令,复制配置文件到普通的用户home目录下:

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

  这样就在Master上安装了Kubernetes,但是在集群内还是没哟可用的工作节点Node,并缺乏对容器网络的配置。这里需要注意的是kubeadm init命令执行完成后几行提示信息,其中包括了加入节点的指令(kubeadm join)和所需的Token
  此时,可以使用命令kubectl get -n kube-system configmap验证一下ConfigMap
在这里插入图片描述
  可以看到其中生成了名为kubeadm-configConfigMap对象。使用指令kubectl get node验证集群,可以看到集群中现在已经有了一个节点:

在这里插入图片描述

2.5 Node安装并加入集群

  此前,我们已经完成了在node上安装kubeadmkubelet的工作,且开启并设置了node节点上的dockerkubelet服务开机自启动。
加入node1
  在k8s-node1上运行如下指令将其加入集群:

kubeadm join 192.168.140.134:6443 --token a3mtet.9kpd8pol4fpxif6u \
    --discovery-token-ca-cert-hash sha256:a144bd098133691cc8e68bda61dcc10741d573696c6a2fd55a5e0b36272db1cb

  以上信息来自master初始化完成的最后几行打印信息,是非常重要的信息,在node节点加入集群式做安全验证等使用。可以看到添加成功:
在这里插入图片描述
  在master上运行kubectl get nodes,可以看到集群中此时已经有两个节点:
在这里插入图片描述
加入node2
  为kubeadm join命令生成配置文件,创建文件join-config.json,内容如下:
在这里插入图片描述
  运行指令kubeadm join --config=join-config.json,可以看到下图,加入成功。
在这里插入图片描述
  此时在master中使用指令kubectl get nodes查看集群中的节点已经达到三个:
在这里插入图片描述
  至此,k8s集群就搭建成功,但我们可以看到多有节点的STATUS均为NotReady,这是因为还没安装网络插件。此外,node节点的ROLES为<none>

3 安装网络插件

3.1 安装flannel

  这一步同样需要选用对应的网络插件版本。

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml

  运行结束后,可以看到k8s-master处于Ready状态而其他节点依然处于NotReady
在这里插入图片描述
  观察系统中所有pod的状态,并没有完全处于running状态。
在这里插入图片描述
  查看k8s-node1节点描述信息:

kubectl describe node k8s-node1

在这里插入图片描述

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

  为此我换了一种网络插件,期待能够消除异常。首先卸载刚刚安装的flannel网络插件:

kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml

3.2更换网络插件为calico

  重现安装calio网络插件:

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

  可以看到应用成功:
在这里插入图片描述
  在此声明,可以选择的网络插件有很多中,除了flannel,calico,还包括weave,cilium,Contiv-VPP等。
  但是在更换网络插件之后,node节点依然处于NotReady状态,为了查找原因,我查看一个处于ConatinerCreating状态的pod

 kubectl describe pod kube-proxy-n98pw -n kube-system

可以得到如下反馈信息:

Events:
  Type     Reason                  Age                      From                Message
  ----     ------                  ----                     ----                -------
  Normal   Scheduled               59m                      default-scheduler   Successfully assigned kube-system/kube-proxy-n98pw to k8s-node1
  Warning  FailedCreatePodSandBox  51m (x4 over 53m)        kubelet, k8s-node1  Failed to create pod sandbox: rpc error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause:3.2": Get https://k8s.gcr.io/v1/_ping: dial tcp 64.233.189.82:443: connect: connection refused
  Warning  FailedCreatePodSandBox  16m (x12 over 58m)       kubelet, k8s-node1  Failed to create pod sandbox: rpc error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause:3.2": Get https://k8s.gcr.io/v1/_ping: dial tcp 74.125.203.82:443: connect: connection refused
  Warning  FailedCreatePodSandBox  11m (x38 over 62m)       kubelet, k8s-node1  Failed to create pod sandbox: rpc error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause:3.2": Get https://k8s.gcr.io/v1/_ping: dial tcp 74.125.204.82:443: connect: connection refused
  Warning  FailedCreatePodSandBox  <invalid> (x5 over 25s)  kubelet, k8s-node1  Failed to create pod sandbox: rpc error: code = Unknown desc = failed pulling image "k8s.gcr.io/pause:3.2": Get https://k8s.gcr.io/v1/_ping: dial tcp 74.125.203.82:443: connect: connection refused

重点内容如下:
在这里插入图片描述
  原来是在k8s-node1k8s-node2节点上没有拉取pause:3.2kube-proxy:v1.18.0两个镜像,我们按照上文拉取镜像并重新tag的方法,在这两个节点上拉取所需的镜像。就可以看到非正常状态的pod由ContainerCreating状态变为(Init:ImagePullBackOff),再变为Running状态,最终达到的效果就是,所有pod处于Running状态:
在这里插入图片描述
以及所有的节点处于Ready状态:
在这里插入图片描述
  至此,我们终于完成了使用kubeadm在三台虚拟机节点上搭建k8s集群的工作。

  感受:虽然教程很多,但是感觉该踩的坑一个也没有少,不管高级的还是低级的错误。而且Google到的答案往往不是我们想要的,这时就应该静下心定位为题出现的位置,根据系统的报错一个个消灭问题,当然请教身边的大佬是个很高效的方法(在此致谢宇哥)。消灭问题的过程,不仅可以完善集群搭建,也可以增长经验。最后,投入了两天的集群搭建工作终于收尾了,也欢迎大家来交流!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值