二进制的方式部署 K8S-1.16 高可用集群

一、项目介绍

项目致力于让有意向使用原生kubernetes集群的企业或个人,可以方便的、系统的使用二进制的方式手工搭建kubernetes高可用集群。并且让相关的人员可以更好的理解kubernetes集群的运作机制。

软件版本

  • os centos7.7(ubuntu也适用,需要替换部分命令)

  • kubernetes 1.16.2

  • etcd 3.4.3

  • docker 18.06

  • calico 3.10.1-2

  • coredns

配置策略

kube-apiserver:

  • 使用节点本地 nginx 4 层透明代理实现高可用;

  • 关闭非安全端口 8080 和匿名访问;

  • 在安全端口 6443 接收 https 请求;

  • 严格的认证和授权策略 (x509、token、RBAC);

  • 开启 bootstrap token 认证,支持 kubelet TLS bootstrapping;

  • 使用 https 访问 kubelet、etcd,加密通信;

kube-controller-manager:

  • 3 节点高可用;

  • 关闭非安全端口 10252,在安全端口 10257 接收 https 请求;

  • 使用 kubeconfig 访问 apiserver 的安全端口;

  • 自动 approve kubelet 证书签名请求 (CSR),证书过期后自动轮转;

  • 各 controller 使用自己的 ServiceAccount 访问 apiserver;

kube-scheduler:

  • 3 节点高可用;

  • 关闭非安全端口 10251,在安全端口 10259 接收 https 请求;

  • 使用 kubeconfig 访问 apiserver 的安全端口;

kubelet:

  • 使用 kubeadm 动态创建 bootstrap token,而不是在 apiserver 中静态配置;

  • 使用 TLS bootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;

  • 在 KubeletConfiguration 类型的 JSON 文件配置主要参数;

  • 关闭只读端口 10255,在安全端口 10250 接收 https 请求,对请求进行认证和授权,拒绝匿名访问和非授权访问;

  • 使用 kubeconfig 访问 apiserver 的安全端口;

kube-proxy:

  • 使用 kubeconfig 访问 apiserver 的安全端口;

  • 在 KubeProxyConfiguration 类型的 JSON 文件配置主要参数;

  • 使用 ipvs 代理模式;

集群插件:

  • DNS:使用功能、性能更好的 coredns;

  • Dashboard:支持登录认证;

  • Metric:metrics-server,使用 https 访问 kubelet 安全端口;

  • Log:Elasticsearch、Fluend、Kibana;

  • Registry 镜像库:docker-registry、harbor;

二、实践环境准备

1. 服务器说明

我们这里使用的是五台centos 7.7虚拟机,具体信息如下表:

系统类型

IP地址

节点角色

CPU

Memory

Hostname

centos-7.7

172.18.0.100

master

>=2

>=2G

k8s-m01

centos-7.7

172.18.0.101

master

>=2

>=2G

k8s-m02

centos-7.7

172.18.0.102

master

>=2

>=2G

k8s-m03

centos-7.7

172.18.0.103

worker

>=2

>=2G

k8s-n01

centos-7.7

172.18.0.104

worker

>=2

>=2G

k8s-n02

使用二进制的方式部署 K8S-1.16 高可用集群(二十)

2. 系统设置(所有节点)

2.1 主机名

主机名必须每个节点都不一样,并且保证所有点之间可以通过 hostname 互相访问。

2.2 安装依赖包

2.3 关闭防火墙、swap,重置iptables

2.4 系统参数设置

2.5 加载内核模块

3. 安装docker(worker节点)

根据kubernetes对docker版本的兼容测试情况,我们选择18.06版本,我们配置阿里云的源,速度比较快。

4. 准备二进制文件(所有节点)

4.1 配置免密登录

为了方便文件的copy我们选择一个中转节点(随便一个节点,可以是集群中的也可以是非集群中的),配置好跟其他所有节点的免密登录,我们这里使用 k8s-m01。

4.2 下载二进制文件

官方下载地址(在CHANGELOG链接里面): https://github.com/kubernetes/kubernetes/releases

我们选择的版本是 1.16.2

网盘下载地址--推荐(我从官网下载整理好的文件): 链接: https://pan.baidu.com/s/1Ut9VERgm55B4lmz0wjjzFQ 提取码: mjem

4.3 分发文件

5. 准备配置文件(k8s-m01 节点)

上一步我们下载了kubernetes各个组件的二进制文件,这些可执行文件的运行也是需要添加很多参数的,包括有的还会依赖一些配置文件。现在我们就把运行它们需要的参数和配置文件都准备好。

5.1 下载配置文件

我这准备了一个项目,专门为大家按照自己的环境生成配置的。它只是帮助大家尽量的减少了机械化的重复工作。它并不会帮你设置系统环境,不会给你安装软件。总之就是会减少你的部署工作量,但不会耽误你对整个系统的认识和把控。

5.2 文件说明

addons :kubernetes的插件目录,包括calico、coredns、dashboard等。

configs:这个目录比较 - 凌乱,包含了部署集群过程中用到的杂七杂八的配置文件、脚本文件等。

pki:各个组件的认证授权相关证书配置。

services:所有的kubernetes服务(service)配置文件。

global-configs.properties:全局配置,包含各种易变的配置内容。

init.sh:初始化脚本,配置好global-config之后,会自动生成所有配置文件。

5.3 生成配置

这里会根据大家各自的环境生成kubernetes部署过程需要的配置文件。 在每个节点上都生成一遍,把所有配置都生成好,后面会根据节点类型去使用相关的配置。

三、高可用集群部署

1. CA证书(任意节点)

1.1 安装cfssl

cfssl是非常好用的CA工具,我们用它来生成证书和秘钥文件 安装过程比较简单,如下:

1.2 生成根证书

查看证书配置文件,CA 配置文件用于配置根证书的使用场景 (profile) 和具体参数 (usage,过期时间、服务端认证、客户端认证、加密等),后续在签名其它证书时需要指定特定场景。

  • signing:表示该证书可用于签名其它证书,生成的 ca.pem 证书中 CA=TRUE

  • server auth:表示 client 可以用该该证书对 server 提供的证书进行验证;

  • client auth:表示 server 可以用该该证书对 client 提供的证书进行验证;

查看证书签名请求文件。

  • CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法;

  • O:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group)

  • kube-apiserver 将提取的 User、Group 作为 RBAC 授权的用户标识;

根证书是集群所有节点共享的,只需要创建一个 CA 证书,后续创建的所有证书都由它签名。

2. 部署etcd集群(master节点)

2.1 下载etcd,并传到各master节点

2.2 生成证书和私钥

查看证书请求文件。

  • hosts 字段指定授权使用该证书的 etcd 节点 IP 或域名列表,需要将 etcd 集群的三个节点 IP 都列在其中;

2.3 创建service文件

2.4 启动服务

etcd 进程首次启动时会等待其它节点的 etcd 加入集群,命令 systemctl start etcd 会卡住一段时间,为正常现象。

3. 部署api-server(master节点)

3.1 生成证书和私钥

查看证书请求文件。

3.2 创建后续访问 metrics-server 使用的证书

创建证书签名请求:

  • CN 名称需要位于 kube-apiserver 的 --requestheader-allowed-names 参数中,否则后续访问 metrics 时会提示权限不足。

生成证书和私钥:

3.3 创建service文件

3.3 启动服务

4. 部署keepalived - apiserver高可用(master节点)

可以使用 nginx 做负载均衡器,把请求分发到后面三台apiserver服务器上面,这样最好,也是官方推荐的。

4.1 安装keepalived

4.2 创建keepalived配置文件

4.3 启动keepalived

5. 部署kubectl(任意节点),我选择 k8s-m01

kubectl 是 kubernetes 集群的命令行管理工具,它默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信息。

5.1 创建 admin 证书和私钥

kubectl 与 apiserver https 安全端口通信,apiserver 对提供的证书进行认证和授权。

kubectl 作为集群的管理工具,需要被授予最高权限。这里创建具有最高权限的 admin 证书。

  • O 为 system:masters,kube-apiserver 收到该证书后将请求的 Group 设置为 system:masters;

  • 预定义的 ClusterRoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予所有 API的权限;

  • 该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;

5.2 创建kubeconfig配置文件

kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书

  • --certificate-authority:验证 kube-apiserver 证书的根证书;

  • --client-certificate--client-key:刚生成的 admin 证书和私钥,连接 kube-apiserver 时使用;

  • --embed-certs=true:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(不加时,写入的是证书文件路径,后续拷贝 kubeconfig 到其它机器时,还需要单独拷贝证书文件,不方便。);

5.3 授予 kubernetes 证书访问 kubelet API 的权限

在执行 kubectl exec、run、logs 等命令时,apiserver 会转发到 kubelet。这里定义 RBAC 规则,授权 apiserver 调用 kubelet API。

5.4 小测试

6. 部署controller-manager(master节点)

controller-manager启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。

6.1 创建证书和私钥

查看证书请求。

  • hosts 列表包含所有 kube-controller-manager 节点 IP;

  • CN 和 O 均为 system:kube-controller-manager,kubernetes 内置的 ClusterRoleBindings system:kube-controller-manager 赋予 kube-controller-manager 工作所需的权限。

6.2 创建controller-manager的kubeconfig

6.3 创建service文件

6.4 启动服务

7. 部署scheduler(master节点)

scheduler启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。

7.1 创建证书和私钥

查看证书请求文件。

  • hosts 列表包含所有 kube-scheduler 节点 IP;

  • CN 和 O 均为 system:kube-scheduler,kubernetes 内置的 ClusterRoleBindings system:kube-scheduler 将赋予 kube-scheduler 工作所需的权限;

7.2 创建scheduler的kubeconfig

7.3 创建service文件

7.4 启动服务

8. 部署kubelet(worker节点)

8.1 创建bootstrap配置文件

  • 向 kubeconfig 写入的是 token,bootstrap 结束后 kube-controller-manager 为 kubelet 创建 client 和 server 证书;

  • token 有效期为 1 天,超期后将不能再被用来 boostrap kubelet,且会被 kube-controller-manager 的 tokencleaner 清理;

  • kube-apiserver 接收 kubelet 的 bootstrap token 后,将请求的 user 设置为 system:bootstrap:<Token ID>,group 设置为 system:bootstrappers,后续将为这个 group 设置 ClusterRoleBinding;

8.2 kubelet配置文件

把kubelet配置文件分发到每个worker节点上

  • authentication.anonymous.enabled:设置为 false,不允许匿名访问 10250 端口;

  • authentication.x509.clientCAFile:指定签名客户端证书的 CA 证书,开启 HTTPs 证书认证;

  • authentication.webhook.enabled=true:开启 HTTPs bearer token 认证;

同时配置了如下授权参数:

  • authroization.mode=Webhook:开启 RBAC 授权;

kubelet 收到请求后,使用 clientCAFile 对证书签名进行认证,或者查询 bearer token 是否有效。如果两者都没通过,则拒绝请求,提示 Unauthorized:

8.3 kubelet服务文件

把kubelet服务文件分发到每个worker节点上

8.4 启动服务

kublet 启动时查找配置的 --kubeletconfig 文件是否存在,如果不存在则使用 --bootstrap-kubeconfig 向 kube-apiserver 发送证书签名请求 (CSR)。 kube-apiserver 收到 CSR 请求后,对其中的 Token 进行认证(事先使用 kubeadm 创建的 token),认证通过后将请求的 user 设置为 system:bootstrap:,group 设置为 system:bootstrappers,这就是Bootstrap Token Auth。

  • kubelet 启动后使用 --bootstrap-kubeconfig 向 kube-apiserver 发送 CSR 请求,当这个 CSR 被 approve 后,kube-controller-manager 为 kubelet 创建 TLS 客户端证书、私钥和 --kubeletconfig 文件。

  • 注意:kube-controller-manager 需要配置 --cluster-signing-cert-file 和 --cluster-signing-key-file 参数,才会为 TLS Bootstrap 创建证书和私钥。

9. 部署kube-proxy(worker节点)

9.1 创建证书和私钥

查看证书请求文件。

  • CN:指定该证书的 User 为 system:kube-proxy

  • 预定义的 RoleBinding system:node-proxier 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;

  • 该证书只会被 kube-proxy 当做 client 证书使用,所以 hosts 字段为空;

9.2 创建和分发 kubeconfig 文件

9.3 分发kube-proxy.config

9.4 分发kube-proxy服务文件

9.5 启动服务

目前是 iptables 模式,使用 ipvs 模式可以修改文件 kube-proxy.config.yaml 我这里遇到的一个问题是 iptables 版本过低,如果遇到,可以编译安装使用新版本。

10. 部署CNI插件 - calico

我们使用calico官方的安装方式来部署。

https://docs.projectcalico.org/v3.10/getting-started/kubernetes/

11. 部署DNS插件 - coredns

https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base

四、集群可用性测试

1. 创建nginx ds

2. 检查各种ip连通性

3. 检查dns可用性

五. 部署dashboard

1. 部署dashboard

2. 访问dashboard

为了集群安全,从 1.7 开始,dashboard 只允许通过 https访问,我们使用nodeport的方式暴露服务,可以使用 https://NodeIP:NodePort 地址访问。

关于自定义证书

默认dashboard的证书是自动生成的,肯定是非安全的证书,如果大家有域名和对应的安全证书可以自己替换掉。使用安全的域名方式访问dashboard。 在dashboard-all.yaml中增加dashboard启动参数,可以指定证书文件,其中证书文件是通过secret注进来的。

--tls-cert-file=dashboard.cer --tls-key-file=dashboard.key

3. 登录dashboard

Dashboard 默认只支持 token 认证,所以如果使用 KubeConfig 文件,需要在该文件中指定 token,我们这里使用token的方式登录

六、部署 metrics-server

metrics-server 通过 kube-apiserver 发现所有节点,然后调用 kubelet APIs(通过 https 接口)获得各节点(Node)和 Pod 的 CPU、Memory 等资源使用情况。

从 Kubernetes 1.12 开始,kubernetes 的安装脚本移除了 Heapster,从 1.13 开始完全移除了对 Heapster 的支持,Heapster 不再被维护。

1. 安装 metrics-server

修改metrics-server-deployment.yaml文件,把 metrics-server 修改为如下命令行参数:

  • --metric-resolution=30s:从 kubelet 采集数据的周期;

  • --kubelet-preferred-address-types:优先使用 InternalIP 来访问 kubelet,这样可以避免节点名称没有 DNS 解析记录时,通过节点名称调用节点 kubelet API 失败的情况(未配置时默认的情况);

2. 部署

参考文档:https://k8s-install.opsnull.com/

Last updated