Fork me on GitHub

Kubeadm 搭建 Kubernetes 集群

两条指令完成部署

# 创建一个Master节点
$ kubeadm init

# 将一个Node节点加入到当前集群中
$ kubeadm join <Master节点的IP和端口>

kubeadm 搭建非常简单,核心就这两条语句。具体还有网络、存储等配置我们往下看。

部署 Overview

  1. 在所有节点上安装 Docker 和 kubeadm;
  2. 部署 Kubernetes Master
  3. 部署容器网络插件;
  4. 部署 Kubernetes Worker;
  5. 部署 Dashboard 可视化插件;
  6. 部署容器存储插件

查看安装的相关组件信息

[root@kubernetes ~]# kubeadm  version
kubeadm version: &version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:17:50Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
[root@kubernetes ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:20:10Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
The connection to the server localhost:8080 was refused - did you specify the right host or port?
[root@kubernetes ~]# kubelet --version
Kubernetes v1.17.0
[root@kubernetes ~]# docker -v
Docker version 1.13.1, build 7f2769b/1.13.1

配置 kube-controller-manager 能够使用自定义资源(Custom Metrics)进行自动水平扩展

kube-controller-manager 设置:
horizontal-pod-autoscaler-use-rest-clients: "true"

kubeadm.yaml 配置文件

apiVersion: kubeadm.k8s.io/v1beta1
kind: InitConfiguration
controllerManagerExtraArgs:
  horizontal-pod-autoscaler-use-rest-clients: "true"
  horizontal-pod-autoscaler-sync-period: "10s"
  node-monitor-grace-period: "10s"
apiServerExtraArgs:
  runtime-config: "api/all=true"
kubernetesVersion: "v1.17.1"
  • 安装 kubeadm init --config kubeadm.yaml
  • 安装好之后根据返回的集群配置命令进行配置:
  • Kubernetes 集群默认需要加密方式访问。所以,这几条命令,就是将刚刚部署生成的 Kubernetes 集群的安全配置文件,保存到当前用户的.kube 目录下,kubectl 默认会使用这个目录下的授权信息访问 Kubernetes 集群。
kubeadm join 192.168.0.19:6443 --token q9cjjj.dtg8a4l2rmzbuws6 \
    --discovery-token-ca-cert-hash sha256:dd9b902dae2d1dc7c5a0036f960a71620f40b393ea86ea490e8592aa641fbba3
    
------

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

查看 master 节点状态

# kubectl get nodes
NAME         STATUS     ROLES    AGE   VERSION
kubernetes   NotReady   master   32d   v1.17.0

查看节点详细信息

# kubectl describe node kubernetes
Name:               kubernetes
Roles:              master
… …

可以通过 kubectl 检查这个节点上各个系统 Pod 的状态,其中,kube-system 是 Kubernetes 项目预留的系统 Pod 的工作空间(Namepsace,注意它并不是 Linux Namespace,它只是 Kubernetes 划分不同工作空间的单位)

CoreDNS、kube-controller-manager 等依赖于网络的 Pod 都处于 Pending 状态,即调度失败。这当然是符合预期的:因为这个 Master 节点的网络尚未就绪。

# kubectl get pods -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-6955765f44-fdxp8             0/1     Pending   0          32d
coredns-6955765f44-hcmrr             0/1     Pending   0          32d

部署网络插件

Container Network Interface (CNI) 最早是由 CoreOS 发起的容器网络规范,是 Kubernetes 网络插件的基础。其基本思想为:Container Runtime 在创建容器时,先创建好 network namespace,然后调用 CNI 插件为这个 netns 配置网络,其后再启动容器内的进程。现已加入 CNCF,成为 CNCF 主推的网络模型。

Kubernetes versions 1.6 and above:

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

Run Weave Net with Kubernetes: https://www.weave.works/blog/weave-net-kubernetes-integration/

重新检查 pod 状态

# kubectl get pods -n kube-system
NAME                                        READY   STATUS    RESTARTS   AGE
coredns-6955765f44-jbldf                    1/1     Running   0          9m32s
coredns-6955765f44-p8dwp                    1/1     Running   0          9m32s
etcd-instance-010oj085                      1/1     Running   0          9m40s
kube-apiserver-instance-010oj085            1/1     Running   0          9m40s
kube-controller-manager-instance-010oj085   1/1     Running   0          9m40s
kube-proxy-p8hff                            1/1     Running   0          9m32s
kube-scheduler-instance-010oj085            1/1     Running   0          9m39s
weave-net-6pt4t                             2/2     Running   0          2m43s

Kubernetes 的 Master 节点就部署完成了。如果你只需要一个单节点的 Kubernetes,现在你就可以使用了。不过,在默认情况下,Kubernetes 的 Master 节点是不能运行用户 Pod 的。

部署 Kubernetes 的 Worker 节点

Kubernetes 的 Worker 节点跟 Master 节点几乎是相同的,它们运行着的都是一个 kubelet 组件。唯一的区别在于,在 kubeadm init 的过程中,kubelet 启动后,Master 节点上还会自动运行 kube-apiserver、kube-scheduler、kube-controller-manger 这三个系统 Pod。

  1. 在全部 work 节点上执行安装 kubeadm 和 Docker
  2. 执行部署 Master 节点时生成的 kubeadm join 指令
kubeadm join 192.168.0.19:6443 --token q9cjjj.dtg8a4l2rmzbuws6 \
    --discovery-token-ca-cert-hash sha256:dd9b902dae2d1dc7c5a0036f960a71620f40b393ea86ea490e8592aa641fbba3

通过 Taint/Toleration 调整 Master 执行 Pod 的策略

默认情况下 Master 节点是不允许运行用户 Pod 的。而 Kubernetes 做到这一点,依靠的是 Kubernetes 的 Taint/Toleration 机制。

一旦某个节点被加上了一个 Taint,即被“打上了污点”,那么所有 Pod 就都不能在这个节点上运行,因为 Kubernetes 的 Pod 都有“洁癖”。除非,有个别的 Pod 声明自己能“容忍”这个“污点”,即声明了 Toleration,它才可以在这个节点上运行。

节点打上 Taint

# kubectl taint nodes node1 foo=bar:NoSchedule

Pod 声明 Toleration(在 Pod 的.yaml 文件中的 spec 部分,加入 tolerations 字段)

apiVersion: v1
kind: Pod
...
spec:
  tolerations:
  - key: "foo"
    operator: "Equal"
    value: "bar"
    effect: "NoSchedule"

查看 master 节点的 Taint 字段

# kubectl describe node master
···
Taints:             node-role.kubernetes.io/master:NoSchedule
···

部署 Dashboard 可视化插件

插件地址:https://github.com/kubernetes/dashboard

查看 dashboard 的 pod 是否创建成功

# kubectl get pods --all-namespaces
NAMESPACE              NAME                                         READY   STATUS    RESTARTS   AGE
kube-system            coredns-6955765f44-jbldf                     1/1     Running   0          18d
kube-system            coredns-6955765f44-p8dwp                     1/1     Running   0          18d
kube-system            etcd-instance-010oj085                       1/1     Running   0          18d
kube-system            kube-apiserver-instance-010oj085             1/1     Running   0          18d
kube-system            kube-controller-manager-instance-010oj085    1/1     Running   0          18d
kube-system            kube-proxy-p8hff                             1/1     Running   0          18d
kube-system            kube-scheduler-instance-010oj085             1/1     Running   0          18d
kube-system            weave-net-6pt4t                              2/2     Running   0          18d
kubernetes-dashboard   dashboard-metrics-scraper-7b8b58dc8b-96vfq   1/1     Running   0          23h
kubernetes-dashboard   kubernetes-dashboard-866f987876-mh5pt        1/1     Running   0          23h

部署容器存储插件(容器持久化存储)

很多时候我们需要用数据卷(Volume)把外面宿主机上的目录或者文件挂载进容器的 Mount Namespace 中,从而达到容器和宿主机共享这些目录或者文件的目的。容器里的应用,也就可以在这些数据卷中新建和写入文件。

在某一台机器上启动的一个容器,显然无法看到其他机器上的容器在它们的数据卷里写入的文件。这是容器最典型的特征之一:无状态。

容器的持久化存储,就是用来保存容器存储状态的重要手段:存储插件会在容器里挂载一个基于网络或者其他机制的远程数据卷,使得在容器里创建的文件,实际上是保存在远程存储服务器上,或者以分布式的方式保存在多个节点上,而与当前宿主机没有任何绑定关系。这样,无论你在其他哪个宿主机上启动新的容器,都可以请求挂载指定的持久化存储卷,从而访问到数据卷里保存的内容。这就是持久化的含义。

Kubernetes 存储插件项目:Rook

https://github.com/rook/rook

Rook provides a growing number of storage providers to a Kubernetes cluster, each with its own operator to deploy and manage the resources for the storage provider.

git clone --single-branch --branch master https://github.com/rook/rook.git
cd /rook/cluster/examples/kubernetes/ceph
kubectl create -f common.yaml
kubectl create -f operator.yaml
kubectl create -f cluster.yaml
posted @ 2020-04-04 17:17  galvinwang  阅读(327)  评论(0编辑  收藏  举报