一、Kubernetes 概述
1.1、什么是 Kubernetes
Kubernetes 是一个可移植、可扩展的开源容器编排系统,主要用于自动化部署、扩展和管理容器应用,提供资源调度、部署管理、服务发现、扩容缩容、监控等功能。对于负载均衡、服务发现、高可用、滚动升级、自动伸缩等容器云平台的功能要求有原生支持。由于 Kubernetes 在 K 和 s 间有 8 个字母,因此常简称为 K8S。2015 年 7 月,Kubernetes V1.0 正式发布,截止到目前最新稳定版本是 V1.18。
事实上,随着对 K8S 系统架构与设计理念的深入了解,可以发现 K8S 系统正是处处为运行云原生应用而设计考虑的。随着对 K8S 系统使用的加深和推广,也会有越来越多有关云原生应用的设计模式产生,使得基于 K8S 系统设计和开发生产级的复杂云原生应用,变得像启动一个单机版容器服务那样简单易用。
Kubernetes 可以调度计算集群节点、动态管理节点上作业,并保证它们按用户期望状态运行。通过使用「Labels(标签)」和「Pods(荚)」的概念,Kubernetes 将应用按逻辑单元进行分组,方便管理和服务发现。
1.2、为什么要用 Kubernetes
使用 Kubernetes 具有以下好处。
- 具备微服务架构
微服务架构的核心是将一个巨大的单体应用分解为很多小的互相连接的微服务。一个微服务背后可能有多个实例副本支撑,副本的数量可能会根据系统负荷变化而进行调整,而 K8S 平台中内嵌的负载均衡器发挥着重要作用。微服务架构使得每个服务都可以由专门的开发团队来开发,开发者可以自由选择开发技术,这对于大规模团队来说很有价值。另外, 每个微服务独立开发、升级、扩展,使得系统具备很高的稳定性和快速迭代进化能力。
- 具备超强的横向扩展能力
Kubernetes 系统架构具备超强的横向扩容能力。对于互联网公司来说,用户规模等价于资产,谁拥有更多的用户,谁就能在竞争中胜出,因此超强的横向扩容能力是互联网业务系统的关键指标之一。一个 Kubernetes 集群可从只包含几个 Node 的小集群,平滑扩展到拥有成百上千个 Node 的大规模集群,利用 Kubernetes 提供的工具,甚至可以在线完成集群的扩容。只要微服务设计的合理,结合硬件或者公有云资源的线性增加,系统就能够承受大量用户并发访问所带来的压力。
1.3、Kubernetes 组件
为了理解 Kubernetes 工作原理,先来剖析下 Kubernetes 的结构。Kubernetes 主要包括以下组件。
1)Master 组件
Master 组件提供集群的管理控制中心,对集群进行全局决策(如调度),并检测和响应集群事件,例如当复制控制器的“副本”字段不满足时启动新的 Pod。基本上 Kubernetes 所有的控制命令都是发给 Master,Master 负责具体的执行过程。Master 组件可以在群集中的任何计算机上运行,但建议 Master 节点占据一个独立的服务器。因为 Master 是整个集群的大脑,如果 Master 所在节点宕机或不可用,那么所有的控制命令都将失效。
Master 组件运行的节点一般称之为 Master 节点,在 Master 节点上运行着以下关键进程。
- Kube-apiserver:用于暴露 Kubernetes API,任何资源请求/调用操作都是通过 kube-apiserver 提供的接口进行。提供了 HTTP Rest 接口的关键服务进程,是 Kubernetes 中所有资源的增、删、改、查等操作的唯一入口,也是集群控制入口进程;
- Etcd:是 Kubernetes 提供的默认存储,所有集群数据都保存在 Etcd 中,使用时建议为 Etcd 数据提供备份计划;
- Kube-scheduler:是负责资源调度的进程,监视新创建且没有分配到 Node 的 Pod,为 Pod 选择一个 Node;
- Kube-controller-manager:运行管理控制器,是集群中处理常规任务的后台线程,是 Kubernetes 里所有资源对象的自动化控制中心。逻辑上,每个控制器是一个单独的进程,但为了降低复杂性,它们都被编译成单个二进制文件,并在单个进程中运行。这些控制器主要包括:
- 节点控制器(Node Controller):负责在节点出现故障时发现和响应;
- 复制控制器(Replication Controller):负责为系统中的每个复制控制器对象维护正确数量的 Pod;
- 端点控制器(Endpoints Controller):填充端点对象(即连接 Services 和 Pods);
- 服务帐户和令牌控制器(Service Account & Token Controllers):为新的命名空间创建默认帐户和 API 访问令牌。
2)Node 组件
除了 Master,Kubernetes 集群中的其他机器被称为 Node 节点。与 Master 节点一样, Node 节点可以是一台物理主机,也可以是一台虚拟机。Node 节点是 Kubernets 集群中的工作负载节点,每个 Node 都会被 Master 分配一些工作负载。当某个 Node 宕机时,其上的工作负载会被 Master 自动转移到其他节点上去。
每个 Node 节点上都运行着以下关键进程:
- kubelet:负责 Pod 对应容器的创建、起停等任务,同时与 Master 节点密切协作,实现集群管理的基本功能。
- Kube-proxy:用于实现 Kubernetes Service 之间的通信与负载均衡机制。
- Docker Engine(docker):Docker 引擎,负责本机的容器创建和管理工作。
Node 节点可以在运行期间动态增加到 Kubernetes 集群中,前提是这个节点上已经正确安装、配置和启动了上述关键进程。在默认情况下,Kubelet 会向 Master 注册自己,这也是 Kubernetes 推荐的 Node 管理方式。一旦 Node 被纳入集群管理范围,Kubelet 进程会定时向 Master 汇报自身的情况,例如操作系统、Docker 版本、机器的 CPU 和内存情况, 以及之前有哪些 Pod 在运行等。这样 Master 可以获知每个 Node 的资源使用情况,并实现高效负载均衡资源调度策略。而某一个 Node 超过指定时间不上报信息时,会被 Master 判定为失聪的状态,被标记为不可用,随后 Master 会触发节点转移进程。
1.4、Kubernetes 资源对象
Kubernetes 包含多种类型的资源对象:Pod、Replication Controller、Service、 Deployment、Job、DaemonSet 等。所有的资源对象都可以通过 Kubernetes 提供的 kubectl 工具进行增、删、改、查等操作,并将其保存在 Etcd 中持久化存储。从这个角度来看, Kubernets 其实是一个高度自动化的资源控制系统,通过跟踪对比 Etcd 存储里保存的资源期望状态与当前环境中的实际资源状态的差异,来实现自动控制和自动纠错等高级功能。下面对常用的资源对象分别进行介绍。
1)Pod
Pod(豆荚)是 Kubernetes 创建或部署的最小/最简单的基本单位,一个 Pod 代表集群上正在运行的一个进程。一个 Pod 由一个或多个容器组成,Pod 中容器共享存储和网络, 在同一台 Docker 主机上运行。每个 Pod 都有一个特殊的被称为“根容器”的 Pause 容器, Pause 容器对应的镜像属于 Kubernetes 平台的一部分。除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器。
2)Label
Label(标签)是 Kubernetes 系统中另外一个核心概念。一个 Label 是一个 key-value 的键值对,其中 key 与 value 由用户自己指定。Label 可以附加到各种资源对象上,例如 Node、Pod、Service、RC 等。一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源对象中,也可以在对象创建后动态添加或者删除。
另外可以通过给指定的资源对象捆绑一个或多个不同的 Label,来实现多纬度的资源分组管理功能,以便于灵活、方便地进行资源分配、调度、配置、部署等管理工作。给某个资源对象定义一个 Label,就相当于给它打了一个标签;随后可以通过 Label selector 标签选择器查询和筛选拥有某些 Label 的资源对象,Kubernetes 通过这种方式实现了类似 SQL 的简单又通用的对象查询机制。
3) Replication Controller
Replication Controller(复制控制器,RC)是 Kubernetes 集群中最早的保证 Pod 高可用的 API 对象。通过监控运行中的 Pod 来保证集群中运行指定数目的 Pod 副本。指定的数目可以是 1 个或多个;如果少于指定数目,RC 就会运行新的 Pod 副本。如果多于指定数目, RC 就会杀死多余的 Pod 副本。即使在数目为 1 的情况下,通过 RC 运行 Pod 也比直接运行 Pod 更明智,因为 RC 可以发挥它高可用的能力,保证永远有 1 个 Pod 在运行。RC 是 K8S 较早期的技术概念,只适用于长期伺服型的业务类型,比如控制小机器人提供高可用 的 Web 服务。
4)Deployment
Deployment(部署)表示用户对 K8S 集群的一次更新操作。部署是一个比 RS 应用模式更广的 API 对象,可以是创建或更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减小到 0 的复合操作;这样一个复合操作用一个 RS 是不太好描述的,需要用一个更通用的 Deployment 来描述。未来对所有长期服务型业务的管理,都会通过 Deployment 来管理。
5)Service
RC 和 Deployment 只是保证了支撑 Service(服务)的微服务 Pod 的数量,但是没有解决如何访问这些服务的问题。一个 Pod 只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的 IP 地址启动一个新的 Pod,因此不能以固定的 IP 地址和端口号提供服务。要稳定地提供服务,需要服务发现和负载均衡能力。服务发现完成的工作, 是针对客户端访问的服务,找到对应的的后端服务实例。
在 K8S 集群中,客户端需要访问的服务就是 Service 对象。每个 Service 会对应一个集群内部有效的虚拟 IP,集群内部通过虚拟 IP 访问一个服务。在 K8S 集群中微服务的负载均衡是由 Kube-proxy 实现的。Kube-proxy 是 K8S 集群内部的负载均衡器。它是一个分布式代理服务器,在 K8S 的每个节点上都会运行一个 Kube-proxy 组件;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的 Kube-proxy 就越多,高可用节点也随之增多。与之相比,通过在服务器端部署反向代理做负载均衡,还需要进一步解决反向代理的负载均衡和高可用问题。
6)Job 计划任务
Job 是 Kubernetes 用来控制批处理型任务的 API 对象。批处理业务与长期服务业务的主要区别是批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。 根据用户的设置,Job 管理的 Pod 把任务成功完成就自动退出了。成功完成的标志根据不同的 spec.completions 策略而不同:单 Pod 型任务有一个 Pod 成功就标志完成;定数成功型任务保证有 N 个任务全部成功;工作队列型任务根据应用确认的全局成功而标志成功。
7)DaemonSet
后台支撑型服务的核心关注点在 Kubernetes 集群中的节点(物理机或虚拟机), DaemonSet(守护程序集)确保所有或某些节点运行同一个 Pod,要保证每个节点上都有一个此类 Pod 运行。节点可能是所有集群节点也可能是通过 nodeSelector 选定的一些特定节点。典型的后台支撑型服务包括,存储,日志和监控等在每个节点上支持 K8S 集群运行的服务。
上述组件与资源对象是 Kubernetes 系统的核心,它们共同构成了 Kubernetes 系统的框架和计算模型,如下图所示。通过对它们进行灵活配置,用户就可以快速、方便地对容器集群进行配置和管理。除了本章所介绍的核心组件与资源对象之外,在 Kubernetes 系统中还有很多辅助的资源对象,例如 LimitRange、ResouceQuota。另外,一些系统内部使用的对象可以参考 Kubernetes 的 API 文档。
Kubernetes 系统的框架和计算模型
1.5、什么是 Kubeadm
Kubeadm 是谷歌推出的一个专门用于快速部署 kubernetes 集群的工具。在集群部署的过程中,可以通过 kubeadm init 来初始化 master 节点,然后使用 kubeadm join 将其他的节点加入到集群中。
Kubeadm 通过简单配置可以快速将一个最小可用的集群运行起来。它在设计之初关注点是快速安装并将集群运行起来,而不是一步步关于各节点环境的准备工作。同样的, kubernetes 集群在使用过程中的各种插件也不是 kubeadm 关注的重点,比如 kubernetes 集群 WEB Dashboard、prometheus 监控集群业务等。kubeadm 应用的目的是作为所有部署的基础,并通过 kubeadm 使得部署 kubernetes 集群更加容易。
Kubeadm 的简单快捷的部署可以应用到如下三方面:
- 新用户可以从 kubeadm 开始快速搭建 Kubernetes 并了解。
- 熟悉 Kubernetes 的用户可以使用 kubeadm 快速搭建集群并测试他们的应用。
- 大型的项目可以将 kubeadm 配合其他的安装工具一起使用,形成一个比较复杂的系统。
二、Kubeadm 快速安装 Kubernetes 集群
2.1、环境介绍
1)本实验环境
本节采用 Kubeadm 方式来安装 Kubernetes 集群,实验环境包括一台 master 节点,两台 node 节点,具体配置要求如下表所示。
主机名 | IP 地址 | 操作系统 | 主要软件 |
k8s-master | 192.168.23.10 | CentOS7.6 | Docker-ce-19.03.15、Docker-ce-cli-19.03.15、Kube-api-server、Kube-controller-manager、Kube-scheduler、Kubelet、Etcd、Kube-proxy |
k8s-node01 | 192.168.23.14 | CentOS7.6 | Docker-ce-19.03.15、Docker-ce-cli-19.03.15、Kubectl、Kube-proxy、Flannel |
k8s-node02 | 192.168.23.15 | CentOS7.6 | Docker-ce-19.03.15、Docker-ce-cli-19.03.15、Kubectl、Kube-proxy、Flannel |
2)实验要求
本节的实验要求:通过 Kubeadm 快速部署 Kubernetes 集群。
3)实现思路
本节的实现思路如下:
- 部署三台主机的基础环境。
- 部署三台主机的 Docker 环境。
- 通过 Kubeadm 快速部署 Kubernetes 集群。
2.2、基础环境准备
正式开始部署 kubernetes 集群之前,先要进行如下准备工作。基础环境相关配置操作在三台主机 k8s-master、k8s-node01、k8s-node02 上都需要执行,下面以 k8s-master 主机为例进行操作演示。
1)基础网络信息配置
依据案例环境为三台主机配置 IP 地址、网关、DNS 等基础信息,确保可连接互联网, 推荐虚拟机使用 NAT 模式。k8s-master 主机最小配置为 2 核 2G,k8s-node 节点最小配置 为 1 核 1G。
2)配置主机名
在三台主机上,分别执行下面的命令进行对应的设置。
[root@centos7-10 ~]# hostnamectl set-hostname k8s-master
[root@centos7-10 ~]# bash
[root@k8s-master ~]#
[root@centos7-14 ~]# hostnamectl set-hostname k8s-node01
[root@centos7-14 ~]# bash
[root@k8s-node01 ~]#
[root@centos7-15 ~]# hostnamectl set-hostname k8s-node02
[root@centos7-15 ~]# bash
[root@k8s-node02 ~]#
3)绑定 hosts
三台主机上操作
[root@k8s-master ~]# vim /etc/hosts
......//省略部分内容
//添加以下三行
192.168.23.210 k8s-master
192.168.23.214 k8s-node01
192.168.23.215 k8s-node02
4)安装常用软件
三台主机上操作
[root@k8s-master ~]# yum -y install vim wget net-tools lrzsz
5)关闭防火墙
三台主机上操作
[root@k8s-master ~]# systemctl stop firewalld
[root@k8s-master ~]# systemctl disable firewalld
6)禁用 SELinux
三台主机上操作
[root@k8s-master ~]# sed -i '/^SELINUX=/s/enforcing/disabled/' /etc/selinux/config
[root@k8s-master ~]# setenforce 0
7)关闭交换分区
三台主机上操作
[root@k8s-master ~]# swapoff -a
[root@k8s-master ~]# sed -i '/swap/s/^/#/' /etc/fstab
2.3、Docker 环境部署
完成基础环境准备之后,在三台主机上分别部署 Docker 环境,因为 Kubernetes 对容器的编排需要 Docker 的支持。以 k8s-master 主机为例进行操作演示,首先安装一些 Docker 的依赖包,然后将 Docker 的 YUM 源设置成国内地址,最后通过 YUM 方式安装 Docker 并启动。
1)安装依赖包
在正式安装 Docker 之前,需要先将 Docker 运行所需的一些依赖软件包安装好。
三台主机上操作
[root@k8s-master ~]# yum install -y yum-utils device-mapperpersistent-data lvm2
2)添加 YUM 软件源
三台主机上操作
使用 YUM 方式安装 Docker 时,推荐使用阿里的 YUM 源。阿里的官方开源站点地址是:https://developer.aliyun.com/mirror/,可以在站点内找到 Docker 的源地址。添加阿里源的命令如下所示。
[root@k8s-master ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
3)更新 YUM 源缓存并安装 Docker
三台主机上操作
[root@k8s-master ~]# yum makecache fast
[root@k8s-master ~]# yum -y install docker-ce-19.03.15 docker-ce-cli-19.03.15
4)启动 Docker
三台主机上操作
[root@k8s-master ~]# systemctl enable docker
[root@k8s-master ~]# systemctl start docker
5)配置加速器
三台主机上操作
很多镜像都是在国外的服务器上,由于网络上存在的问题,经常导致无法拉取镜像的错误,所以最好将镜像拉取地址设置成国内的。目前国内很多公有云服务商都提供了镜像加速服务。镜像加速配置如下所示。
[root@k8s-master ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn", //Azure中国镜像
"https://hub-mirror.c.163.com" //网易云加速器
]
}
[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]# systemctl restart docker
将镜像加速地址直接写入/etc/docker/daemon.json 文件内,如果文件不存在,可直接新建文件并保存。通过该文件扩展名可以看出,daemon.json 的内容必须符合 json 格式, 书写时要注意。同时,由于单一镜像服务存在不可用的情况,在配置加速时推荐配置两个或多个加速地址,从而达到冗余、高可用的目的。
6)内核优化
三台主机上操作
在 Docker 的使用过程中有时会看到下面这个警告信息。
WARNING:bridge-nf-call-iptables is disabled
WARNING:bridge-nf-call-ip6tables is disabled
这种警告信息可通过配置内核参数的方式来消除,具体配置如下。
[root@k8s-master ~]# cat << EOF >> /etc/sysctl.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> EOF
[root@k8s-master ~]# sysctl -p
2.4、部署 Kubernetes 集群
准备好基础环境和 Docker 环境,下面就开始通过 Kubeadm 来部署 Kubernetes 集群。
1)配置 Kubernetes 的 YUM 源
三台主机上操作
这里使用的 Kubernetes 源同样推荐使用阿里的。
[root@k8s-master ~]# 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)安装 Kubelet、kubeadm 和 kubectl
三台主机上操作
[root@k8s-master ~]# yum -y install kubelet-1.17.4 kubeadm-1.17.4 kubectl-1.17.4
如果在命令执行过程中出现索引 gpg 检查失败的情况, 请使用 yum install -y --nogpgcheck kubelet kubeadm kubectl 来安装。
3)Kubelet 设置开机启动
三台主机上操作
[root@k8s-master ~]# systemctl enable kubelet
kubelet 刚安装完成后,通过 systemctl start kubelet 方式是无法启动的,需要加入节点或初始化为 master 后才可启动成功。
4)生成初始化配置文件
master 节点上操作
Kubeadm 提供了很多配置项,Kubeadm 配置在 Kubernetes 集群中是存储在 ConfigMap 中的,也可将这些配置写入配置文件,方便管理复杂的配置项。Kubeadm 配置内容是通过 kubeadm config 命令写入配置文件的。
[root@k8s-master ~]# kubeadm config print init-defaults > init-config.yaml
W0514 15:55:39.321049 17329 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0514 15:55:39.321147 17329 validation.go:28] Cannot validate kubelet config - no validator is available
其中,kubeadm config 除了用于输出配置项到文件中,还提供了其他一些常用功能, 如下所示。
- kubeadm config view:查看当前集群中的配置值。
- kubeadm config print join-defaults:输出 kubeadm join 默认参数文件的内容。
- kubeadm config images list:列出所需的镜像列表。
- kubeadm config images pull:拉取镜像到本地。
- kubeadm config upload from-flags:由配置参数生成 ConfigMap。
5)修改初始化配置文件
master 节点操作
[root@k8s-master ~]# vim init-config.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: 192.168.23.210 //修改此行、master节点的 IP 地址
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master //如果使用域名保证可以解析、或直接使用 IP 地址
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 //etcd 容器挂载到本地的目录
imageRepository: registry.aliyuncs.com/google_containers //修改为国内的地址
kind: ClusterConfiguration
kubernetesVersion: v1.17.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16 //新增加 Pod 网段
scheduler: {}
上述配置文件中常用的功能块的作用如下所示。
- InitConfiguration:用于定义初始化配置,如初始化使用的 token 以及 apiserver 等。
- ClusterConfiguration:用于定义 apiserver、etcd、network、scheduler、controller-manager 等 master 组件相关配置项。
- KubeletConfiguration:用于定义 kubelet 组件相关的配置项。
- KubeProxyConfiguration:用于定义 kube-proxy 组件相关的配置项。
6)拉取所需镜像
master 节点上操作
[root@k8s-master ~]# kubeadm config images list --config init-config.yaml //列出所需的镜像列表
W0514 16:05:08.114643 17350 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0514 16:05:08.114752 17350 validation.go:28] Cannot validate kubelet config - no validator is available
registry.aliyuncs.com/google_containers/kube-apiserver:v1.17.0
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.17.0
registry.aliyuncs.com/google_containers/kube-scheduler:v1.17.0
registry.aliyuncs.com/google_containers/kube-proxy:v1.17.0
registry.aliyuncs.com/google_containers/pause:3.1
registry.aliyuncs.com/google_containers/etcd:3.4.3-0
registry.aliyuncs.com/google_containers/coredns:1.6.5
[root@k8s-master ~]# kubeadm config images pull --config=init-config.yaml //拉取所需的镜像
W0514 16:05:59.752778 17356 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0514 16:05:59.752892 17356 validation.go:28] Cannot validate kubelet config - no validator is available
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.17.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.17.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.17.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.17.0
[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.1
[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.4.3-0
[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:1.6.5
7)初始化 k8s-master
master 节点上操作
Kubeadm 通过初始化安装是不包括网络插件的,也就是说初始化之后是不具备相关网络功能的,比如 k8s-master 节点上查看节点信息都是“Not Ready”状态、Pod 的 CoreDNS 无法提供服务等。
[root@k8s-master ~]# kubeadm init --config=init-config.yaml //初始化安装 K8s
......//省略部分内容
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
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
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.23.210:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:8a1e405f23033aa13e5824e1819370d9196541d02ba0c55c06173080cfcff08d
[root@k8s-master ~]#
初始化安装结束后,需要关注的信息都已经在上面用黑体加粗了。查看是否有 “successfully”字样;复制配置文件到用户 home 目录是第 8 步要进行的操作;最后一行要保留下,因为这是其他节点加入到集群中需执行的命令,尤其不要漏掉 Token 信息。
8)复制配置文件到用户的 home 目录
master 节点操作
[root@k8s-master ~]# mkdir -p $HOME/.kube
[root@k8s-master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
9)node 节点加入集群
node 节点操作
[root@k8s-node01 ~]# kubeadm join 192.168.23.210:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:8a1e405f23033aa13e5824e1819370d9196541d02ba0c55c06173080cfcff08d
W0514 16:26:58.788168 16934 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.17" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
[root@k8s-node01 ~]#
[root@k8s-node02 ~]# kubeadm join 192.168.23.210:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:8a1e405f23033aa13e5824e1819370d9196541d02ba0c55c06173080cfcff08d
W0514 16:27:40.720350 16929 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.17" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
10)在 k8s-master 查看节点
在 master 节点上操作
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master NotReady master 18m v1.17.4
k8s-node01 NotReady <none> 8m28s v1.17.4
k8s-node02 NotReady <none> 7m46s v1.17.4
前面已经提到,在初始化 k8s-master 时并没有网络相关配置,所以无法跟 node 节点通信,因此状态都是“NotReady”。但是通过 kubeadm join 加入的 node 节点已经在 k8s-master 上可以看到。
11)安装网络
master 节点操作
[root@k8s-master ~]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml //下载 flannel 配置文件
[root@k8s-master ~]# kubectl apply -f kube-flannel.yml //运行开启 flannel 网络 Pod
12)查看节点状态
master 节点操作
[root@k8s-master ~]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master Ready master 5h16m v1.17.4 192.168.23.210 <none> CentOS Linux 7 (Core) 3.10.0-1160.71.1.el7.x86_64 docker://19.3.15
k8s-node01 Ready <none> 5h5m v1.17.4 192.168.23.214 <none> CentOS Linux 7 (Core) 3.10.0-1160.71.1.el7.x86_64 docker://19.3.15
k8s-node02 Ready <none> 5h5m v1.17.4 192.168.23.215 <none> CentOS Linux 7 (Core) 3.10.0-1160.71.1.el7.x86_64 docker://19.3.15
至此,通过 Kubeadm 快速安装 Kubernetes 集群已经完成。