Kubernetes核心对象及使用 kubeadm 部署集群

释放双眼,带上耳机,听听看~!

Kubernetes 的核心对象

API Server 提供了一个 RESTful 风格的编程接口,其管理的资源是 Kubernetes API 中的端点,用于存储某种API对象的集合,例如内置 Pod 资源 是包含了所有 Pod 对象的集合。资源对象是用于表现集群状态的实体,常用于描述应于哪个节点进行容器化应用、需要为其配置什么资源以及应用程序的管理策略等,例如,重启、升级、及容错机制。另外一个对象也是一种 ”意向记录“ ———— 一旦创建,Kubernetes 就需要一直确保对象始终存在。 Pod、Deployment 和 Service 等都是最常用的核心对象。

Pod 资源对象

Pod 资源对象集合了一个或者多个应用容器、存储资源、专用 IP 及支持容器运行的其他逻辑组件。
Kubernetes 网络模型要求其各 Pod 对象的 IP 地址位于同一 IP 网段内,各个 Pod 之间可使用其 IP 直接通信,无论他们运行于集群内的哪个工作节之上,这些 Pod 对象都像是运行于同一局域网中的多个主机。Pod 对象中的各进程均运行于彼此隔离的容器中,并于同一 Pod 中各容器间共享两种关键资源:网络存储卷

  • 网络(networking):每个 Pod 对象都会被分配一个集群内专用的 IP 地址,也称为 Pod IP,同一 Pod 内部的所有容器共享 Pod 对象的 Network 和 UTS 名称空间,其中包含主机名、IP 地址和端口等。因此这些容器间的通信可以基于本地回环接口直接进行,而与 Pod 外的其他组件通信则需要使用 Service 资源对象的 Cluster IP 及相应的端口进行实现。
  • 存储卷(volume):用户可以为 Pod 对象配置一组 ”存储卷“ 资源,这些资源可以共享给其内部所有容器使用,从而完成同容器间数据的共享。存储卷还可以确保在容器终止后被重启,甚至是删除后也确保数据不丢失,从而保证了生命周期内的 Pod 对象数据持久化存储。

一个 Pod 对象代表某个应用程序的一个特定实例,如果需要扩展应用程序,那么即为此程序同时创建多个 Pod 实例,每个实例均代表应用程序的一个 ”副本“。这些容器 “副本” 的创建和管理操作通常由另一组称为 “控制器(Controller)” 的对象实现,例如,Deployment 控制器对象。

创建Pod 时,还可以使用 Pod Preset 对象为 Pod 注入特定的信息,如 ConfigMap、Secret、存储卷、卷挂载和环境变量等。有了 Pod Preset 对象,Pod 模板的创建者久无需为每个模板显式提供所有信息,因此,也就无须事先了解需要配置的每个应用的细节即可完成模板定义。

Controller

Kubernetes 集群设计中,Pod 是由生命周期的对象,用户通过手工创建或由 Controller(控制器) 直接创建的 Pod 对象会被 “调度器(Scheduler)” 调度至集群中的某工作节点运行,待到容器应用进程运行结束之后正常终止,随后就会被删除。另外,节点资源耗尽也会导致 Pod 对象被回收。

Pod 对象本身不具备 “自愈” 功能,若是因为工作节点甚至是调度器自身导致运行失败,那么它将会被删除;同样,资源耗尽或节点故障导致的回收操作也会删除相关的 Pod 对象,在设计上,Kubernetes使用 “控制器” 实现对一次性的(用后即弃) Pod 对象的管理操作,例如:要确保 Pod 副本数量严格反映用户期望的数目,以及基于 Pod 模板来重建的 Pod 对象等,从而实现 Pod 对象的扩缩容,滚动更新和自愈能力。例如某 Pod 节点发生故障时,相关控制器会将此节点上运行的 Pod 对象重新调度到其它节点进行重建。

控制器本身也是一种资源类型,它有着多种实现,其中与工作负载相关的实现如 Replication、Controller、Deployment、StatefulSet、DaemonSet、DaemonSet、和 Jobs 等,也可统称他们为 Pod 控制器,如下图中Deployment 就是这类控制器的代表实现,是目前最常用的管理无状态应用的 Pod 控制器。

Pod 控制器的定义是由期望的副本数量、Pod 模板和标签选择器(Label Selector)组成。Pod 控制器会根据标签选择器对 Pod 对象的标签进行匹配检查,所有满足条件的 Pod 对象都将受控于当前控制器并计入其副本总数,并确保此数目能够精确反映期望的副本数量。

在实际的应用场景中,在接收到请求流量负载明显低于或者接近已用 Pod 副本的整体承载能力时,用户需要手动修改 Pod 控制器中的期望副本数量以实现应用规模的扩容或缩容。如果集群中部署了 HeapSter 或 Prometheus 一类的资源指标监控附件时,用户可以使用 “HorizontalPodAutoscaler"(HPA) 计算出合适的 Pod 副本数量,并自动修改 Pod 控制器中期望的副本数以实现应用规模的动态伸缩,提高集群资源利用率。
Kubernetes 集群中的每个节点都运行着 cAdvisor 用来收集容器及 Pod 节点的 CPU、内存及磁盘资源的利用率指标数据,这些统计数据由 Heapster 聚合后可通过 API Server 访问。HorizontalPodAutoscaler 基于这些统计数据监控容器健康状态并作出扩展决定。

Service

虽然 Pod 对象可以拥有 IP 地址,但是 Pod 地址无法确保在 Pod 对象重启或重建后保持不变,对此解决办法为,Service 资源被用于在被访问的 Pod 对象中添加一个有固定 IP 地址的中间层,客户端向此地址发起访问请求后由相关的 Service 资源调度并代理至后端的 Pod 对象。Service 是通过定义出多个 Pod 对象组合而成的逻辑组合,并附带访问这组 Pod 对象的策略。Service 对象挑选关联 Pod 对象的方式同 Pod 控制器已用,都是基于 标签选择器 Label Selector 进行定义。

Service IP 是一种虚拟IP,也称为 Cluster IP,它专用于集群内通信,通常使用专用的地址段,如 “10.96.0.0/12“网络,各 Service 对象的 IP 地址在此范围内由系统动态分配。
集群内的 Pod 对象可直接请求 Cluster IP,例如上图中来自 pod client 的访问请求即可以 Service 的 Cluster IP作为目标地址,但集群网络属于私有的网络地址,他们仅在集群内部可达,将集群外部的访问流量引入集群内部的常用方法是通过节点网络进行,实现方法是通过工作节点的 IP 地址和某端口(NodePort)接入请求并将其代理至相应的 Service 对象和 Cluster IP 上的服务端口,而后由 Service 对象将请求代理至后端的 Pod 对象的 Pod IP 及应用程序监听的端口,因此,上图中 External Clients 这种来自集群外部的客户端无法直接请求此 Service 听得服务,而是需要事先经由某一个工作节点(如 Node Y)的 IP 地址进行,这类请求需要两次才能到达目标 Pod 对象,因此在通信效率上必然存在负面影响。
NodePort 会部署于集群中的每一个节点,这就意味着,集群外部的客户端通过任何一个工作节点的 IP 地址来访问定义好的 NodePort 都可以到达相应的 Service对象。此种场景中,如果存在集群外部一个负载均衡器,即可将用用户请求负载均衡至集群中的部分或所有节点,这是一种称为 ”LoadBalancer“ 类型的 Service,它通常是由 Cloud Provider 自动创建并提供的软件负载均衡器。例如 Nginx、HAProxy或者硬件负载 F5等。

简单来说,Service 主要由三种常用类型;
第一种是仅用于集群内部通信的 Cluster IP类型。
第二种是接入集群外部请求的 NodePort 类型,它工作与每个节点的主机 IP 之上。
第三种是 LoadBalancer 类型,它可以把外部请求负责均衡至多个 Node 主机IP的Node Port之上。
三种类型中,每一种都以其前一种为基础才能实现,而且第三种类型中的 LoadBalancer 需要协同集群外部的组件才能实现,并且此外部组件不接受 Kubernetes 的管理。

部署 Kubernetes 集群

Kubernetes 集群部署的方式有很多选择,简单的可以基于 kubeadm 一类的部署工具运行几条命令即可实现,而复杂的则可以使从零开始手动构建集群环境。

kuberadm 部署工具

kubeadm 是 Kubernetes 项目自带的集群构建工具,它负责构建一个最小化的集群以及将其启动等必要的基本步骤,简单来讲,kubeadm 是 Kubernetes 集群全生命周期的管理工具,可用于实现集群的部署、升级/降级及拆除。在部署操作中,kubeadm 尽关心如何初始化并启动集群,余下的其他操作,例如安装 Kubernetes Dashboard、监控系统、日志系统等必要的附加组件则不再其考虑范围之内,需要自行部署。

kubeadm 集成了 kubeadm initkubeadm join等工具程序。
kubeadm init 工具用于集群初始化,其核心功能是部署 Master 节点的各个组件。
kubeadm join 工具用于将Node节点加入到指定集群中。
kubeadm token 可于集群构建后管理用于加入集群时使用的认证临牌 (token)。
kubeadm reset 命令的功能则是删除集群构建过程中生成的文件以重置回初始状态。

kubeadm 还支持管理初始引导认证令牌 (Bootstrap Token),完成待加入的新节点首次联系 API Server 时的身份认证(基于共享密钥)。另外,他们还支持管理集群版本的升降级操作。

集群运行模式

Kubernetes 集群支持三种运行模式:
1)独立组件模式:系统各个组件直接以守护进程的方式运行于节点智商,各组件之间相互协作构成集群。
2)静态 Pod 模式:除 kubelet 和 Docker 之外的其他组件 (如 etcd、kube-apiserver、kube-controller-mangeer和 kube-scheduler等)都是以静态 Pod 对象运行于 Master 主机之上。
3)自托管模式:这种模式是 Kubernetes的 自托管模式(self-hosted),它类似于第二种方式,将除了 kubelet 和 Docker 之外的其他组件运行为集群之上的 Pod 对象,但不同的是,这些 Pod 对象托管运行在 Kubernetes 集群自身之上受控于 DaemonSet 类型的控制器。而非静态的 Pod 对象。

使用 kubeadm 部署的 Kubernetes 集群可运行为第二种或者第三种模式,默认为静态 Pod 对象模式,需要使用自托管模式时,kubeadm init 命令使用 "--features-gates=selfHosting",选项即可,第一种模式集群的构建需要将各组件运行于系统之上的独立守护进程中,期间需要用到的证书及 Token 等认证信息也需要手动生成,过程繁琐且极易出错;若有必要用到,则建议使用 GitHub 上的项目辅助进行。

准备集群环境

如下图所示,该集群由一个 Master 主机和三个 Node 主机组成,基于 kubeadm 部署,除了kubelet 和 Docker 之外的其他集群组件都运行于 Pod 对象中。

角色 IP地址 主机名 系统版本 内核版本 docker版本 k8s版本
master 192.168.31.245 kube-master CentOS 7.6.1810 3.10.0-957.el7.x86_64 18.09.9 1.16.0
node 192.168.31.241 kube-node1 CentOS 7.6.1810 3.10.0-957.el7.x86_64 18.09.9 v1.16.2
node 192.168.31.242 kube-node2 CentOS 7.6.1810 3.10.0-957.el7.x86_64 18.09.9 v1.16.2
node 192.168.31.243 kube-node3 CentOS 7.6.1810 3.10.0-957.el7.x86_64 18.09.9 v1.16.2

设置部署Kubernetes必要条件

所有机器操作
安装Kubernetes至少需要2c/2ram以上
1.)关闭防火墙

systemctl stop firewalld && systemctl disable firewalld 

2.关闭SELinux

setenforce 0
sed -i 's/SELINUX=permissive/SELINUX=disabled/' /etc/sysconfig/selinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

3.时钟校对

yum install ntpdate.x86_64 -y
timedatectl set-timezone Asia/Shanghai
/sbin/ntpdate ntp2.aliyun.com;/sbin/hwclock -w
cat >> /var/spool/cron/root << EOF
#Clock synchronization
00 00 * * * /sbin/ntpdate ntp2.aliyun.com;/sbin/hwclock -w
EOF

4.修改内核参数

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

5.Swap交换分区
kubernetes自1.8版本起强制要求关闭系统上的交换分区(swap),否则无法启动,如果系统不足或者有其它重要进程使用交换分区时那么也是可以保留交换分区。

1)如果你要禁用交换分区

swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab

2)如果你要启用交换分区

创建交换区原则:
1.创建的swap交换区大小应该大于实际物理内存的容量大小,但是不要过大,以免造成硬盘空间浪费。
2.如果内存IO请求频繁,而单一swap交换区IO队列等待时间过长的话,可以多创建几个swap交换区。
3.原则上优先在IO速度最快的设备上创建。

#创建swap交换分区
#通常创建物理内存2~2.5倍大小的文件作为交换区。
dd if=/dev/zero of=/swap bs=1G count=8

#使用mkswap格式化文件为swap文件系统
#-f 使用文件作为swap交换区
mkswap -f /swap

#启用刚才创建的Swap文件
swapon /swap

#如果有必要可以设置开机自动启用swap文件交换区,修改/etc/fstab,增加一行
echo '/swap swap swap defaults 0 0' >> /etc/fstab

6.安装docker

yum install yum-utils device-mapper-persistent-data lvm2 -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce-18.09.9-3.el7 -y
systemctl enable docker && systemctl start docker

7.操作完成后建议重启下机器

reboot

master安装 kubeadm kubelet kubectl

master操作
由于官方Kubernetes镜像源在google,因各种不可描述原因,这里使用阿里云yum源

1.添加阿里云yum源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

2.安装kubeadm、kubectl、kubelet

yum clean all && yum makecache

#列出目前1.16的所有衍生版本
[root@kube-master src]# yum list kubectl --showduplicates | sort -r | grep 1.16
kubectl.x86_64                       1.16.3-0                         kubernetes
kubectl.x86_64                       1.16.2-0                         kubernetes
kubectl.x86_64                       1.16.1-0                         kubernetes
kubectl.x86_64                       1.16.0-0                         kubernetes
[root@kube-master src]# yum list kubeadm --showduplicates | sort -r | grep 1.16
kubeadm.x86_64                       1.16.3-0                         kubernetes
kubeadm.x86_64                       1.16.2-0                         kubernetes
kubeadm.x86_64                       1.16.1-0                         kubernetes
kubeadm.x86_64                       1.16.0-0                         kubernetes
[root@kube-master src]# yum list kubelet --showduplicates | sort -r | grep 1.16
kubelet.x86_64                       1.16.3-0                         kubernetes
kubelet.x86_64                       1.16.2-0                         kubernetes
kubelet.x86_64                       1.16.1-0                         kubernetes
kubelet.x86_64                       1.16.0-0                         kubernetes

#指定1.16.0版本进行安装
yum install kubectl-1.16.0-0 kubeadm-1.16.0-0 kubelet-1.16.0-0 -y

3.查看kubelet安装了哪些文件

[root@kube-master src]# rpm -ql kubelet 
/etc/kubernetes/manifests
/etc/sysconfig/kubelet
/usr/bin/kubelet
/usr/lib/systemd/system/kubelet.service

[root@kube-master src]# rpm -ql kubeadm
/usr/bin/kubeadm
/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

[root@kube-master src]# rpm -ql kubectl
/usr/bin/kubectl

4.配置kubelet(开启swap分区操作)
如果你禁用了swap分区,那么这步骤直接略过即可,如果开启了swap分区,那么需操作以下来对Kubernetes忽略禁用swap限制

cat <<EOF > /etc/sysconfig/kubelet 
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
EOF

5.设置kubelet服务*
配置文件修改完成后,需要设定kuberlet服务开机自动启动,这也是Kubeadm的强制要求

systemctl enable kubelet

node安装 kubeadm kubelet kubectl

node操作
1.添加阿里云yum源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

2.安装kubeadm、kubectl、kubelet

yum clean all && yum makecache
yum install kubectl-1.16.0-0 kubeadm-1.16.0-0 kubelet-1.16.0-0 -y

3.配置kubelet(开启swap分区操作)
如果你禁用了swap分区,那么这步骤直接略过即可,如果开启了swap分区,那么需操作以下来对Kubernetes忽略禁用swap限制

cat <<EOF > /etc/sysconfig/kubelet 
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
EOF

4.设置kubelet服务
配置文件修改完成后,需要设定kuberlet服务开机自动启动,这也是Kubeadm的强制要求

systemctl enable kubelet

集群初始化

Master节点操作
Master和各Node的Docker及kubelet配置完成后,便可以在master节点上执行 "kubeadm init”命令进行集群初始化。
初始化过程中 Kubernetes会下载管理节点所用到的 6 个 docker镜像分别为 Kubernetes 的各个组件,以 静态 Pod 的方式运行于容器之中。
kubeadm init命令支持两种初始化方式:
1)通过命令行选项传递关键的参数设定
2)基于 yaml 格式的专用配置文件设定更详细的配置参数
这里演示通过第一种方法进行初始化。

1.Master 初始化

[root@kube-master src]# kubeadm init \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.16.0 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--apiserver-advertise-address=0.0.0.0 \
--ignore-preflight-errors=Swap \
--token-ttl 30m

参数解释:

  • --image-repository:初始化过程中会去docker仓库拉去镜像,默认指定的为docker hub,所以在此使用--image-repository参数指定阿里云镜像。
  • --kubernetes-version:指定正在使用的 Kubernetes 程序组件的版本号,需要与 kubelet 的版本号相同。
  • --pod-network-cidr:Pod 网络的地址范围,其值为 CIDR 格式的网络地址,使用 flannel 网络插件时,其默认地址为 10.244.0.0/16
  • --service-cidr:Service 的网络地址范围,其值为 CIDR 格式的网络地址,默认地址为 10.96.0.0/12
  • --apiserver-advertise-address:API Server 通告给其它组件的IP地址,一般为 Master 节点的IP地址,0.0.0.0 标识节点上所有可用的地址。
  • ignore-preflight-errors:忽略哪些运行时的错误信息,其值为 Swap 时,表示忽略因 swap 未关闭而导致的错误。
  • --token-ttl:token令牌自动删除时间,默认为24小时,指定为 0 表示永不过期,指定单位可以使 秒s 分m 时h,在node加入Kubernetes集群时需要指定token。

初始化过程中到 kubeadm config images pull 会稍有卡顿

2.初始化完成返回如下

3.设定 kubectl 配置文件
kubectl 是执行 kubernetes 集群管理的核心工具。默认情况下,kubectl会从当前用户主目录(保存于环境变量HOME中的值)中隐藏目录 .kube 下名为 config 的配置文件中读取配置信息,包括要接入 Kubernetes 集群、以及用于集群认证的证书或令牌等信息,集群初始化时,kubeadm 会自动生成一个用于此类功能的配置文件 /etc/kubernetes/admin.conf,将它复制为用户的 $HOME/.kube.config即可直接使用。
直接复制以上绿色框画中的命令即可

[root@kube-master src]# mkdir -p $HOME/.kube
[root@kube-master src]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@kube-master src]# sudo chown $(id -u):$(id -g) $HOME/.kube/config

目前,一个 Kubernetes Master 节点已经配置完成。
使用 kubectl get nodes可以获取到集群节点相关状态信息,如果命令结果Master节点状态为 “NotReady(未就绪)”,这是因为集群中尚未安装网络插件所致,网络插件安装完成后即为 "Ready(就绪)" 状态。

[root@kube-master src]# kubectl get nodes
NAME          STATUS     ROLES    AGE     VERSION
kube-master   NotReady   master   9m23s   v1.16.0

如果你的配置或输出结果有误,则可以通过 kubeadm reset 命令重新进行集群初始化

部署网络插件

Master操作
为 Kubernetes 提供 Pod 网络插件的有很多,目前最流行的是 flannelCalico。相比较来说,flannel 以其简单、易部署、易用性广受欢迎。
基于 kubeadm 部署时,flannel 同样运行为 Kubernetes 集群的附件,以 Pod 的形式部署运行于每个集群节点上以接受 Kubernetes 集群管理。部署方式可以获取其资源清单于本地而后部署集群中,也可以直接在线进行应用部署。部署命令是 kubectl applykubectl create

1.flannel 网络插件部署

[root@kube-master src]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

手动下载kube-flannel.yml文件后,修改其地址quay.ioquay-mirror.qiniu.com,因quay.io为国外地址,国内访问超级慢,如果你没有正确的上网,那么必定拉不下 flannel镜像,所以这里把 quay.io 改为国内地址 quay-mirror.qiniu.com

[root@kube-master src]# sed -i 's/quay.io/quay-mirror.qiniu.com/g' kube-flannel.yml
[root@kube-master src]# kubectl apply -f kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds-amd64 created
daemonset.apps/kube-flannel-ds-arm64 created
daemonset.apps/kube-flannel-ds-arm created
daemonset.apps/kube-flannel-ds-ppc64le created
daemonset.apps/kube-flannel-ds-s390x created

配置 flannel 网络插件时,Master 节点上的 Docker 首先会去获取 flannel 的镜像文件,而后根据镜像文件启动相应的 Pod 对象。待其运行完成后再次检查集群中的节点状态可以看出 Master 已经变为 "Ready" 状态。

[root@kube-master src]# kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
kube-master   Ready    master   13m   v1.16.0

如果发现你的 flannel Pod 处于 ImagePullBackOff 状态,那么就是 flannel 镜像未拉取成功,而正常的则为 Running状态

[root@kube-master src]# kubectl get pods -n kube-system | grep flannel
kube-flannel-ds-amd64-wtk6q           1/1     Running   0          3m28s

2.正确上网部署flannel(可选)
如果你可以正确规范上网,则使用以下可直接进行部署

[root@kube-master src]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

3.卸载flannel网络插件(可选)
如果你的网络插件 flannel 拉取失败,或需要重新部署此插件,可以使用 kubectl delete -f $uri 来进行删除此配置

[root@kube-master src]# kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

添加Node到集群

任何一个Node加入集群中的节点都需要先经过 API Server 完成认证,其认证方法和认证信息在 Master 上进行集群初始化的时 kubeadm init 命令执行时输出到了最后一行。
图示:

如果忘记了加入集群的命令,可通过 kubeadm token create --print-join-command命令获取

[root@kube-master src]# kubeadm token create --print-join-command
kubeadm join 192.168.31.245:6443 --token e0vezd.o8s6mopfjibpbpaq     --discovery-token-ca-cert-hash sha256:947146190e917a2a06f7319602bd512aab4206cf9a058dca4e66e4aa1ac99ab2

在Node加入集群时需要加上 --ignore-preflight-errors=Swap 选项来忽略Swap分区警告问题。
提供给 API Server 的 bootstap token 认证完成后,kubeadm join 命令会为后续 Master 与 Node 组件间的双向 ssl/tls 认证生成私钥及证书签署请求,并由 Node 在首次加入集群时提交给 Master 端的 CA 进行签署。默认情况下,kubeadm 配置 kube-apiserver 启用了 bootstrap TLS功能,并支持证书的自动签署。于是,kubelet 及 kube-proxy 等组件的相关私钥和证书文件在命令执行结束后便可自动生成,他们默认莫存储于 /var/lib/kubelet/pki目录中

kube-node1加入集群

[root@kube-node1 ~]# kubeadm join 192.168.31.245:6443 \
--token e0vezd.o8s6mopfjibpbpaq  \
--ignore-preflight-errors=Swap \
--discovery-token-ca-cert-hash \
sha256:947146190e917a2a06f7319602bd512aab4206cf9a058dca4e66e4aa1ac99ab2

kube-node2加入集群

[root@kube-node2 ~]# kubeadm join 192.168.31.245:6443 \
--token e0vezd.o8s6mopfjibpbpaq  \
--ignore-preflight-errors=Swap \
--discovery-token-ca-cert-hash \
sha256:947146190e917a2a06f7319602bd512aab4206cf9a058dca4e66e4aa1ac99ab2

kube-node3加入集群

[root@kube-node3 ~]# kubeadm join 192.168.31.245:6443 \
--token e0vezd.o8s6mopfjibpbpaq  \
--ignore-preflight-errors=Swap \
--discovery-token-ca-cert-hash \
sha256:947146190e917a2a06f7319602bd512aab4206cf9a058dca4e66e4aa1ac99ab2

Master查看集群状态
以下节点状态都为 "Ready" 就绪状态,则证明集群部署成功。当然现在只是最小化部署Kubernetes集群,一个功能完整的 Kubernetes 集群应当具备的附加组件还包括 DashboardIngress ControllerHeapster/Prometheus等。

[root@kube-master src]# kubectl get nodes
NAME          STATUS   ROLES    AGE     VERSION
kube-master   Ready    master   30m     v1.16.0
kube-node1    Ready    <none>   2m32s   v1.16.0
kube-node2    Ready    <none>   89s     v1.16.0
kube-node3    Ready    <none>   86s     v1.16.0

kubeadm init 初始化信息可通过 kubeadm config 命令来进行导出为 yaml 格式的文件

[root@kube-master src]# kubeadm config print init-defaults > kubeadm-init.yaml
[root@kube-master src]# cat kubeadm-init.yaml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 1.2.3.4
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: kube-master
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.16.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}

获取集群状态信息

Kubernetes集群Server端和Client端的版本等信息可以使用 kubectl version 命令进行查看

[root@kube-master src]# kubectl version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.0", GitCommit:"2bd9643cee5b3b3a5ecbd3af49d09018f0773c77", GitTreeState:"clean", BuildDate:"2019-09-18T14:36:53Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.0", GitCommit:"2bd9643cee5b3b3a5ecbd3af49d09018f0773c77", GitTreeState:"clean", BuildDate:"2019-09-18T14:27:17Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}

默认输入信息很多,这里可简化只查看版本号

[root@kube-master src]# kubectl version --short=true
Client Version: v1.16.0
Server Version: v1.16.0

Kubernetes的API Server地址,此地址通常被其它程序所调用,查看Kubernetes API Server地址

[root@kube-master src]# kubectl cluster-info
Kubernetes master is running at https://192.168.31.245:6443
KubeDNS is running at https://192.168.31.245:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

也可以使用 kubectl cluster-info dump 来获取 kubernetes 集群的更多信息 metadata元数据

从集群中移除节点

运行过程中,若有节点需要从正常运行的集群中移除,则可使用如下步骤进行。

例如我们将 kube-node2 从 kubernetes 集群中移除,如下:
1.在Master使用 kubectl drain 命令将 kube-node2 上的所有资源迁移至集群中的其它节点

[root@kube-master src]# kubectl drain kube-node2 --delete-local-data --force --ignore-daemonsets
[root@kube-master src]# kubectl get nodes
NAME          STATUS                     ROLES    AGE   VERSION
kube-master   Ready                      master   52m   v1.16.0
kube-node1    Ready                      <none>   24m   v1.16.0
kube-node2    Ready,SchedulingDisabled   <none>   23m   v1.16.0
kube-node3    Ready                      <none>   23m   v1.16.0

2.从 Kubernetes 集群中移除 kube-node2 节点

[root@kube-master src]# kubectl delete node kube-node2
node "kube-node2" deleted
[root@kube-master src]# kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
kube-master   Ready    master   53m   v1.16.0
kube-node1    Ready    <none>   25m   v1.16.0
kube-node3    Ready    <none>   24m   v1.16.0

3.将 kube-node2 重新加入Kubernetes集群

#在Master获取加入集群 token
[root@kube-master src]# kubeadm token create --print-join-command
kubeadm join 192.168.31.245:6443 --token 6fs57x.86ljj77hakrzf9h0     --discovery-token-ca-cert-hash sha256:947146190e917a2a06f7319602bd512aab4206cf9a058dca4e66e4aa1ac99ab2
#在kube-node2上进行加入操作,加入集群前必须先经过重置,因之前有加入集群的信息存在,须先清空
[root@kube-node2 ~]# kubeadm reset
[root@kube-node2 ~]# kubeadm join 192.168.31.245:6443 \
--token e0vezd.o8s6mopfjibpbpaq  \
--ignore-preflight-errors=Swap \
--discovery-token-ca-cert-hash \
sha256:947146190e917a2a06f7319602bd512aab4206cf9a058dca4e66e4aa1ac99ab2

4.在主节点获取节点信息

[root@kube-master src]# kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
kube-master   Ready    master   59m   v1.16.0
kube-node1    Ready    <none>   31m   v1.16.0
kube-node2    Ready    <none>   12s   v1.16.0           #kube-node2已加入
kube-node3    Ready    <none>   29m   v1.16.0

查看 Master与Node 都运行了哪些组件

Master

Nodes

人已赞赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧