一、前言

我们将现有的虚拟机称之为Node1,用作主节点。为了减少工作量,在Node1安装Kubernetes后,我们利用VirtualBox的虚拟机复制功能,复制出两个完全一样的虚拟机作为工作节点。三者角色为:

  • Node1:Master

  • Node2:Woker

  • Node3:Woker

二、安装Kubernetes

还是那句话,官方文档永远是最好的参考资料:https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/

但是,仅供参考,因为墙的原因,并不完全适用于我们天朝子民。下面将详细介绍在Node1上安装Kubernetes的过程,安装完毕后,再进行虚拟机的复制出Node2、Node3即可。

配置K8S的yum源

官方仓库无法使用,建议使用阿里源的仓库,执行以下命令添加kubernetes.repo仓库:

cat <<EOF > /etc/yum.repos.d/kubernetes.repo

[kubernetes]

name=Kubernetes

baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64enabled=1gpgcheck=0repo_gpgcheck=0gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg

        http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpgEOF

关闭swap、防火墙

上一篇文章已介绍关闭

关闭SeLinux

执行:setenforce 0

安装K8S组件

执行以下命令安装kubelet、kubeadm、kubectl:

yum install -y kubelet kubeadm kubectl

如下图所示:

image.png

配置kubelet的cgroup drive

确保docker 的cgroup drive 和kubelet的cgroup drive一样:

docker info | grep -i cgroup

cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

若显示不一样,则执行:

sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
systemctl daemon-reload

如图:

image.png

启动kubelet

注意,根据官方文档描述,安装kubelet、kubeadm、kubectl三者后,要求启动kubelet:
systemctl enable kubelet && systemctl start kubelet
但实际测试发现,无法启动,报如下错误:

image.png

查看日志发现是没有证书:

unable to load client CA file /etc/kubernetes/pki/ca.crt: open /etc/kubernetes/pki/ca.crt: no such file or directory

image.png

我在网上没有找到解决方法,但无意测试中发现,后面的kubeadm init操作会创建证书。也就是说,现在无法启动并不影响后续操作,继续!

下载K8S的Docker镜像

本文使用的是K8S官方提供的kubeadm工具来初始化K8S集群,而初始化操作kubeadm init会默认去访问谷歌的服务器,以下载集群所依赖的Docker镜像,因此也会超时失败,你懂得。

但是,只要我们可以提前导入这些镜像,kubeadm init操作就会发现这些镜像已经存在,就不会再去访问谷歌。网上有一些方法可以获得这些镜像,如利用Docker Hub制作镜像等,但稍显繁琐。

这里,我已将初始化时用到的所有Docker镜像整理好了,镜像版本是V1.10.0。推荐大家使用。

  • 地址:https://pan.baidu.com/s/11AheivJxFzc4X6Q5_qCw8A

  • 密码:2zov

准备好的镜像如下图所示:

image.png

K8S更新速度很快,截止目前最新版本是V1.10.2。本人提供的镜像会越来越旧,需要最新版本的读者可以根据网上教材自行制作

脚本docker_images_load.sh用于导入镜像:

docker load < quay.io#calico#node.tardocker load < quay.io#calico#cni.tardocker load < quay.io#calico#kube-controllers.tardocker load < k8s.gcr.io#kube-proxy-amd64.tardocker load < k8s.gcr.io#kube-scheduler-amd64.tardocker load < k8s.gcr.io#kube-controller-manager-amd64.tardocker load < k8s.gcr.io#kube-apiserver-amd64.tardocker load < k8s.gcr.io#etcd-amd64.tardocker load < k8s.gcr.io#k8s-dns-dnsmasq-nanny-amd64.tardocker load < k8s.gcr.io#k8s-dns-sidecar-amd64.tardocker load < k8s.gcr.io#k8s-dns-kube-dns-amd64.tardocker load < k8s.gcr.io#pause-amd64.tardocker load < quay.io#coreos#etcd.tardocker load < quay.io#calico#node.tardocker load < quay.io#calico#cni.tardocker load < quay.io#calico#kube-policy-controller.tardocker load < gcr.io#google_containers#etcd.tar

将镜像与该脚本放置同一目录,执行即可导入Docker镜像。运行docker images,如下图所示,即表示镜像导入成功:

image.png

三、复制虚拟机

前言中提到,当Node1的Kubernetes安装完毕后,就需要进行虚拟机的复制了。

复制

复制前需要退出虚拟机,我们选择“正常关机”。右键虚拟机点击复制:

image.png

如上,新的节点命名为CentOS-Node2,注意一定要勾选"重新初始化网卡Mac地址"。点击“复制”,稍等几分钟,即可完成复制:

image.png

依此法再复制一个节点命名为CentOS-Node3

添加网卡

复制结束后,如果直接启动三个虚拟机,你会发现每个机子的IP地址(网卡enp0s3)都是一样的:

image.png

这是因为复制虚拟机时连同网卡的地址也复制了,这样的话,三个节点之间是无法访问的。因此,我建议复制结束后,不要马上启动虚拟机,而先要为每一个虚拟机添加一个网卡,用于节点间的互通访问。

如下图所示,连接方式选择“Host-Only”模式:

image.png

网卡添加结束后,启动三个虚拟机,查看各个IP。以主节点Node1为例,运行ip addr

image.png

可以看到,网卡enp0s8为新添加的网卡2,IP地址为192.168.56.101。三个节点IP分别为:

  • Node1:192.168.56.101

  • Node2:192.168.56.102

  • Node3:192.168.56.103

在这三个节点中,可以使用这些IP互相ping一下,确保网络连通正常。

另外,同上一节所述,建议启用端口转发功能,使用Xshell连接到Node1和Node2的终端。

设置虚拟机

网卡添加结束后,即可启动三个虚拟机,我们需要进行一些简单的设置,以主节点Node1为例:

  • 编辑/etc/hostname,将hostname修改为k8s-node1

  • 编辑/etc/hosts,追加内容 IP k8s-node1

以上IP为网卡2的IP地址,修改后重启生效。另外两个节点修改同理,主机名分别为k8s-node2k8s-node3

四、创建集群

kubeadm介绍

前面的工作都准备好后,我们就可以真正的创建集群了。这里使用的是官方提供的kubeadm工具,它可以快速、方便的创建一个K8S集群。kubeadm的具体介绍大家可以参考官方文档:https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/

截止目前,kubeadm尚处于beta状态,官方暂时不推荐在生产环境使用,但是预计今年会推出GA版本。这里,我建议大家尽量使用kubeadm,相对于纯手动部署效率更高,也不容易出错。

创建集群

在Master主节点(k8s-node1)上执行:
kubeadm init --pod-network-cidr=192.168.0.0/16 --kubernetes-version=v1.10.0 --apiserver-advertise-address=192.168.56.101

含义:
1.选项--pod-network-cidr=192.168.0.0/16表示集群将使用Calico网络,这里需要提前指定Calico的子网范围
2.选项--kubernetes-version=v1.10.0指定K8S版本,这里必须与之前导入到Docker镜像版本v1.10.0一致,否则会访问谷歌去重新下载K8S最新版的Docker镜像
3.选项--apiserver-advertise-address表示绑定的网卡IP,这里一定要绑定前面提到的enp0s8网卡,否则会默认使用enp0s3网卡
4.若执行kubeadm init出错或强制终止,则再需要执行该命令时,需要先执行kubeadm reset重置

执行结果:

[root@k8s-node1 ~]# kubeadm init --pod-network-cidr=192.168.0.0/16 --kubernetes-version=v1.10.0 --apiserver-advertise-address=192.168.56.101[init] Using Kubernetes version: v1.10.0[init] Using Authorization modes: [Node RBAC]
[preflight] Running pre-flight checks.
    [WARNING SystemVerification]: docker version is greater than the most recently validated version. Docker version: 18.03.1-ce. Max validated version: 17.03
    [WARNING FileExisting-crictl]: crictl not found in system path
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [k8s-node1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.56.101]
[certificates] Generated apiserver-kubelet-client certificate and key.
[certificates] Generated etcd/ca certificate and key.
[certificates] Generated etcd/server certificate and key.
[certificates] etcd/server serving cert is signed for DNS names [localhost] and IPs [127.0.0.1]
[certificates] Generated etcd/peer certificate and key.
[certificates] etcd/peer serving cert is signed for DNS names [k8s-node1] and IPs [192.168.56.101]
[certificates] Generated etcd/healthcheck-client certificate and key.
[certificates] Generated apiserver-etcd-client certificate and key.
[certificates] Generated sa key and public key.
[certificates] Generated front-proxy-ca certificate and key.
[certificates] Generated front-proxy-client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests".
[init] This might take a minute or longer if the control plane images have to be pulled.
[apiclient] All control plane components are healthy after 24.006116 seconds
[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[markmaster] Will mark node k8s-node1 as master by adding a label and a taint
[markmaster] Master k8s-node1 tainted and labelled with key/value: node-role.kubernetes.io/master=""[bootstraptoken] Using token: kt62dw.q99dfynu1kuf4wgy
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: kube-dns
[addons] Applied essential addon: kube-proxy Your Kubernetes master has initialized successfully! To start using your cluster, you need to run the following as a regular user:   mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of machines by running the following on each nodeas root:   kubeadm join 192.168.56.101:6443 --token kt62dw.q99dfynu1kuf4wgy --discovery-token-ca-cert-hash sha256:5404bcccc1ade37e9d80831ce82590e6079c1a3ea52a941f3077b40ba19f2c68

可以看到,提示集群成功初始化,并且我们需要执行以下命令:

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

另外, 提示我们还需要创建网络,并且让其他节点执行kubeadm join...加入集群。

创建网络

如果不创建网络,查看pod状态时,可以看到kube-dns组件是阻塞状态,集群时不可用的:

image.png

大家可以参考官方文档,根据需求选择适合的网络,这里,我们使用Calico(在前面初始化集群的时候就已经确定了)。

根据官方文档,在主节点上,需要执行如下命令:
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml

但需要注意的是:

本文实验时所使用的calico的docker镜像版本为v3.1.0,如下图所示

image.png

但截至本文撰写时,calico.yaml文件中版本已升级为v3.1.1。因此我们需要下载calico.yaml,手动编辑文件修改为v3.1.0并重新创建网络。否则,执行kubectl apply命令时,会重新拉取v3.1.1的镜像导致超时失败。同时,kube-dns模块也会因为网络无法创建而Pending:

image.png

确保版本一致后,执行成功则提示:

image.png

image.png

五、集群设置

将Master作为工作节点

K8S集群默认不会将Pod调度到Master上,这样Master的资源就浪费了。在Master(即k8s-node1)上,可以运行以下命令使其作为一个工作节点:
kubectl taint nodes --all node-role.kubernetes.io/master-

利用该方法,我们可以不使用minikube而创建一个单节点的K8S集群

执行成功后提示:

image.png

将其他节点加入集群

在其他两个节点k8s-node2和k8s-node3上,执行主节点生成的kubeadm join命令即可加入集群:
kubeadm join 192.168.56.101:6443 --token kt62dw.q99dfynu1kuf4wgy --discovery-token-ca-cert-hash sha256:5404bcccc1ade37e9d80831ce82590e6079c1a3ea52a941f3077b40ba19f2c68

加入成功后,提示:

image.png

验证集群是否正常

当所有节点加入集群后,稍等片刻,在主节点上运行kubectl get nodes可以看到:

image.png

如上,若提示notReady则表示节点尚未准备好,可能正在进行其他初始化操作,等待全部变为Ready即可。

大家可能会好奇,我们前面使用的是v1.10.0,为何这里版本是v1.10.2。实际上,这里显示是每个节点上kubelet程序的版本,即先前使用yum安装时的默认版本,是向下兼容的。而v.1.10.0指的是K8S依赖的Docker镜像版本,与kubeadm init命令中一定要保持一致。

另外,建议查看所有pod状态,运行kubectl get pods -n kube-system

image.png

如上,全部Running则表示集群正常。至此,我们的K8S集群就搭建成功了。走!去按摩一下颈椎,放松一下,真累啊!

搭建K8S集群的更多相关文章

  1. kubeadm 搭建 K8S集群

    kubeadm是K8s官方推荐的快速搭建K8s集群的方法. 环境: Ubuntu 16.04 1 安装docker Install Docker from Ubuntu’s repositories: ...

  2. kubeadm搭建K8s集群及Pod初体验

    基于Kubeadm 搭建K8s集群: 通过上一篇博客,我们已经基本了解了 k8s 的基本概念,也许你现在还是有些模糊,说真的我也是很模糊的.只有不断地操作去熟练,强化自己对他的认知,才能提升境界. 我 ...

  3. 教你用multipass快速搭建k8s集群

    目录 前言 一.multipass快速入门 安装 使用 二.使用multipass搭建k8s集群 创建3台虚拟机 安装master节点 安装node节点 测试k8s集群 三.其他问题 不能拉取镜像:报 ...

  4. 1 搭建K8s集群

    官网:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing ...

  5. 从0到1搭建k8s集群系列1:安装虚拟机及docker

    前言 本系列文章记录了本人学习k8s集群搭建的过程,从k8s基本组件的安装.到部署mysql服务到k8s集群.部署web项目到k8s集群以及安装可视化界面管理工具kuboard. 因为k8s的组件安装 ...

  6. CentOS7 使用 kubeadm 搭建 k8s 集群

    一 安装Docker-CE 前言 Docker 使用越来越多,安装也很简单,本次记录一下基本的步骤. Docker 目前支持 CentOS 7 及以后的版本,内核要求至少为 3.10. Docker ...

  7. Rancher 下图形界面 搭建 K8S 集群

    首先我们准备4台 2核3G 的 centos 7 温馨提示:先安装好一台 CentOS 的虚拟机,并且安装好 docker,永久关闭防火墙. 再这个基础上我们分别克隆出四台 Rancher.K8S1. ...

  8. 关于使用kubeoperator搭建k8s集群使用containerd作为容器运行时,从自己搭建的habor仓库拉取镜像的有关说明

    1.kubepi界面添加habor仓库信息,并授权给k8s集群 这一步的操作是当在工作负载选择从harbor仓库拉取镜像时会自动创建有关的secrets信息,从而不用事先手动创建了(有别于kuboar ...

  9. rancher2.X搭建k8s集群平台

    一, 新版特性 Rancher 1.6支持多种容器编排框架,包括Kubernetes.Mesos.Docker Swarm,默认的基础编排引擎是Cattle,Cattle极简的操作体验受到了大量开源社 ...

随机推荐

  1. 微服务与SpringCloud简介

    A.官网 https://spring.io/projects/spring-cloud B.简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用 ...

  2. js数据类型及判断数据类型

    众所周知,js有7种数据类型 1. null 2. undefined 3. boolean 4. number 5. string 6. 引用类型(object.array.function) 7. ...

  3. Wenaox 一款轻量性能好的微信小程序状态管理库

    感慨一下!!! 从开始开发 wenaox 从开始到现在,,时不时更新一下,改一改 bug,却发现已经快 1 年了 orz 虽然很少人用 hhh,但偶尔也会有人提一些问题,我就知道还有人用的~ 感兴趣的 ...

  4. Django ORM整理

    字段类型 # 自增长 Auto = models.AutoField() BigAuto = models.BigAutoField() # 二进制 Binary = models.BinaryFie ...

  5. fastjson反序列化漏洞研究(下)

    之前的文章显示字符太多 拒绝显示  只好分为两篇了 这样我们只需要找到可以利用的类,构造poc链就好了,这个和以前的java反序列化漏洞类似,先不说.网上最早的poc是使用com.sun.org.ap ...

  6. org.springframework.dao.DuplicateKeyException: 问题

    转自:https://blog.51cto.com/chengxuyuan/1786938 org.springframework.dao.DuplicateKeyException: a diffe ...

  7. python(函数调用)

    1.在原文件中调用 def abc(x,y): print x + y abc(2,3) #直接通过函数名加括号进行调用传参 2.同一个包(package)下面调用不同文件中的函数 "&qu ...

  8. 计算机网络原理,TCP&UDP

    UDP伪首部:计算校验和时会用到,然后实际传输过程中里包含的IP地址没有什么用. UDP校验和计算:求数值之和,如果溢出回卷,最后求出反码;UDP伪首部,UDP首部,应用层数据相加 tcp报文,最短2 ...

  9. 数据库类型对应Java语言类型表

    下表列出了基本 SQL Server.JDBC 和 Java 编程语言数据类型之间的默认映射: SQL Server 类型 JDBC 类型 (java.sql.Types) Java 语言类型 big ...

  10. 【独家】K8S漏洞报告 | CVE-2019-1002101解读

    kubectl cp漏洞CVE-2019-1002101分析 Kube-proxy IPVS添加flag ipvs-strict-arp 近期bug fix数据分析 ——本期更新内容 kubectl ...