通过kubeadm加vip安装一个简单的k8s集群并实现集群的高可用

通过kubeadm安装一个简单的k8s集群

部署工具:

使用批量部署工具如(ansible/ saltstack)安装(使用较多)、手动二进制、kubeadm(使用较多)官方提供的一个安装部署工具,会将管理端都以容器的方式去运行、apt-get/yum 等方式安装,以守护进程的方式启动在宿主机上,类似于是 Nginx 一样使用service 脚本启动。K8s一年会更新4个大版本,更新较快。

kubeadm

使用 k8s 官方提供的部署工具 kubeadm 自动安装,需要在 master 和 node 节点上安装docker 等组件,然后初始化,把管理端的控制服务和 node 上的服务都以pod 的方式运行。

kubeadm 介绍:

https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm/

#V1.10 版 本 kubeadm 介 绍 : https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.m d

安装注意事项:

注意:禁用swap,selinux,iptables

部署过程分为以下几个大部分:

  • 进行初始化:kubeadm init,这个init主要是初始化master将master上的服务都要装上
  • 配置认证:基于配置文件来做,在master上能够由权限通过K8S进行某些操作
  • 添加node节点

kubeadm 概述

Kubeadm 是一个工具,它提供了 kubeadm init (初始化master)以及 kubeadm join 这两个命令作为快速创建 kubernetes 集群的最佳实践。

 

kubeadm 通过执行必要的操作来启动和运行一个最小可用的集群。它被故意设计为只关心启动集群,而不是之前的节点准备工作。同样的,诸如安装各种各样值得拥有的插件,例如 Kubernetes Dashboard、监控解决方案以及特定云提供商的插件,这些都不在它负责的范围。相反,我们期望由一个基于 kubeadm 从更高层设计的更加合适的工具来做这些事情;并且,理想情况下,使用 kubeadm 作为所有部署的基础将会使得创建一个符合期望的集群变得容易。

 

  • kubeadm init(该命令使用较多)启动一个 Kubernetes 主节点,master
  • kubeadm join(该命令使用较多)启动一个 Kubernetes 工作节点并且将其加入到集群node节点
  • kubeadm upgrade(该命令使用较多)更新一个 Kubernetes 集群到新版本(用于K8S的版本升级)
  • kubeadm config如果使用7.x 或者更低版本的 kubeadm 初始化集群,您需要对集群做一些配置以便使用 kubeadm upgrade 命令
  • kubeadm token管理 kubeadm join 使用的令牌,这个令牌是一个临时的字符串,有效期默认为24小时,超出有效期之后,要是哦那个kubeadm token这个命令重新获取,所以我们创建了一个K8S集群以后,后期想将一个新的node节点加进去的话会再次使用kubeadm token命令让他生成一个零时的认证,然后再加到集群中
  • kubeadm reset还原 kubeadm init 或者 kubeadm join 对主机所做的任何更改,其实就是整个环境进行初始化,
  • kubeadm version打印 kubeadm 版本
  • kubeadm alpha预览一组可用的新功能以便从社区搜集反馈

部署架构及kubernetes 部署过程

Master1:172.18.17.101

Master2:172.18.17.102

vip地址:172.18.17.188

Node1:172.18.17.103

Node2:172.18.17.104

service的地址为:172.31.0.0/16

pod的ip为10.10.0.0/16

这个结构就是我们有两个管理端(两个master)来实现master的高可用,当其中一个master当了之后,我们的k8s集群还能使用。我们让这两个master中间通过VIP来实现高可用。我们访问K8S都是直接访问VIP的地址,这个VIP地址我们通过keepalived让他在master1和master2上来做高可用,默认情况下让他跑在master1上,如果master1宕机了让他飘到master2上。这个VIP在那个master上就由那个master来提供K8S的服务,这是一种高可用的方式。在往下就是node节点了。这些node节点就是正真运行容器的地方,当我们要创建容器的时候就是先访问到VIP地址172.18.17.188,基于这个vip地址来下发指令,让他创建各个容器,这些所有的node节点都是被这个vip地址172.18.17.188所管理的。

具体步骤:

部署版本为当前次新版本,因为后面需要使用 kubeadm 做 kubernetes 版本升级演示。

1、在master 先安装 kubelet,docker,kubeadm

2、master 节点运行 kubeadm init 初始化命令

3、验证 master 节点状态

4、在各个 node 节点安装 kubeadm:为了在node节点上执行kubeadm join 命令将node节点指定到某个master上、kubectl、docker 环境

5、在 node 节点使用 kubeadm 命令将自己加入 k8s master(需要使用 master 生成token 认证有效期为24小时)

6、到master节点上验证 node 节点状态是否加入该集群

7、启动nginx容器测试访问页面。

在各个master 节点安装 docker

#在两个master上安装必要的一些系统工具

sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common

在两个master上安装 GPG 证书

curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

写入软件源信息

sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

更新并安装 Docker-CE #

apt-get -y update

apt-cache madison docker-ce

查看安装的 Docker 版本

在两台master上面安装docker5:18.09.9~3-0~ubuntu- bionic版本

apt-get -y install docker-ce=5:18.09.9~3-0~ubuntu-bionic docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic 

启动docker并设置为开机启动

systemctl start docker && systemctl enable docker

查看docker版本

docker version

master 节点配置 docker 加速器:

在 /etc/目录下创建一个docker的文件

sudo mkdir -p /etc/docker

vim /etc/docker/daemon.json
{
 "registry-mirrors":["https://hpqoo1ip.mirror.aliyuncs.com"]
}

重新加载docker服务

sudo systemctl daemon-reload
sudo systemctl restart docker

master节点配置阿里云仓库地址:

配置阿里云镜像的kubernetes 源(用于安装kubelet kubeadm kubectl 命令)

https://developer.aliyun.com/mirror/kubernetes?spm=a2c6h.13651102.0.0.53322f70ezisiM

我们是ubuntu的系统所以使用ubuntu的配置方法

Master节点上配置

apt-get update && apt-get install -y apt-transport-https

Master节点上添加gpg的证书

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - 

添加阿里云K8S镜像地址

vim /etc/apt/sources.list.d/kubernetes.list

deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main 

在这两个master节点上升级软件包将K8S添加经来

apt update

master节点安装指定版本为1.16.1的kubeadm和kubelet及 kubectl命令:

升级完了软件包列表之后,我们开始安装kuberadm等命令。

使用#apt-cache madison kubeadm命令查看kubeadm的版本信息

apt-cache madison kubeadm kubelet kubectl

在两个master节点上安装指定的1.16.1版本

apt install kubectl=1.16.1-00 kubelet=1.16.1-00  kubeadm=1.16.1-00 -y

在两个master节点安装keepalived实现K8S集群的高可用

apt install keepalived -y

配置VIP文件

Keepalived默认是没有配置文件的,所以我们需要将他的模板配置文件拷贝到/etc/keeplived下

使用find / -name keepalived*找到模板文件

find / -name keepalived*

拷贝到/etc/下并改名为keepalived.conf

cp /usr/share/doc/keepalived/samples/keepalived.conf.vrrp /etc/keepalived/keepalived.conf

编辑/etc/keepalived/keepalived.conf 文件将我们的VIP添加进去

vim /etc/keepalived/keepalived.conf 

! Configuration File for keepalived

global_defs {
   notification_email {
     acassen
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    garp_master_delay 10
    smtp_alert
    virtual_router_id 17
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.18.18.188 dev eth0 label eth0:1
    }
}

启动master1节点上的keepalived服务观察vip是否生成

systemctl restart keepalived.service

通过ip a查看已经生成

然后再将这个keepalived配置文件拷贝到master2节点

scp /etc/keepalived/keepalived.conf 172.18.18.102:/etc/keepalived/keepalived.conf

在master2上修改keepalived配置文件,调低优先级

vim /etc/keepalived/keepalived.conf

重启master2节点上的keepalived服务

systemctl restart keepalived.service

验证VIP是否能够实现飘逸高可用

现在我们将master1节点的keepalived服务宕了,观察VIP是否能够漂移到master2上

systemctl stop keepalived.service

Master2节点观察,vip已经飘移过来从而实现了高可用

验证 master 节点 kubelet 服务

安装完了之后会默认启动kbelet 以下报错:

无法加载Kubelet配置文件/var/lib/kubelet/config.yaml,错误无法读取kubelet配置文件“ /var/lib/kubelet/config.yaml”,错误:打开/var/lib/kubelet/config.yaml : 无此文件或目录,这个报错可以忽略,没有关系

kubeadm 命令使用:

命令使用:

https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm/

集群初始化:

https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init/

 

查看kubeadm init 的选项帮助

kubeadm init --help

Kubeadm的必选项:

–apiserver-advertise-address string #API Server 将要监听的监听地址,为本机IP,这个地址是给API入口去使用的,但是我们这里是VIP就写VIP地址

–apiserver-bind-port int32 #API Server 绑定的端口,默认为 6443是给API server去使用的

–apiserver-cert-extra-sans stringSlice #可选的证书额外信息,用于指定 API Server

的服务器证书。可以是IP 地址也可以是DNS 名称。(一般不用指定)

Kubeadm的可选项:

–cert-dir string #证书的存储路径,这个路径不指定的话就会默认放到 /etc/kubernetes/pki。这些证书在使用kuberadm安装的时候会自动生成

 

–config string #kubeadm 配置文件的路径。默认生成

 

–ignore-preflight-errors strings #可以忽略检查过程 中出现的错误信息,比如忽略 swap,如果为 all 就忽略所有(一般我们都会让他检查一遍)

 

–image-repository string #设置一个镜像仓库,默认为k8s.gcr.io(默认是谷歌的镜像)这个镜像仓库在国内是打不开的。这个镜像仓库必须改为国内的地址。

 

–kubernetes-version string #选择 k8s 版本,默认为当前最新的。我们一般会装指定的版本,所以这个参数是必须要指定的

 

–node-name string #指定 node 名称。默认会取主机名,这个不需要动,在整个K8S里面我们的主机名要保证不一样

 

–pod-network-cidr #设置 pod ip 地址范围,这个是给容器去使用的ip地址

 

–service-cidr #设置 service 网络地址范围,这个是内部service网络的地址端,相当于K8S的内部负载均衡。

 

–service-dns-domain string #设置 k8s 内部域名,默认为 cluster.local,会有相应的 DNS 服务(kube-dns/coredns)解析生成的域名记录。

 

–skip-certificate-key-print #不打印用于加密的key 信息,这个值我们一般都让它打印出来

 

–skip-phases strings #要跳过哪些阶段一般不用加

 

–skip-token-print #跳过打印token 信息一般不用加

 

–token #指定 token,默认情况下会随机生成一个token,一般我们也不设置

 

–token-ttl #指定token 过期时间,默认为 24 小时,0 为永不过期一般不设置这个值

 

–upload-certs #更新证书 也不用设置

 

#全局选项也不用设置

–log-file string #日志路径

–log-file-max-size uint #设置日志文件的最大大小,单位为兆,默认为 1800 兆,0 为没有限制

–rootfs #宿主机的根路径,也就是使用绝对路径

–skip-headers #如果为 true,在 log 日志里面不显示标题前缀

–skip-log-headers #如果为 true,在 log 日志里里不显示标题

 

两个master节点镜像下载:

镜像最好提前在 master 节点下载下来,但是镜像默认使用 Google 的镜像仓库, 所以国内无法直接下载,但是可以通过阿里云的镜像仓库把镜像先提前下载下来, 可以避免后期因镜像下载异常而导致k8s 部署异常。

 

查看安装指定的K8S需要那些镜像

kubeadm config images list --kubernetes-version v1.16.1

k8s.gcr.io/kube-apiserver:v1.16.1

k8s.gcr.io/kube-controller-manager:v1.16.1

k8s.gcr.io/kube-scheduler:v1.16.1

k8s.gcr.io/kube-proxy:v1.16.1

k8s.gcr.io/pause:3.1

k8s.gcr.io/etcd:3.3.15-0

k8s.gcr.io/coredns:1.6.2

将镜像仓库修改为阿里云的镜像仓库

 

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.16.1

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.16.1

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.16.1

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.16.1

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.3.15-0

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.2

高可用 master1节点上初始化:

首先基于keepalived 实现高可用VIP,然后实现基于VIP 的高可用master。初始化仅一台master上初始化即可。所以我们的master2节点主机就不用初始化了,在master1初始化之后再将master2节点加到里面即可

参数解析:

–apiserver-advertise-address=172.18.18.101:我们的master节点主机ip

–control-plane- endpoint=172.18.18.188:用户请求访问ip

–apiserver-bind-port=6443:对外暴露端口

–kubernetes-version=v1.16.1:K8S版本号

–pod- network-cidr=10.10.0.0/16:后端pod服务器内部ip地址池

–service-cidr=172.31.0.0/16:service ip地址池

–service-dns-domain=linux38.local:DNS解析域名

— image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers:使用的是阿里镜像仓库

–ignore-preflight- errors=swap:忽略swap分区

 

基于命令初始化高可用 master 方式:

kubeadm init --apiserver-advertise-address=172.18.18.101 --control-plane-endpoint=172.18.18.188 --apiserver-bind-port=6443 --kubernetes-version=v1.16.1 --pod-network-cidr=10.10.0.0/16 --service-cidr=172.31.0.0/16 --service-dns-domain=linux38.local --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --ignore-preflight-errors=swap

但是这个时候他会报错

failed with error: Get http://localhost:10248/healthz: dial tcp [::1]:10248: connect: connection refused

 

然后我们查看系统日志。它报错的原因是我们不支持交换分区

vim /var/log/syslog

swap on is not supported,

 

关闭swap交换分区并重新执行初始化

打开将swap注释掉

vim /etc/fstab

swapoff -a

 

执行kubeadm reset将这个K8S安装过程恢复到初始化,因为我们刚才已经安装了一些文件或者目录,这会导致K8s环境失效

kubeadm reset

 

全部清除之后再执行初始化。

kubeadm init --apiserver-advertise-address=172.18.18.101 --control-plane-endpoint=172.18.18.188 --apiserver-bind-port=6443 --kubernetes-version=v1.16.1 --pod-network-cidr=10.10.0.0/16 --service-cidr=172.31.0.0/16 --service-dns-domain=linux38.local --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --ignore-preflight-errors=swap

 

 

初始化完了之后系统会提示:

您的Kubernetes控制面板已成功初始化!

 

要开始使用群集,您需要以普通用户身份运行以下命令:

 

mkdir -p $ HOME / .kube

sudo cp -i /etc/kubernetes/admin.conf $ HOME / .kube / config

sudo chown $ {id -u):$ {id -g)$ HOME / .kube / config

 

现在,您应该将Pod网络部署到群集。

使用列出的选项之一运行“ kubectl apply -f [podnetwork] .yaml”:

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

 

现在,您可以通过复制证书颁发机构来加入任意数量的控制平面节点

和每个节点上的服务帐户密钥,然后以root用户身份运行以下命令:

 

kubeadm join 172.18.18.188:6443 –token wm5tc1.hyo3jes43w37hmii \

–discovery-token-ca-cert-hash sha256:a28c738ea002fbfbfa0e4ce8843fb470df4e053a2293d031aac3dc211aeaf81f \

-控制平面

 

然后,您可以通过在每个根上运行以下命令来加入任意数量的工作节点:

 

kubeadm join 172.18.18.188:6443 –token wm5tc1.hyo3jes43w37hmii \

–discovery-token-ca-cert-hash sha256:a28c738ea002fbfbfa0e4ce8843fb470df4e053a2293d031aac3dc211aeaf81f

执行K8S初始化之后的提示执行这三条命令

kdir -p $HOME/.kube 这是再当前目录下创建一个.kube文件

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config 然后将admin.conf文件拷贝到.kube中

sudo chown $(id -u):$(id -g) $HOME/.kube/config 这是添加这个用户的组和用户id信息

 

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

 

执行kubectl get node命令来获取节点信息,这个命令获取到的信息就是通过.kube/config文件得到的。

kubectl get node

 

kubectl get pod -A

查看所有的pod状态会发现有两个coredns的pod状态是待定(Pending)的

 

下载kube-flannel.yml文件并编辑该文件解决pod的Pending状态

下载kube-flannel.yml文件

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

在这个文件中找打10.244.0.0/16这一行改为我们的pod的ip地址段即可10.10.0.0/16

vim kube-flannel.yml

然后执行这个kube-flannel.yml将pod的ip生成

kubectl apply -f kube-flannel.yml

 

再次查看因为pod的ip网段已经修改所以我们的pod状态就为 Running(准备状态)

kubectl get pod -A

Master2节点上添加新的K8S管理节点

执行下面这条命令将我们的master2主机添加到K8S管理节点中,是通过token验证,但是这个时候他会报错,因为我们的swap分区没有关

kubeadm join 172.18.18.188:6443 --token wm5tc1.hyo3jes43w37hmii \
--discovery-token-ca-cert-hash sha256:a28c738ea002fbfbfa0e4ce8843fb470df4e053a2293d031aac3dc211aeaf81f \
--control-plane

 

关闭master2节点上的swap分区,注释掉

vim /etc/fstab

使swap生效

swapoff -a

即使将swap关了之后还是不行,因为我们需要添加–control-plane  –certificate-key 参数来实现key的验证

安装好了kubeadm主机生成证书用于添加新控制节点:

在已经安装好了kubeadm主机(master1)上使用下面条命令生成证书,这是让他打出了他的token和他的hash值这里得到的是

b6f956a27786dd7a0041f24168ceac4b32315896cb24fef7bdd295f7f244d2bc的key

 

kubeadm init phase upload-certs --upload-certs

 

注意他加的时候是用VIP的地址加进去的,而不是使用本地地址,使用本地地址是加不进去的

–control-plane –certificate-key:这个参数后面加我们再master1节点上的到的key

kubeadm join 172.18.18.188:6443 --token wm5tc1.hyo3jes43w37hmii --discovery-token-ca-cert-hash sha256:a28c738ea002fbfbfa0e4ce8843fb470df4e053a2293d031aac3dc211aeaf81f --control-plane --certificate-key b6f956a27786dd7a0041f24168ceac4b32315896cb24fef7bdd295f7f244d2bc

再master2节点上安装完了之后系统会提示

Run ‘kubectl get nodes’ to see this node join the cluster.解释为:运行“ kubectl获取节点”以查看该节点加入集群。

 

然后再master1节点上输入kubectl get node指令会发现master2已经加到该K8S集群中

kubectl get node

在master2节点上执行K8S初始化之后的提示执行这三条命令

在三条命令是加上之后才能够使用kubectl get node -A命令查看节点集群节点信息,他起到了一个验证的作用,不然他会报错为连接拒绝

The connection to the server localhost:8080 was refused – did you specify the right host or port?

(与服务器localhost:8080的连接被拒绝-您是否指定了正确的主机或端口?)

 

kdir -p $HOME/.kube 这是再当前目录下创建一个.kube文件

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config 然后将admin.conf文件拷贝到.kube中

sudo chown $(id -u):$(id -g) $HOME/.kube/config 这是添加这个用户的组和用户id信息

 

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

kubectl get node -A

验证master能否实现高可用

现在我们将master1节点上的keepalived服务停了,让他飘到master2节点上,然后是否能够使用kubectl命令

停掉master1节点的keepalived服务

systemctl stop keepalived.service

Master2节点上VIP已经漂移过来

 

Kubectl命令已经可以正常使用

以上就是两个master节点的搭建过程。下面我们开始搭建两个node节点

添加两个 node 节点:

只要将node节点加进来之后我们就可以跑容器了和跑服务了。各 node 节点都要安装 docker kubeadm kubelet ,因此都要重新执行安装 docker kubeadm kubelet 的步骤,即配置 apt 仓库、配置 docker 加速器、安装命令、启动kubelet 服务。

 

在两个node节点上安装docker服务

sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common

两个node节点验证GPG证书

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

这两个node节点写入软件园信息

sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

安装18.09版本的docker
apt-get -y install docker-ce=5:18.09.9~3-0~ubuntu-bionic docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic

启动docker并设置为开机启动

systemctl start docker && systemctl enable docker

两个node节点安装阿里云的K8S的镜像源

apt-get update && apt-get install -y apt-transport-https

给这两个node节点写入阿里镜像源

vim /etc/apt/sources.list.d/kubernetes.list

deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main

添加阿里云的镜像key文件

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -

更新这两个node节点的软件包

apt-get update

再node节点上安装kubeadm等组件

apt install kubeadm=1.16.1-00 kubectl=1.16.1-00 kubelet=1.16.1-00

启动kubelet服务,并设置为开机启动

systemctl start kubelet && systemctl enable kubelet

添加node到K8S集群中

关闭这两个node节点的swap交换分区功能

vim /etc/fstab

 

使用swapoff  -a是关闭交换分区生效

swapoff  -a

使用token将两个node节点加入到K8S集群中

kubeadm join 172.18.18.188:6443 --token wm5tc1.hyo3jes43w37hmii     --discovery-token-ca-cert-hash sha256:a28c738ea002fbfbfa0e4ce8843fb470df4e053a2293d031aac3dc211aeaf81f

验证node节点是否加入到K8S集群中

回到master1节点上输入kubectl get node -A命令查看我们的两个node节点已经加入,并且状态为ready(准备状态)

kubectl get node -A

后期添加新的node节点的时候也是这样,安装docker安装K8S等命令,添加到k8s集群就可以了