Kubeadm 搭建 Kubernetes 集群
两条指令完成部署
# 创建一个Master节点
$ kubeadm init
# 将一个Node节点加入到当前集群中
$ kubeadm join <Master节点的IP和端口>
kubeadm 搭建非常简单,核心就这两条语句。具体还有网络、存储等配置我们往下看。
部署 Overview
- 在所有节点上安装 Docker 和 kubeadm;
- 部署 Kubernetes Master
- 部署容器网络插件;
- 部署 Kubernetes Worker;
- 部署 Dashboard 可视化插件;
- 部署容器存储插件
查看安装的相关组件信息
[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。
- 在全部 work 节点上执行安装 kubeadm 和 Docker
- 执行部署 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 可视化插件
查看 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
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