那时候刚好下着雨,柏油路面湿冷冷的,还闪烁着青、黄、红颜色的灯火。



使用 kubeadm 搭建一套kubernetes集群


使用 kubeadm 搭建一套kubernetes集群

上一篇我们讲了一下《如何基于Golang设计一套微服务架构》,那么这篇我们来填上次挖的一些坑。

为了实现微服务架构, 我们需要搭建一个基础的平台。

在安装前需做些设置让系统环境一致,确保后面顺利安装。

以下安装方式或配置方式仅限于在开发、测试环境快速度使用,生产不建议这么搞,需要把一些组件独立拆分出来。

硬件、系统配置

本套硬件使用的是PC,每台配置有1T硬盘。因资源不够等问题,我们会把其他工具也分别部署在这几台电脑上。

角色 配置 IP HOSTNAME
master 8核32G 10.106.145.44 dev-01
node 8核16G 10.106.145.43 dev-03
node 8核16G 10.106.145.45 dev-02

可能需要在 /etc/hosts 加入你每个节点的ip及指向的名称

  • 10.106.145.43 dev-03
  • 10.106.145.44 dev-01
  • 10.106.145.45 dev-02

系统设置

以下这几项很重要

为了减少一些不必要的麻烦,我们先把防火墙、Swap、Selinux都设置为关闭的状态,要不然安装时或加入集群时总是会出现各处各样的问题。

关闭防火墙

$ systemctl stop firewalld
$ systemctl disable firewalld

关闭swap内存

Kubernetes 1.8开始要求关闭系统的Swap,如果不关闭,默认配置下kubelet将无法启动。

  • 方法一: 通过kubelet的启动参数–fail-swap-on=false更改这个限制。
  • 方法二: 关闭系统的Swap。
$ swapoff -a
$ sed 's/.*swap.*/#&/' /etc/fstab

或修改/etc/fstab文件,注释掉SWAP的自动挂载,使用free -m确认swap已经关闭。

关闭selinux

$ setenforce 0

编辑文件/etc/selinux/config,将SELINUX修改为disabled,如下:

SELINUX=disabled

如果没有可以试试各种目录:

$ sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux 
$ sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config 
$ sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/sysconfig/selinux 
$ sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/selinux/config 

安装k8s基础设施

分别在每台机器上安装docker、kubelet、kubeadm和kubectl,详细看官方文档。

安装Docker

Docker 建议使用最新的,因为17.xx 的某个版本似乎是有个小问题。或者您也可以参照Docker官方给出的方案 https://docs.docker.com/install/linux/docker-ce/

如果无法安装,请加vpn或使用代理,国内你们都懂的。

$ apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
$ add-apt-repository \
"deb https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") $(lsb_release -cs) stable
deb http://apt.kubernetes.io/ kubernetes-xenial \
main"
# 先安装docker
$ apt-get update && apt-get install -y docker-ce=$(apt-cache madison docker-ce | grep 18.04 | head -1 | awk '{print $3}')

配置Docker

  • 创建daemon.json文件设置为国内镜像:

    $ vim /etc/docker/daemon.json
    

    输入以下代码保存:

    {
        "registry-mirrors": ["https://registry.docker-cn.com"]
    }
    
  • 开启iptables filter表的FORWARD链

    编辑/lib/systemd/system/docker.service,在ExecStart=..上面加入如下内容:

    ExecStartPost=/usr/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT
    
  • 配置Cgroup Driver

    创建文件/etc/docker/daemon.json,添加如下内容:

    {
      "exec-opts": ["native.cgroupdriver=systemd"]
    }
    
  • 重启Docker服务

    $ systemctl daemon-reload && systemctl restart docker && systemctl status docker
        
    

安装 kubelet、kubeadm和kubectl

如果无法安装,请加vpn或使用代理,国内你们都懂的。

$ apt-get update && apt-get install -y apt-transport-https
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl

# 假设报有 cni错误 试试 apt-get install -y kubernetes-cni 不过咱们不使用这种方式

确保cgroup与kubelet所使用的驱动程序是一样的:

$ docker info | grep -i cgroup
$ cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

如果Docker 的cgroup 驱动与 kubelet配置不匹配,改变kubelet配置Docker 的cgroup驱动。你需要改变的标志是——cgroup-driver:

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

重新启动 kubelet

$ systemctl daemon-reload
$ systemctl restart kubelet

记得在每台机器上都安装以上工具及配置

创建master节点

如果之前有设置master 想重新安装执行:

$ kubeadm reset

$ systemctl daemon-reload
$ systemctl stop kubelet
$ docker rm -f $(docker ps -q); mount | grep "/var/lib/kubelet/*" | awk '{print $3}' | xargs umount 1>/dev/null 2>/dev/null;
$ rm -rf /var/lib/kubelet /etc/kubernetes /var/lib/etcd /etc/cni
$ rm -rf /root/.kube/*
$ systemctl start kubelet

选择一台性能较好的机器,我们以dev-01作为Master来使用。

可以先生成,然后 init 的时间指定,也可以不先生成init后会自动创建token。

$ kubeadm token generate // 可以水
$ kubeadm init –apiserver-advertise-address dev-01 // 也可以水 --pod-network-cidr=10.244.0.0/16

没报错应该就算成功了:

如果失败了,查看失败原因:

  1. 上面系统设置写的要关闭的东西有没有关闭
  2. 通过命令journalctl -f -u kubelet查看日志尝试解决
  3. Github 搜
  4. Google 搜
  5. kubeadm reset 再来一遍(⁎⁍̴̛ᴗ⁍̴̛⁎)
$ 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 命令需要连接的配置文件放到$HOME/.kube/config 目录,为什么呢?

查看kubeclt源码不难发现:

它优先获取环境变量KUBECONFIG,如果没有则读取当前用户HOME目录下的/.kube/config配置文件

将Node加入到Master组成集群

加入到master需要使用mast init生成的一段命令:

$ kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>

保存好上面那条命令(master创建成功后会在最后留下一条命令),后续其他node 需要加入集群时通过这条命令加入:

$ kubeadm join 10.106.145.44:6443 --token g8z3gc.ujlihp9kr3oyakgp --discovery-token-ca-cert-hash sha256:1739ed5374f1975b73ceba833d6a5c6c11f2dcf550967e2b813b0ab7d83736c1

如果忘记了token 可以在master使用命令:

$ kubeadm token list | grep authentication,signing | awk '{print $1}'

如果 discovery-token-ca-cert-hash 也不记得了, 也可以通过以下命令查询:

$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

这里需要注册, token只会保存24小时如果过期,并且要有新节点加入的话需要执行: $ kubeadm token create 创建一个新的token

登陆到已经安装和配置好docker、kubeadm、kubelet的服务器上执行刚刚保存的命令。

如果没有有报错,那应该是加入成功了,如果有报错试试执行:

$ kubectl reset

当然前提必须是系统设置确定已经配置好了。

回到master节点查看node 是否加入成功。

通常到这一步都是NotReady,为什么呢?因为我们还没安装网络组件。

查看kubelet 日志 : journalctl -f -u kubelet

查看集群状态:

$ kubectl get cs

如果有遇到以下这样的错误:

[preflight] WARNING: ebtables not found in system path                          
[preflight] WARNING: ethtool not found in system path     

尝试安装或升级一下 ebtables, ethtool

  • CentOS: yum install ebtables ethtool
  • Ubuntu: apt install ebtables ethtool

Node的隔离与恢复

如果发现node有问题,可以使用以下命令对node进行隔离或恢复。

安装网络

推荐使用Calico, 为了方便这里以官方的flannel为例:

安装网络:

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml
$ kubectl create -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel-rbac.yml
$ kubectl create -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml

显示以下信息是创建成功了:

clusterrole "flannel" created
clusterrolebinding "flannel" created
serviceaccount "flannel" created
configmap "kube-flannel-cfg" created
daemonset "kube-flannel-ds" created

安装完成之后,我们再查看Node是否为 Ready

到这里,我们集群就算是搭建完了。

需要注意的是,我不推荐使用 kube-proxy 来代理 apiservice。因为有安全隐患,我们还是应该通过tls加密的方式来进行通信。

从Kubernetes集群中移除节点

$ kubectl drain 10.106.145.43 --delete-local-data --force --ignore-daemonsets
$ kubectl delete node 10.106.145.43

安装Web UI (Dashboard)

在Master上直接执行:

方案一:

$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

咱们可以通过命令对dashboard进行编辑:

$ kubectl -n kube-system edit service kubernetes-dashboard

需要有一个对外访问的端口,咱们把spec下面的type修改为 NodePort 然后:wq 退出保存就行了。一会pod重启后会自动分配一个宿主机的端口进行映射。

方案二:

$ wget https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
$ vim kubernetes-dashboard.yaml # 它进行编辑

spec下面的type修改为 NodePort 然后:wq 退出保存。

再执行命令:

$ kubectl create -f kubernetes-dashboard.yaml

拉取镜像需要一些时间,骚等一会。

可以执行以下命令查询kubernetes-dashboard-xxxxxx在STATUS:

$ kubectl get pods -n kube-system
$ kubectl get pods --all-namespaces # 查看所有有pod

当STATUS为Running的时候表示它已经启动了。

查询token:

$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep role | awk '{print $1}')

好了,我们打开浏览器,输入集群任意一ip加上 kubernetes dashboard 的NodePort访问,注意这里得是https,不是http。

如果不知道端口,可以输入以下命令查询...

查看服务运行的端口:

$ kubectl get svc -n kube-system

到这里,集群已经基本完成了,可以正常使用。


安装监控

为了保证集群的正常使用,通常我们还需要一些监控工具,这里推荐使用官网推荐的方案。

克隆或下载: [](https://github.com/kubernetes/heapster)

然后进入到deploy目录,执行以下命令:

$ ./kube.sh start

监控的组件一共有这么些:

  • grafana
  • heapster-rbac
  • heapster
  • influxdb

方案二

  1. 创建目录: $ mkdir ./heapster/ && cd ./heapster/

  2. 下载文件:

    $ wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/grafana.yaml
        
    $ wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml
        
    $ wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/heapster.yaml
        
    $ wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml
    
  3. 执行命令安装:

    $ kubectl create -f ./
    

方案三

  1. 克隆github代码:

    $ git clone https://github.com/kubernetes/heapster.git
    $ cd heapster/
    
  2. 执行命令安装influxdb:

    $ kubectl apply -f deploy/kube-config/influxdb/
    
  3. 执行命令安装rbac及控制器:

    $ kubectl apply -f deploy/kube-config/rbac/heapster-rbac.yaml
    $ kubectl apply -f deploy/kube-config/standalone/
    
  4. 安装api-service等:

    $ kubectl apply -f deploy/kube-config/standalone-with-apiserver/
    

效果如下

回到dashboard看情况:

监控安装成功。

尾巴

如果集群里的应用要对外提供服务我们有几种方案

  • NodePort 不推荐
  • Ingress 不推荐
  • nginx-ingress 不推荐
  • traefik-ingress 推荐
  • istio-ingressgateway 推荐

我们在集群尽量只开放两个端口,一个是6443 dashboard 一个是ingress的NodePort。其他端口最好关闭,流量都从ingress进入或流出。甚至dashboard的6443端口也可以从Ingress走。

下次我写服务网络的时候再来介绍这几个吧。

下次是什么时候?


不用我说了,大家都懂的。


 标签 , TAG , 啦啦