欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群

程序员文章站 2022-04-19 18:43:54
...

目录

  • Kubeadm 介绍
  • 环境、软件准备
  • 软件安装配置
    • 镜像准备
    • 安装 Docker
    • 安装并配置 Kubernetes 组件
  • 初始化 Master
  • 安装 Flannel 网络组件
  • 部署 Node 节点
  • 安装 Kubernetes Dashboard
  • Dashboard 集成 Heapster
  • 安装过程问题总结

1、kubeadm 介绍

Kubernetes 是 Google 开源的基于 Docker 的容器集群管理系统,通过 yaml 语言写的配置文件,简单快速的就能自动部署好应用环境,支持应用横向扩展,并且可以组织、编排、管理和迁移这些容器化的应用。Kubeadm 是一个可以快速帮助我们创建稳定集群服务的工具,通过它,我们可以在虚拟机、实体机或者云端快速部署一个高可用的集群服务。

2、环境、软件准备

安装之前,先介绍下 Kubeadm 安装 kubernetes 需要的一些基本硬件要求。

  • 系统要求,支持的系统 Ubuntu 16.04+、 CentOS 7 、HypriotOS v1.0.1+
  • 内存要求,每台机器至少要有 1GB 内存,否则集群启动后,留给运行的应用可用内存就很少了。
  • 网络要求,保证集群内所有机器之前的网络是可以互相连通的。

本次演示我准备了两台系统为 CentOS Linux 7 (Core) 的虚拟机,一台作为 Master,一台作为 Node,默认 Master 机器不参与 Pod 调度。集群机器信息如下:

HostName IP CPU MEM DES
master.localdomain 10.236.65.125 2 Core 2G k8s master 节点
node0.localdomain 10.236.65.135 2 Core 2G 应用节点

此外,我们还需要做一些初始化工作,下边安装过程中遇到坑的时候也会提到。

1、安装 ebtables ethtool,否则后边执行 kubeadm init 的时候会报错。

$ yum install ebtables ethtool

2、修改网络开启桥接网络支持,只针对(RHEL/CentOS 7)系统。

$ cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

或者
$ vim /usr/lib/sysctl.d/00-system.conf  # 将 net.bridge.bridge-nf-call-iptables 值改成 1

# 然后修改当前内核状态
$ echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables

3、关闭 SELinux,目的为了允许容器能够与本机文件系统交互。

$ setenforce 0
$ systemctl daemon-reload

4、修改节点的 hostname,因为 kubernetes 是根据 hostname 来标示各节点的。

# Master 节点
$ echo "master.localdomain" > /etc/hostname 
$ echo "10.236.65.125   master.localdomain" >> /etc/hosts
$ sysctl kernel.hostname=master.localdomain # 不重启情况下使内核修改生效

3、软件安装配置

我们知道 kubernetes 环境底层是依赖 Docker 的,所以这里软件安装包括了 Docker 安装, kubelet、kubeadm、kubectl 组件安装,以及一些初始化配置工作。

Master 和 Node 节点由于分工不一样,所以安装的服务不同,最终安装完毕,Master 和 Node 启动的核心服务分别如下:

Master 节点 Node 节点
etcd-master kube-flannel
kube-apiserver kube-proxy
kube-controller-manager other apps
kube-dns
kube-flannel
kube-proxy
kube-scheduler

3.1 镜像准备

kubernetes 服务启动依赖很多镜像,但是这些镜像要是在国内没有*的话,是下载不下来的。这里我们可以去 Docker Hub 下载指定版本的镜像替代,下载完成后,通过 docker tag ... 命令修改成指定名称的镜像即可。

本次演示 kubernetes 所依赖的各个镜像列表如下:

Image Name Version Des ( * 必需)
gcr.io/google_containers/kube-scheduler-amd64 v1.6.2 *
gcr.io/google_containers/kube-proxy-amd64 v1.6.2 *
gcr.io/google_containers/kube-controller-manager-amd64 v1.6.2 *
gcr.io/google_containers/kube-apiserver-amd64 v1.6.2 *
gcr.io/google_containers/etcd-amd64 3.0.17 *
gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64 1.14.1 *
gcr.io/google_containers/k8s-dns-kube-dns-amd64 1.14.1 *
gcr.io/google_containers/k8s-dns-sidecar-amd64 1.14.1 *
gcr.io/google_containers/pause-amd64 3.0 *
gcr.io/google_containers/flannel v0.7.1-amd64 *
gcr.io/google_containers/kubernetes-dashboard-amd64 v1.6.0
gcr.io/google_containers/heapster-influxdb-amd64 v1.3.3
gcr.io/google_containers/heapster-grafana-amd64 v4.4.3
gcr.io/google_containers/heapster-amd64 v1.4.0

可使用下边脚本,分别替换以上镜像。

#!/bin/bash

images=(
    flannel:v0.7.1-amd64 
    kube-scheduler-amd64:v1.6.2 
    kube-proxy-amd64:v1.6.2  
    kube-controller-manager-amd64:v1.6.2 
    etcd-amd64:3.0.17 
    kubernetes-dashboard-amd64:v1.6.0  
    k8s-dns-dnsmasq-nanny-amd64:1.14.1  
    k8s-dns-kube-dns-amd64:1.14.1
    k8s-dns-sidecar-amd64:1.14.1 
    pause-amd64:3.0)

for imageName in ${images[@]} ; do
    docker pull docker.io/lvanneo/$imageName
    docker tag docker.io/lvanneo/$imageName gcr.io/google_containers/$imageName 
    docker rmi docker.io/lvanneo/$imageName
done


docker pull docker.io/bjb2010/kube-apiserver-amd64:v1.6.2 
docker tag docker.io/bjb2010/kube-apiserver-amd64:v1.6.2  gcr.io/google_containers/kube-apiserver-amd64:v1.6.2
docker rmi docker.io/bjb2010/kube-apiserver-amd64:v1.6.2

images=(
    heapster-grafana-amd64-v4.4.3:v4.4.3
    heapster-influxdb-amd64-v1.3.3:v1.3.3
    heapster-amd64-v1.4.0:v1.4.0)

for imageName in ${images[@]} ; do
    docker pull docker.io/wanghkkk/$imageName
    docker tag docker.io/wanghkkk/$imageName gcr.io/google_containers/$imageName 
    docker rmi docker.io/wanghkkk/$imageName
done    

3.2 安装 Docker

每台机器都需要安装 Docker,官方文档建议版本为 Version v1.12,其他版本 v1.11、v1.13、 17.03 也都测试没问题,最新版还没有测试验证,这里我们选择 v1.12 版本。

$ yum install -y docker

# 设置开启启动并启动服务
$ systemctl enable docker && systemctl start docker

3.3 安装并配置 kubernetes 组件

需要安装的 kubernetes 组件主要有 kubelet、kubeadm、kubectl 这几个。针对可以*的用户可以 yum 配置 kubernetes 官方源:

# 配置 yum 源
cat <<EOF > /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

#设置完成后,安装kubelet、kubeadm、kubectl 组件
$ yum install -y kubelet kubeadm kubectl

# 设置开机启动,以及启动各组件
$ systemctl enable kubelet && systemctl start kubelet

对于国内不能*的用户,可以下载指定版本的 rpm 包安装,也可以去 github 下载 kubernetes release 这个项目源码,本地编译生成 rpm 包。

$ git clone https://github.com/kubernetes/release.git
$ cd rpm
$ ./docker-build.sh
...

最终执行完毕的结果,会在项目 release/rpm/output/ 下生成特定版本的 rpm 包。

国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群

这里附上热心网友已经上传到网盘的 RPM 包地址:https://pan.baidu.com/s/1clIpjC cp6h,可以下载下来上传到虚拟机中。然后执行如下命令,完成组件的安装。

# yum 安装 rpm 包
$ yum install -y *.rpm

# 设置开机启动
$ systemctl enable kubelet

安装完毕后,我们还需要配置一下 kubelet,主要修改配置文件 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 中的 KUBELET_CGROUP_ARGS 配置。

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

[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--kubeconfig=/etc/kubernetes/kubelet.conf --require-kubeconfig=true"
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true"
Environment="KUBELET_NETWORK_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local"
Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook --client-ca-file=/etc/kubernetes/pki/ca.crt"
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=systemd"
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_AUTHZ_ARGS $KUBELET_CGROUP_ARGS  $KUBELET_EXTRA_ARGS

这里说明一下,kubelet 默认的 cgroup 的驱动为 cgroupfs,而 Docker 默认的 cgroup 的驱动为 systemd,所有这里可以将 kubectl 的默认驱动改为同 Docker 的一样,否则下边执行 kubeadm init 的时候会报错。当然也可以修改 Docker 的驱动为 cgroupfs。

修改完成之后,需要重新 reload 一下 kubelet 服务。

$ systemctl daemon-reload

好了,通过以上安装配置就完成了 Master 节点环境的初始化工作了,Node 节点机器初始化就简单了,因为我使用的是虚拟机,那么只需要将配置好的主机环境复制一份就好了。当然如果你是实体机的话,那就按照上边初始化的操作步骤来一遍就可以了。最后不要忘记修改 Node 节点的 hostname 哈。

# Node 节点
$ echo "node0.localdomain" > /etc/hostname 
$ echo "10.236.65.135   node0.localdomain" >> /etc/hosts
$ sysctl kernel.hostname=node0.localdomain # 不重启情况下使内核修改生效

4、初始化启动 Master

配置完主机后,我们可以启动 Master 节点了。在执行初始化 init 时,kubernetes 并没有选择默认的 Pod Network,它支持很多种,这里我们选择 Flannel 作为 Pod Network,按照文档说明,执行 init 时,需要带上参数 --pod-network-cidr,即指定网络区间,同时我们也可以通过 --kubernetes-version 指定选择 kubernetes 的版本号,因为我们镜像以及 rpm 包都是指定 1.6.2 的版本,所以最终执行命令如下:

$ kubeadm init --kubernetes-version=v1.6.2 --pod-network-cidr=10.96.0.0/12
[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.
[init] Using Kubernetes version: v1.6.2
[init] Using Authorization mode: RBAC
[preflight] Running pre-flight checks
[preflight] Starting the kubelet service
[certificates] Generated CA certificate and key.
[certificates] Generated API server certificate and key.
[certificates] API Server serving cert is signed for DNS names [master.localdomain kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.236.65.125]
[certificates] Generated API server kubelet client certificate and key.
[certificates] Generated service account token signing 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/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[apiclient] Created API client, waiting for the control plane to become ready
[apiclient] All control plane components are healthy after 16.577867 seconds
[apiclient] Waiting for at least one node to register
[apiclient] First node has registered after 4.004669 seconds
[token] Using token: 3aaf19.8e758a48f2050bd1
[apiconfig] Created RBAC rules
[addons] Created essential addon: kube-proxy
[addons] Created essential addon: kube-dns

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run (as a regular user):

  sudo cp /etc/kubernetes/admin.conf $HOME/
  sudo chown $(id -u):$(id -g) $HOME/admin.conf
  export KUBECONFIG=$HOME/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  http://kubernetes.io/docs/admin/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token 3aaf19.8e758a48f2050bd1 10.236.65.125:6443

如果一切顺利的话,就会出现上边的执行结果输出。此时我们需要好好保存一下 kubeadm join --token 3aaf19.8e758a48f2050bd1 10.236.65.125:6443,这是后边其他 Node 节点加入集群的通关文牒。。。 不过要提一下的是,如果初始化时卡在某一步不能继续下去的时候,可以通过 journalctl -xeu kubelet 查看初始化日志,找到错误原因。

好了初始化 Master 完成后,我们使用命令 kubectl get node 查看集群节点信息,但是你会发现并没有出现 Node 信息,反而报错如下:

$ kubectl get node
The connection to the server localhost:8080 was refused - did you specify the right host or port?

What?上边不都显示安装完成了吗?其实是已经初始化完成了,只不过想使用集群的话,少了上边日志输出的那一步。

$ sudo cp /etc/kubernetes/admin.conf $HOME/
$ sudo chown $(id -u):$(id -g) $HOME/admin.conf
$ export KUBECONFIG=$HOME/admin.conf

现在我们在使用命令 kubectl get node 查看集群节点信息,就符合预期结果了。

$ kubectl get node
NAME                 STATUS    AGE       VERSION
master.localdomain   Ready     1d        v1.6.2

我们在使用命令 kubectl get pod --all-namespaces 查看当前节点所有的 pod。

$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                         READY     STATUS         RESTARTS   AGE
kube-system   etcd-master.localdomain                      1/1       Running        0          23h
kube-system   kube-apiserver-master.localdomain            1/1       Running        0          1d
kube-system   kube-controller-manager-master.localdomain   1/1       Running        0          1d
kube-system   kube-dns-3913472980-37b6d                    0/3       Pending        0          14m
kube-system   kube-proxy-czzg9                             1/1       Running        0          1d
kube-system   kube-scheduler-master.localdomain            1/1       Running        0          1d

注意这里 kube-dns 显示状态为 Pending,没有关系,这是因为还没有安装 Pod Network 组件导致的,接下来我们安装 Flannel 网络组件后,它就会自动跑起来了。

5、安装 Flannel 网络组件

kubernetes 提供了很多种网络组件选择,有 Calia、Canal、Flannel、Kube-router、Romana、Weave Net 可以使用,具体使用可以参考 官方文档 (3/4) Installing a pod network 来操作,这里我们选择 Flannel 作为网络组件。

# 安装最新版,注意提前下载好要替代的 image
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.0/Documentation/kube-flannel.yml

这里我使用 v0.7.1 版本,需要使用两个文件,可在 Github Flannel上获取。

$ kubectl apply -f https://github.com/coreos/flannel/blob/v0.7.1/Documentation/kube-flannel-rbac.yml
$ kubectl apply -f https://github.com/coreos/flannel/blob/v0.7.1/Documentation/kube-flannel.yml

安装完毕后,我们稍等一会再来查看下 pod 列表。

$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                         READY     STATUS             RESTARTS   AGE
kube-system   etcd-master.localdomain                      1/1       Running            0          23h
kube-system   kube-apiserver-master.localdomain            1/1       Running            0          1d
kube-system   kube-controller-manager-master.localdomain   1/1       Running            0          1d
kube-system   kube-dns-3913472980-37b6d                    3/3       Running            0          14m
kube-system   kube-flannel-ds-vkdzw                        2/2       Running            5          4m
kube-system   kube-proxy-czzg9                             1/1       Running            0          1d
kube-system   kube-scheduler-master.localdomain            1/1       Running            0          1d

现在是不是都是 Running 状态啦!

6、部署 Node 节点

Master 已经正常启动完毕了,现在我们将 Node 加入 cluster 集群中,使用 kubeadm join ... 命令。在 Node 节点上执行(上边执行 init 时日志打印的命令)

$ kubeadm join --token 3aaf19.8e758a48f2050bd1 10.236.65.125:6443
[preflight] Running pre-flight checks
[preflight] Starting the kubelet service
[discovery] Trying to connect to API Server "10.236.65.125:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.236.65.125:6443"
[discovery] Cluster info signature and contents are valid, will use API Server "https://10.236.65.125:6443"
[discovery] Successfully established connection with API Server "10.236.65.125:6443"
[bootstrap] Detected server version: v1.6.2
[bootstrap] The server supports the Certificates API (certificates.k8s.io/v1beta1)
[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request
[csr] Received signed certificate from the API server, generating KubeConfig...
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"

Node join complete:
* Certificate signing request sent to master and response
  received.
* Kubelet informed of new secure connection details.

Run 'kubectl get nodes' on the master to see this machine join.

现在我们在 Master 节点查看下集群节点信息,就会发现已经包含该 Node 节点了。

$ kubectl get node -o wide
NAME                 STATUS    AGE       VERSION   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION
master.localdomain   Ready     1d        v1.6.2    <none>        CentOS Linux 7 (Core)   3.10.0-514.26.2.el7.x86_64
node0.localdomain    Ready     1d        v1.6.2    <none>        CentOS Linux 7 (Core)   3.10.0-514.26.2.el7.x86_64

查看下集群所有 pod 列表,发现符合预期 Master、Node 启动服务列表。

$ kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                                         READY     STATUS    RESTARTS   AGE       IP             NODE
kube-system   etcd-master.localdomain                      1/1       Running   0          1d        10.236.65.125   master.localdomain
kube-system   kube-apiserver-master.localdomain            1/1       Running   0          1d        10.236.65.125   master.localdomain
kube-system   kube-controller-manager-master.localdomain   1/1       Running   0          1d        10.236.65.125   master.localdomain
kube-system   kube-dns-3913472980-2v5l8                    3/3       Running   0          1d        10.96.0.3       master.localdomain
kube-system   kube-flannel-ds-lm1hn                        2/2       Running   0          1d        10.236.65.135   node0.localdomain
kube-system   kube-flannel-ds-v37gs                        2/2       Running   0          1d        10.236.65.125   master.localdomain
kube-system   kube-proxy-2t7k1                             1/1       Running   0          1d        10.236.65.135   node0.localdomain
kube-system   kube-proxy-pvw73                             1/1       Running   0          1d        10.236.65.125   master.localdomain
kube-system   kube-scheduler-master.localdomain            1/1       Running   0          1d        10.236.65.125   master.localdomain

7、安装 Kubernetes Dashboard

接下来我们来安装一下 Kubernetes Dashboard 监控,版本选择,因为我们 kubernetes 版本为 v1.6.2 所以我们选择对应的 Dashboard 版本为 v1.6.+ 即可,版本也不要太新,否则可能会出现兼容性问题。不过可以使用 v1.6.0+ 的版本,它开始支持中文了,更直观一些哈。

$ kubectl create -f https://github.com/kubernetes/dashboard/blob/v1.6.0/src/deploy/kubernetes-dashboard.yaml

安装完成之后,可以通过命令获取服务端口号,方式有两种:

方式一,通过获取 service 列表中 PORT,例如下边 80:30438/TCP ,那么 NodePort 就是 30438

$ kubectl get service --all-namespaces
NAMESPACE     NAME                   CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
default       kubernetes             10.96.0.1        <none>        443/TCP         1d
kube-system   kube-dns               10.96.0.10       <none>        53/UDP,53/TCP   1d
kube-system   kubernetes-dashboard   10.106.212.217   <nodes>       80:30438/TCP    1d

方式二,通过获取 service kubernetes-dashboard 的描述信息,找到 NodePort: 显示即为端口号。

$ kubectl describe service kubernetes-dashboard -n kube-system
Name:           kubernetes-dashboard
Namespace:      kube-system
Labels:         app=kubernetes-dashboard
Annotations:        kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"kubernetes-dashboard"},"name":"kubernetes-dashboard","namespace":"kub...
Selector:       app=kubernetes-dashboard
Type:           NodePort
IP:         10.106.212.217
Port:           <unset> 80/TCP
NodePort:       <unset> 30438/TCP
Endpoints:      10.96.0.4:9090
Session Affinity:   None
Events:         <none>

从上可以看出 NodePort 为 30438,所以我们可以通过 http://<NodeIP>:<NodePort> 方式既可以访问 Dashboard UI 页面了。注意这里的 NodeIP 可以为 Master 或者 Node 节点的 IP 都可以。我这两台虚拟机,可以通过 http://10.236.65.125:30438http://10.236.65.135:30438 访问 Dashboard。

国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群

国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群

国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群

8、Dashboard 集成 Heapster

Kubernetes Dashboard 监控安装完毕后,其实整个 Kubernetes 服务体系已经可以正常运行起来了,我们需要做的就是将我们的服务部署到集群中。这里在补充一下如何使 Kubernetes Dashboard 集成 Heapster 插件,来图形化展现集群度量指标信息。大体安装过程如我上一篇文章 初始 minikube 安装 Kubernetes Dashboard 并集成 Heapster,这里就在简单的说一下。

首先我们去 GitHub 下载 GitHub Heapster 最新稳定版代码到本地指定目录,然后通过 yaml 文件创建并启动各个服务。这里我们选择 InfluxDB 作为后端数据存储,Grafana 作为图形化展示。

$ cd /Users/wanyang3/docker/kubernetes/
$ git clone https://github.com/kubernetes/heapster.git
$ ls -l deploy/kube-config/influxdb/
total 24
-rw-r--r--  1 wanyang3  staff  2291 10 19 14:49 grafana.yaml
-rw-r--r--  1 wanyang3  staff  1162 10 20 15:01 heapster.yaml
-rw-r--r--  1 wanyang3  staff   974 10 19 14:49 influxdb.yaml

在执行 create 之前请保证能够*或者已经替换好了所需要的 images。

$ kubectl create -f deploy/kube-config/influxdb/
delpoyment "heapster" created
service "heapster" created
deployment "monitoring-influxdb" created
service "monitoring-influxdb" created
deployment "monitoring-grafana" created
service "monitoring-grafana" created

$ kubectl get pods -n kube-system
NAME                                   READY     STATUS    RESTARTS   AGE
heapster-3848557544-1548b              1/1       Running   0          1d
monitoring-grafana-2175968514-7tl3w    1/1       Running   0          1d
monitoring-influxdb-1957622127-x28mz   1/1       Running   0          1d
...

Heapster 插件已经启动完毕了,如果一切正常的话,稍等几分钟(采集数据需要些时间),再次刷新 dashboard,就能看到集群度量指标信息将以图形化方式展现出来。

国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群

国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群

这里值的一提的是,如果刷新没有出来图形化的话,可以通过查看日志查找原因。

$kubectl logs -f pod/heapster-3848557544-1548b -n kube-system

通过日志可以发现,在 heapster-3848557544-1548b 这个 pod 的日志中,发现有错误:

...
Failed to list *api.Node: Get https://kubernetes.default/api/v1/nodes?resourceVersion=0: 
x509: certificate is valid for server, not kubernetes.default
...

解决方法有两种:

1、通过参考 Github Heapster 配置数据源文档 Heapster source-configuration,修改配置数据源为 --source=kubernetes:http://<address-of-kubernetes-master>:<http-port>?inClusterConfig=false,采用 insecure-port 的方式连接,因为 kube-apiserver 针对 insecure-port 接入的请求没有任何限制机制。
2、通过命令获取 kubernetes ClusterIP,直接使用 ClusterIP 也是可以的。

$ kubectl get service
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes       ClusterIP   10.0.0.1     <none>        443/TCP        1d
...

修改 heapster.yaml 

command:
    - /heapster
    #- --source=kubernetes:https://kubernetes.default
    - --source=kubernetes:https://10.0.0.1
    - --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086

修改配置完成后,使用 kubectl apply -f deploy/kube-config/influxdb/heapster.yaml 重新 apply 一下该 pod。再次稍等几分钟,再次刷新 dashboard,就能看到了。

9、安装过程问题总结

  1. 执行 kubeadm init ... 时,报错如下:

    ebtables not found in system path ...

    原因是没有安装 ebtables 导致,执行 yum install -y ebtables 安装即可。

  2. 执行 kubeadm init ... 时,卡在了 [apiclient] Created API client, waiting for the control plane to become ready 不继续执行了,通过 journalctl -xeu kubelet 查看日志得到报错信息:

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

    原因是 kubelet 的 cgroup 驱动跟 docker 不一致,解决方案是选择一种驱动,将二者改成一致。

    方式一:

    $ vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=systemd"
    
    $ systemctl daemon-reload 
    $ systemctl restart kubelet

    方式二:

    $ vim /lib/systemd/system/docker.service
    将 --exec-opt native.cgroupdriver=systemd  修改为:--exec-opt native.cgroupdriver=cgroupfs
    
    $ systemctl daemon-reload 
    $ systemctl restart docker.service
  3. 执行 kubeadm init ... 完成之后,使用 kubectl ... 命令时,提示如下信息:

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

    原因是没有设置 KUBECONFIG,执行如下两种方式均可:

    方式一:
    sudo cp /etc/kubernetes/admin.conf $HOME/
    sudo chown $(id -u):$(id -g) $HOME/admin.conf
    export KUBECONFIG=$HOME/admin.conf
    
    方式二:
    export KUBECONFIG=/etc/kubernetes/admin.conf 
    source ~/.bash_profile  
  4. 安装完 Flannel 网络组件之后,发现 pod kube-flannel 的状态为 CrashLoopBackOff,执行命令查看日志,提示如下信息:

    Error from server (BadRequest): a container name must be specified for pod kube-flannel-ds-hl9xd, choose one of: [kube-flannel install-cni]

    出现这个是因为 pod kube-flannel 启动了两个容器 kube-flannel 和 install-cni,查看日志时需要指定查看那个容器,可通过命令 -c <container_name> 指定,例如: kubectl logs -f pods/kube-flannel-ds-vkdzw -c install-cni -n kube-system。通过命令可以看到报错信息如下:

    + cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf
    cp: can't create '/etc/cni/net.d/10-flannel.conf': Permission denied

    这个是因为容器跟主机文件系统有交互操作,需要关闭 SELinux,执行如下命令即可:

    $ setenforce 0
    $ systemctl daemon-reload
  5. Dashboard 集成 Heapster 插件时,执行完 $ kubectl create -f deploy/kube-config/influxdb/ 操作后,发现 pod heapster 状态非 Running,通过日志可以看到如下报错信息:

    ...
    E1027 07:36:16.951175       1 reflector.go:190] k8s.io/heapster/metrics/heapster.go:322: Failed to list *v1.Pod: User "system:serviceaccount:kube-system:heapster" cannot list pods at the cluster scope. (get pods)
    E1027 07:39:18.383356       1 reflector.go:190] k8s.io/heapster/metrics/processors/namespace_based_enricher.go:84: Failed to list *v1.Namespace: User "system:serviceaccount:kube-system:heapster" cannot list namespaces at the cluster scope. (get namespaces)
    ...

    解决这个方案是增加了一个 heapster-rbac.yaml 文件,定义一个名为 heapster 的 ServiceAccount,然后将它和 Cluster Role view 绑定。该文件在下载的源码中 deploy/kube-config/rbac 目录中存在,执行如下命令即可:

    $ kubectl apply -f deploy/kube-config/rbac/heapster-rbac.yaml
  6. 执行 kubeadm init ... 或者 kubeadm join ... 操作失败后,如果想重新操作,不可以直接重复执行,需要执行 kubeadm reset 还原后在次执行。

  7. 如果我们需要重新部署并删除 Node 节点的话,可以在 Master 节点上执行如下命令:

    $ kubectl drain <node_name> --delete-local-data --force --ignore-daemonsets
    $ kubectl delete node <node_name>

    node 节点上执行删除 flannel 网段操作

    $ kubeadm reset
    $ ifconfig cni0 down
    $ ip link delete cni0
    $ ifconfig flannel.1 down
    $ ip link delete flannel.1
    $ rm -rf /var/lib/cni/
  8. kubeadm 默认安装时,Master 节点不参与 Pod 调度,即不会有非核心组件的 Pod 在 Master 节点上被创建出来,可以通过如下命名,将 Master 参与 Pod 调度。

    $ kubectl taint nodes <node_name> dedicated-
    
  9. 配置其他节点管理整个集群,可以通过如下命令:

    $ scp aaa@qq.com<master_ip>:/etc/kubernetes/admin.conf .
    $ kubectl --kubeconfig ./admin.conf get nodes
  10. 配置本地代理 API Server,可以通过如下命令:

    $ scp aaa@qq.com<master_ip>:/etc/kubernetes/admin.conf .
    $ kubectl --kubeconfig ./admin.conf proxy

参考资料