05 动手实践:搭建一个 Kubernetes 集群 - 生产可用 通过上一节的学习,我们快速的使用

Minikube 搭建了一个本地可用的 K8S 集群。默认情况下,节点是一个虚拟机实例,我们可以在上面体验一些基本的功能。

大多数人的需求并不只是包含一个虚拟机节点的本地测试集群,而是一个可在服务器运行,可自行扩/缩容,具备全部功能的,达到生产可用的集群。

K8S 集群的搭建,一直让很多人头疼,本节我们来搭建一个生产可用的集群,便于后续的学习或使用。

方案选择

K8S 生产环境可用的集群方案有很多,本节我们选择一个 Kubernetes 官方推荐的方案

kubeadm 进行搭建。

kubeadm 是 Kubernetes 官方提供的一个 CLI 工具,可以很方便的搭建一套符合官方最佳实践的最小化可用集群。当我们使用

kubeadm 搭建集群时,集群可以通过 K8S 的一致性测试,并且

kubeadm 还支持其他的集群生命周期功能,比如升级/降级等。

我们在此处选择

kubeadm ,因为我们可以不用过于关注集群的内部细节,便可以快速的搭建出生产可用的集群。我们可以通过后续章节的学习,快速上手 K8S ,并学习到 K8S 的内部原理。在此基础上,想要在物理机上完全一步步搭建集群,便轻而易举。

安装基础组件

前期准备

使用

kubeadm 前,我们需要提前做一些准备。

  • 我们需要禁用 swap。通过之前的学习,我们知道每个节点上都有个必须的组件,名为

kubelet ,自 K8S 1.8 开始,启动

kubelet 时,需要禁用

swap 。或者需要更改

kubelet 的启动参数

–fail-swap-on=false 。

虽说可以更改参数让其可用,但是我建议还是禁用

swap 除非你的集群有特殊的需求,比如:有大内存使用的需求,但又想节约成本;或者你知道你将要做什么,否则可能会出现一些非预期的情况,尤其是做了内存限制的时候,当某个 Pod 达到内存限制的时候,它可能会溢出到 swap 中,这会导致 K8S 无法正常进行调度。

如何禁用:

  • 使用

sudo cat /proc/swaps 验证 swap 配置的设备和文件。

  • 通过

swapoff -a 关闭 swap 。

  • 使用

sudo blkid 或者

sudo lsblk 可查看到我们的设备属性,请注意输出结果中带有

swap 字样的信息。

/etc/fstab 中和上一条命令中输出的,和 swap 相关的挂载点都删掉,以免在机器重启或重挂载时,再挂载

swap 分区。

执行完上述操作,

swap 便会被禁用,当然你也可以再次通过上述命令,或者

free 命令来确认是否还有

swap 存在。 [root@master ~]/# free total used free shared buff/cache available Mem: 1882748 85608 1614836 16808 182304 1630476 Swap: 0 0 0

  • 通过

sudo cat /sys/class/dmi/id/product_uuid 可查看机器的

product_uuid 请确保要搭建集群的所有节点的

product_uuid 均不相同。同时所有节点的 Mac 地址也不能相同,通过

ip a 或者

ifconfig -a 可进行查看。

我们在第二章提到过,每个 Node 都有一些信息会被记录进集群内,而此处我们需要保证的这些唯一的信息,便会记录在集群的

nodeInfo 中,比如

product_uuid 在集群内以

systemUUID 来表示。具体信息我们可以通过集群的

API Server 获取到,在后面的章节会详细讲述。

  • 第三章中,我们已经谈过 K8S 是 C/S 架构,在启动后,会固定监听一些端口用于提供服务。可以通过

sudo netstat -ntlp |grep -E ‘6443|23[79,80]|1025[0,1,2]’ 查看这些端口是否被占用,如果被占用,请手动释放。

如果你执行上述命令时,提示

command not found ,则表明你需要先安装

netstat ,在 CentOS 系统中需要通过

sudo yum install net-tools 安装,而在 Debian/Ubuntu 系统中,则需要通过

sudo apt install net-tools 进行安装。

  • 前面我们也提到了,我们需要一个容器运行时,通常情况下是

Docker ,我们可以通过官方的 Docker 文档 进行安装,安装完成后记得启动服务。

官方推荐使用

17.03 ,但我建议你可以直接安装

18.03 或者更新的版本,因为

17.03 版本的 Docker 已经在 2018 年 3 月

EOL (End Of Life)了。对于更新版本的 Docker,虽然 K8S 尚未在新版本中经过大量测试,但毕竟新版本有很多 Bugfix 和新特性的增加,也能规避一些可能遇到的问题(比如个别情况下 container 不会自动删除的情况 (17.09) )。

另外,由于 Docker 的 API 都是带有版本的,且有良好的兼容性,当使用低版本 API 请求时会自动降级,所以一般情况下也不会有什么问题。

安装 kubectl

第三章中,我们已经说过

kubectl 是集群的客户端,我们现在搭建集群时,也必须要安装它,用于验证集群功能。

安装步骤在第 4 章已经详细说明了,此处不做赘述,可查阅第 4 章或参考下面的内容。

安装 kubeadm 和 kubelet

首先是版本的选择,我们可以通过下面的命令获取到当前的 stable 版本号。要访问这个地址,需要自行处理网络问题或使用我后面提供的解决办法。 [root@master ~]/# curl -sSL https://dl.k8s.io/release/stable.txt v1.11.3

下载二进制包,并通过

kubeadm version 验证版本是否正确。

[root@master ~]/# curl -sSL https://dl.k8s.io/release/v1.11.3/bin/linux/amd64/kubeadm > /usr/bin/kubeadm [root@master ~]/# chmod a+rx /usr/bin/kubeadm [root@master ~]/# kubeadm version kubeadm version: &version.Info{Major:”1”, Minor:”11”, GitVersion:”v1.11.3”, GitCommit:”a4529464e4629c21224b3d52edfe0ea91b072862”, GitTreeState:”clean”, BuildDate:”2018-09-09T17:59:42Z”, GoVersion:”go1.10.3”, Compiler:”gc”, Platform:”linux/amd64”}

当然,我们其实可以使用如同上一章的方式,直接进入到

kubernetes 的官方仓库,找到我们所需版本 v1.11.3 下载

Server Binaries ,如下图:

img

终端下可使用如下方式下载: [root@master tmp]/# wget -q https://dl.k8s.io/v1.11.3/kubernetes-server-linux-amd64.tar.gz

对于国内用户,我已经准备了下面的方式,方便使用。

链接: https://pan.baidu.com/s/1FSEcEUplQQGsjyBIZ6j2fA 提取码: cu4s

下载完成后,验证文件是否正确无误,验证通过后进行解压。

[root@master tmp]/# echo ‘e49d0db1791555d73add107d2110d54487df538b35b9dde0c5590ac4c5e9e039 kubernetes-server-linux-amd64.tar.gz’ sha256sum -c - kubernetes-server-linux-amd64.tar.gz: 确定 [root@master tmp]/# tar -zxf kubernetes-server-linux-amd64.tar.gz [root@master tmp]/# ls kubernetes addons kubernetes-src.tar.gz LICENSES server [root@master tmp]/# ls kubernetes/server/bin/ grep -E ‘kubeadm kubelet kubectl’ kubeadm kubectl kubelet

可以看到在

server/bin/ 目录下有我们所需要的全部内容,将我们所需要的

kubeadm

kubectl

kubelet 等都移动至

/usr/bin 目录下。

[root@master tmp]/# mv kubernetes/server/bin/kube{adm,ctl,let} /usr/bin/ [root@master tmp]/# ls /usr/bin/kube/* /usr/bin/kubeadm /usr/bin/kubectl /usr/bin/kubelet [root@master tmp]/# kubeadm version kubeadm version: &version.Info{Major:”1”, Minor:”11”, GitVersion:”v1.11.3”, GitCommit:”a4529464e4629c21224b3d52edfe0ea91b072862”, GitTreeState:”clean”, BuildDate:”2018-09-09T17:59:42Z”, GoVersion:”go1.10.3”, Compiler:”gc”, Platform:”linux/amd64”} [root@master tmp]/# kubectl version –client Client Version: version.Info{Major:”1”, Minor:”11”, GitVersion:”v1.11.3”, GitCommit:”a4529464e4629c21224b3d52edfe0ea91b072862”, GitTreeState:”clean”, BuildDate:”2018-09-09T18:02:47Z”, GoVersion:”go1.10.3”, Compiler:”gc”, Platform:”linux/amd64”} [root@master tmp]/# kubelet –version Kubernetes v1.11.3

可以看到我们所需的组件,版本均为

v1.11.3 。

配置

为了在生产环境中保障各组件的稳定运行,同时也为了便于管理,我们增加对

kubelet 的

systemd 的配置,由

systemd 对服务进行管理。

配置 kubelet

[root@master tmp]/# cat «‘EOF’ > /etc/systemd/system/kubelet.service [Unit] Description=kubelet: The Kubernetes Agent Documentation=http://kubernetes.io/docs/ [Service] ExecStart=/usr/bin/kubelet Restart=always StartLimitInterval=0 RestartSec=10 [Install] WantedBy=multi-user.target EOF [root@master tmp]/# mkdir -p /etc/systemd/system/kubelet.service.d [root@master tmp]/# cat «‘EOF’ > /etc/systemd/system/kubelet.service.d/kubeadm.conf [Service] Environment=”KUBELET_KUBECONFIG_ARGS=–bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf –kubeconfig=/etc/kubernetes/kubelet.conf” Environment=”KUBELET_CONFIG_ARGS=–config=/var/lib/kubelet/config.yaml” EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env EnvironmentFile=-/etc/default/kubelet ExecStart= ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS EOF [root@master tmp]/# systemctl enable kubelet Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /etc/systemd/system/kubelet.service.

在这里我们添加了

kubelet 的 systemd 配置,然后添加了它的

Drop-in 文件,我们增加的这个

kubeadm.conf 文件,会被 systemd 自动解析,用于复写

kubelet 的基础 systemd 配置,可以看到我们增加了一系列的配置参数。在第 17 章中,我们会对

kubelet 做详细剖析,到时再进行解释。

启动

此时,我们的前期准备已经基本完成,可以使用

kubeadm 来创建集群了。别着急,在此之前,我们还需要安装两个工具,名为

crictl 和

socat 。

安装前置依赖 crictl

crictl 包含在 cri-tools 项目中,这个项目中包含两个工具:

  • crictl 是

kubelet CRI (Container Runtime Interface) 的 CLI 。

  • critest 是

kubelet CRI 的测试工具集。

安装可以通过进入

cri-tools 项目的 Release 页面 ,根据项目 README 文件中的版本兼容关系,选择自己所需的安装包,下载即可,由于我们安装 K8S 1.11.3 所以选择最新的 v1.11.x 的安装包。

img [root@master ~]/# wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.11.1/crictl-v1.11.1-linux-amd64.tar.gz [root@master ~]/# echo ‘ccf83574556793ceb01717dc91c66b70f183c60c2bbec70283939aae8fdef768 crictl-v1.11.1-linux-amd64.tar.gz’ | sha256sum -c - crictl-v1.11.1-linux-amd64.tar.gz: 确定 [root@master ~]/# tar zxvf crictl-v1.11.1-linux-amd64.tar.gz [root@master ~]/# mv crictl /usr/bin/

安装前置依赖 socat

socat 是一款很强大的命令行工具,可以建立两个双向字节流并在其中传输数据。这么说你也许不太理解,简单点说,它其中的一个功能是可以实现端口转发。

无论在 K8S 中,还是在 Docker 中,如果我们需要在外部访问服务,端口转发是个必不可少的部分。当然,你可能会问基本上没有任何地方提到说

socat 是一个依赖项啊,别急,我们来看下K8S 的源码便知道了。 func portForward(client libdocker.Interface, podSandboxID string, port int32, stream io.ReadWriteCloser) error { // 省略了和 socat 无关的代码 socatPath, lookupErr := exec.LookPath(“socat”) if lookupErr != nil { return fmt.Errorf(“unable to do port forwarding: socat not found.”) } args := []string{“-t”, fmt.Sprintf(“%d”, containerPid), “-n”, socatPath, “-“, fmt.Sprintf(“TCP4:localhost:%d”, port)} // … }

socat 的安装很简单 CentOS 下执行

sudo yum install -y socat ,Debian/Ubuntu 下执行

sudo apt-get install -y socat 即可完成安装。

初始化集群

所有的准备工作已经完成,我们开始真正创建一个 K8S 集群。 注意:如果需要配置 Pod 网络方案,请先阅读本章最后的部分 配置集群网络 [root@master ~]/# kubeadm init [init] using Kubernetes version: v1.11.3 [preflight] running pre-flight checks … I0920 01:09:09.602908 17966 kernel_validator.go:81] Validating kernel version I0920 01:09:09.603001 17966 kernel_validator.go:96] Validating kernel config [WARNING SystemVerification]: docker version is greater than the most recently validated version. Docker version: 18.03.1-ce. Max validated version: 17.03 [preflight/images] Pulling images required for setting up a Kubernetes cluster [preflight/images] This might take a minute or two, depending on the speed of your internet connection [preflight/images] You can also perform this action in beforehand using ‘kubeadm config images pull’ [kubelet] Writing kubelet environment file with flags to file “/var/lib/kubelet/kubeadm-flags.env” [kubelet] Writing kubelet configuration to file “/var/lib/kubelet/config.yaml” [preflight] Activating the kubelet service [certificates] Generated ca certificate and key. [certificates] Generated apiserver certificate and key. … [markmaster] Marking the node master as master by adding the label “node-role.kubernetes.io/master=’’” [markmaster] Marking the node master as master by adding the taints [node-role.kubernetes.io/master:NoSchedule] [bootstraptoken] creating the “cluster-info” ConfigMap in the “kube-public” namespace [addons] Applied essential addon: CoreDNS [addons] Applied essential addon: kube-proxy Your Kubernetes master has initialized successfully! … You can now join any number of machines by running the following on each node as root: kubeadm join 202.182.112.120:6443 –token t14kzc.vjurhx5k98dpzqdc –discovery-token-ca-cert-hash sha256:d64f7ce1af9f9c0c73d2d737fd0095456ad98a2816cb5527d55f984c8aa8a762

以上省略了部分输出。

我们从以上日志中可以看到,创建集群时会检查内核版本,Docker 版本等信息,这里提示 Docker 版本较高,我们忽略这个提示。

然后会下载一些镜像,当然这里提示我们可以通过执行

kubeadm config images pull 提前去下载镜像。我们来看下 [root@master ~]/# kubeadm config images pull [config/images] Pulled k8s.gcr.io/kube-apiserver-amd64:v1.11.3 [config/images] Pulled k8s.gcr.io/kube-controller-manager-amd64:v1.11.3 [config/images] Pulled k8s.gcr.io/kube-scheduler-amd64:v1.11.3 [config/images] Pulled k8s.gcr.io/kube-proxy-amd64:v1.11.3 [config/images] Pulled k8s.gcr.io/pause:3.1 [config/images] Pulled k8s.gcr.io/etcd-amd64:3.2.18 [config/images] Pulled k8s.gcr.io/coredns:1.1.3

对于国内用户使用

kubeadm 创建集群时,可能遇到的问题便是这些镜像下载不下来,最终导致创建失败。所以我在国内的代码托管平台提供了一个仓库 可以 clone 该项目,进入

v1.11.3 目录,对每个

tar 文件执行

sudo docker load -i xx.tar 即可将镜像导入。

或者可使用阿里云提供的镜像,只需要将

k8s.gcr.io 替换为

registry.aliyuncs.com/google_containers ,执行

docker pull 后再

docker tag 重 tag 即可。

继续看上面的日志,

kubeadm init 执行起见生成了一些文件,而这些文件我们先前在 kubelet server 的

Drop-in 的配置中配置过。

生成这些配置文件后,将启动

kubelet 服务,生成一系列的证书和相关的配置之类的,并增加一些扩展。

最终集群创建成功,并提示可在任意机器上使用指定命令加入集群。

验证

在上面的步骤中,我们已经安装了 K8S 的 CLI 工具

kubectl ,我们使用此工具查看集群信息: [root@master ~]/# kubectl cluster-info Kubernetes master is running at http://localhost:8080 To further debug and diagnose cluster problems, use ‘kubectl cluster-info dump’. The connection to the server localhost:8080 was refused - did you specify the right host or port? [root@master ~]/# kubectl get nodes The connection to the server localhost:8080 was refused - did you specify the right host or port?

使用

kubectl cluster-info 可查看集群 master 和集群服务的地址,但我们也注意到最后有一句报错

connection … refused 很显然这里存在错误。

kubectl get nodes 可查看集群中

Node 信息,同样报错。

在上面我们提到过,K8S 默认会监听一些端口,但并不是

8080 端口,由此可知,我们的

kubectl 配置有误。

配置 kubectl

  • 使用

kubectl 的参数

–kubeconfig 或者环境变量

KUBECONFIG 。 [root@master ~]/# kubectl –kubeconfig /etc/kubernetes/admin.conf get nodes NAME STATUS ROLES AGE VERSION master NotReady master 13h v1.11.3 [root@master ~]/# [root@master ~]/# KUBECONFIG=/etc/kubernetes/admin.conf kubectl get nodes NAME STATUS ROLES AGE VERSION master NotReady master 13h v1.11.3

  • 使用传参的方式未免太繁琐,我们也可以更改默认配置文件 [root@master ~]/# mkdir -p $HOME/.kube [root@master ~]/# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@master ~]/# sudo chown $(id -u):$(id -g) $HOME/.kube/config [root@master ~]/# kubectl get nodes NAME STATUS ROLES AGE VERSION master NotReady master 13h v1.11.3

配置集群网络

通过上面的配置,我们已经可以正常获取

Node 信息。但通过第 2 章,我们了解到

Node 都有

status ,而此时我们唯一的

Node 是

NotReady 。我们通过给

kubectl 传递

-o 参数更改输出格式,查看更详细的情况。 [root@master ~]/# kubectl get nodes -o yaml apiVersion: v1 items: - apiVersion: v1 kind: Node … status: addresses: - address: master type: Hostname … - lastHeartbeatTime: 2018-09-20T14:45:45Z lastTransitionTime: 2018-09-20T01:09:48Z message: ‘runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized’ reason: KubeletNotReady status: “False” type: Ready …

从以上输出中,我们可以看到 master 处于

NotReady 的原因是

network plugin is not ready: cni config uninitialized 那么

CNI 是什么呢?

CNI 是 Container Network Interface 的缩写,是 K8S 用于配置 Linux 容器网络的接口规范。

关于网络的选择,我们此处不做过多介绍,我们暂时选择一个被广泛使用的方案

flannel 。 但注意,如果要使用

flannel 需要在

kubeadm init 的时候,传递

–pod-network-cidr=10.244.0.0/16 参数。另外需要查看

/proc/sys/net/bridge/bridge-nf-call-iptables 是否已设置为

1 。 可以通过

sysctl net.bridge.bridge-nf-call-iptables=1 更改配置。

我们在前面创建集群时,并没有传递任何参数。为了能使用

flannel , 所以我们需要先将集群重置。使用

kubeadm reset [root@master ~]/# kubeadm reset [reset] WARNING: changes made to this host by ‘kubeadm init’ or ‘kubeadm join’ will be reverted. [reset] are you sure you want to proceed? [y/N]: y [preflight] running pre-flight checks [reset] stopping the kubelet service [reset] unmounting mounted directories in “/var/lib/kubelet” [reset] removing kubernetes-managed containers [reset] cleaning up running containers using crictl with socket /var/run/dockershim.sock [reset] failed to list running pods using crictl: exit status 1. Trying to use docker instead[reset] deleting contents of stateful directories: [/var/lib/kubelet /etc/cni/net.d /var/lib/dockershim /var/run/kubernetes /var/lib/etcd] [reset] deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki] [reset] deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]

重新初始化集群,并传递参数。

[root@master ~]/# kubeadm init –pod-network-cidr=10.244.0.0/16 [init] using Kubernetes version: v1.11.3 … Your Kubernetes master has initialized successfully!

注意:这里会重新生成相应证书等配置,需要按上面的内容重新配置 kubectl。

此时,

CNI 也尚未初始化完成,我们还需完成以下的步骤。 /# 注意,这里的 flannel 配置仅适用于 1.11 版本的 K8S,若安装其他版本的 K8S 需要替换掉此链接 [root@master ~]/# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.extensions/kube-flannel-ds created

稍等片刻,再次查看 Node 状态:

[root@master ~]/# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 12m v1.11.3

可以看到 status 已经是

Ready 状态。根据第 3 章的内容,我们知道 K8S 中最小的调度单元是

Pod 我们来看下集群中现有

Pod 的状态。

[root@master ~]/# kubectl get pods –all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-78fcdf6894-h7pkc 0/1 ContainerCreating 0 12m kube-system coredns-78fcdf6894-lhlks 0/1 ContainerCreating 0 12m kube-system etcd-master 1/1 Running 0 5m kube-system kube-apiserver-master 1/1 Running 0 5m kube-system kube-controller-manager-master 1/1 Running 0 5m kube-system kube-flannel-ds-tqvck 1/1 Running 0 6m kube-system kube-proxy-25tk2 1/1 Running 0 12m kube-system kube-scheduler-master 1/1 Running 0 5m

我们发现有两个

coredns 的

Pod 是

ContainerCreating 的状态,但并未就绪。根据第 3 章的内容,我们知道

Pod 实际会有一个调度过程,此处我们暂且不论,后续章节再对此进行解释。

新增 Node

我们按照刚才执行完

kubeadm init 后,给出的信息,在新的机器上执行

kubeadm join 命令。 [root@node1 ~]/# kubeadm join 202.182.112.120:6443 –token t14kzc.vjurhx5k98dpzqdc –discovery-token-ca-cert-hash sha256:d64f7ce1af9f9c0c73d2d737fd0095456ad98a2816cb5527d55f984c8aa8a762 [preflight] running pre-flight checks [WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}] you can solve this problem with following methods: 1. Run ‘modprobe – ‘ to load missing kernel modules; 2. Provide the missing builtin kernel ipvs support I0921 04:00:54.805439 10677 kernel_validator.go:81] Validating kernel version I0921 04:00:54.805604 10677 kernel_validator.go:96] Validating kernel config [WARNING SystemVerification]: docker version is greater than the most recently validated version. Docker version: 18.03.1-ce. Max validated version: 17.03 [discovery] Trying to connect to API Server “202.182.112.120:6443” [discovery] Created cluster-info discovery client, requesting info from “https://202.182.112.120:6443” [discovery] Requesting info from “https://202.182.112.120:6443” again to validate TLS against the pinned public key [discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server “202.182.112.120:6443” [discovery] Successfully established connection with API Server “202.182.112.120:6443” [kubelet] Downloading configuration for the kubelet from the “kubelet-config-1.11” ConfigMap in the kube-system namespace [kubelet] Writing kubelet configuration to file “/var/lib/kubelet/config.yaml” [kubelet] Writing kubelet environment file with flags to file “/var/lib/kubelet/kubeadm-flags.env” [preflight] Activating the kubelet service [tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap… [patchnode] Uploading the CRI Socket information “/var/run/dockershim.sock” to the Node API object “node1” as an annotation This node has joined the cluster: /* Certificate signing request was sent to master and a response was received. /* The Kubelet was informed of the new secure connection details. Run ‘kubectl get nodes’ on the master to see this node join the cluster.

上面的命令执行完成,提示已经成功加入集群。 此时,我们在 master 上查看下当前集群状态。

[root@master ~]/# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 12m v1.11.3 node1 Ready 7m v1.11.3

可以看到 node1 已经加入了集群。

总结

在本节中,我们选择官方推荐的

kubeadm 工具在服务器上搭建了一套有两个节点的集群。

kubeadm 可以自动的拉取相关组件的 Docker 镜像,并将其“组织”起来,免去了我们逐个部署相关组件的麻烦。

我们首先学习到了部署 K8S 时需要对系统做的基础配置,其次安装了一些必要的工具,以便 K8S 的功能可正常运行。

其次,我们学习到了 CNI 相关的知识,并在集群中部署了

flannel 网络方案。

最后,我们学习了增加 Node 的方法,以便后续扩展集群。

集群搭建方面的学习暂时告一段落,但这并不是结束,这才是真正的开始,从下一章开始,我们要学习集群管理相关的内容,学习如何真正使用 K8S 。

参考资料

https://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/Kubernetes%20%e4%bb%8e%e4%b8%8a%e6%89%8b%e5%88%b0%e5%ae%9e%e8%b7%b5/05%20%e5%8a%a8%e6%89%8b%e5%ae%9e%e8%b7%b5%ef%bc%9a%e6%90%ad%e5%bb%ba%e4%b8%80%e4%b8%aa%20Kubernetes%20%e9%9b%86%e7%be%a4%20-%20%e7%94%9f%e4%ba%a7%e5%8f%af%e7%94%a8.md