使用 Kubespray 定制化部署 Kubernetes 集群

介绍

K8S现在已然成为了云原生的核心标准,整个生态的发展速度非常快,庞大的架构和不断滚动加入的功能也让部署的成本愈来愈大。
官方也提供了自带的kubeadm通过Static Pods的方式来加快部署,成为了大部分团队的首选。但是,kubeadm的扩展能力有限,并且只能在pre-flight阶段对OS做基线巡检,不能实施基线,而且只能够部署控制层,后续的HA、CNI、LB等都需要注入manifests方案来完成。另外,如果需要深度定制部署编排,需要研究kubeadm和Kind的源码,二开的难度也比较高。

这里介绍一个K8S部署的Ansible方案Kubespray
Kubespray是K8S官方推荐的一种集群部署方式,支持生产环境的集群维护,通过Ansible来管理部署动作,提供了多种参数来满足定制化的需求。从v2.3开始,部署的K8S的控制组件,底层使用同为K8S官方推荐的部署方案kubeadm来落地。
即便是底层使用了kubeadm,但是Kubespray通过大量的Ansible剧本进行封装管控,非常友好的支持自定义部署的需求,支持自动部署CNI、Add-On、APP等。在kubespray/docs目录里,有一些不同基线要求的部署说明,在定制化集群时,可以在这里参考到不同的部署实践。

部署

基线配置

Kubespray支持丰富的K8S部署模式,这里介绍几个不同的部署模式,来说明如何使用Kubespray实现定制化的部署。
这里使用的Kubespray版本为v2.23.0,仓库地址为https://github.com/kubernetes-sigs/kubespray

可以通过如下方式下载:

# 下载仓库
git clone -b v2.23.0 --depth 1 https://github.com/kubernetes-sigs/kubespray.git
# 安装虚拟环境和依赖
cd kubespray
virtualenv ./venv
source ./venv/bin/activate
python -m pip install -r requirements.txt
# 拷贝资产样例,名称为 cls
cp -rfp inventory/sample inventory/cls

在部署各类模式之前,先统一下全局基线。

# ########## 安全基线
# 关闭 RHEL 下的 SELinux
echo 'preinstall_selinux_state: disabled' >> inventory/cls/group_vars/all/all.yml
# 限制集群部署用户
sed -i 's#kube_owner:s*.*$#kube_owner: root#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# 限制证书用户组
sed -i 's#kube_cert_group:s*.*$#kube_cert_group: root#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml

# ########## etcd 基线
# 暴露指标采集端口
echo 'etcd_metrics_port: 2381' >> inventory/cls/group_vars/all/etcd.yml

# ########## k8s baseline
# 设置集群名称
sed -i 's#cluster_name:s*.*$#cluster_name: cluster.cls#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# 关闭 NodeLocal DNSCache
sed -i 's#enable_nodelocaldns:s*.*$#enable_nodelocaldns: false#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# SVC 的地址段设置为 172.255.0.0/16
sed -i 's#kube_service_addresses:s*.*$#kube_service_addresses: 172.255.0.0/16#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# POD 的地址段设置为 172.0.0.0/16
# 注意,如果需要将 POD 地址对外路由,这里要同步配置 SDN。
sed -i 's#kube_pods_subnet:s*.*$#kube_pods_subnet: 172.0.0.0/16#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml

如果因为网络问题,需要走代理,可以配置以下参数:

http_proxy: "http://192.168.1.1:1099"
https_proxy: "http://192.168.1.1:1099"
no_proxy: "192.168.1.0/24"

注意:部署阶段,会把生成的证书加密的对称密钥下载到inventory/cls/credentials/kubeadm_certificate_key.creds,虽然Kubespray的.gitignore已经将非官方的Inventory过滤了,但是也要注意不要将这类敏感文件推送到公共仓库。

最小集群精简模式

介绍
开发测试阶段,需要部署一个最小资源的单节点master与worker,不使用额外的LB接入,来满足测试场景的使用。

架构规划

Control Plane: Kubernetes v1.27.5
CRI: containerd
etcd deploy: kubeadm
CNI: flannel (vxlan mode)

架构图

使用 Kubespray 定制化部署 Kubernetes 集群

实施
为了满足部署要求,进行配置修改。

# 修改 K8S 版本
sed -i 's#kube_version:s*.*$#kube_version: v1.27.5#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# CRI 选择 containerd
sed -i 's#container_manager:s*.*$#container_manager: containerd#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# 修改 etcd 部署模式为 kubeadm
sed -i 's#etcd_deployment_type:s*.*$#etcd_deployment_type: kubeadm#g' inventory/cls/group_vars/all/etcd.yml
# 修改 CNI 为 flannel
sed -i 's#kube_network_plugin:s*.*$#kube_network_plugin: flannel#g' inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# 限定 CNI 绑定的网卡
# 注意双引号和单引号在 yaml 的转义方式区别
echo "flannel_interface_regexp: '192\\.168\\.\\d{1,3}\\.\\d{1,3}'" >> inventory/cls/group_vars/k8s_cluster/k8s-net-flannel.yml

配置 Ansible Inventory:

# inventory/cls/inventory.ini
# 所有的主机清单
# ansible_host 是 Ansible SSH 连接的目标地址
# 如果服务器有多 ip 地址,需要指定 ip 变量来限制绑定的地址范围
[all]
node1   ansible_host=192.168.1.11 ip=192.168.1.11

# 部署单个实例的 etcd 集群
[etcd]
node1

[k8s_cluster:children]

kube_control_plane
kube_node

# 控制面
[kube_control_plane]
node1

# 工作节点也是同一个
[kube_node]
node1

开始执行部署:

ansible-playbook -i inventory/cls/inventory.ini 
-b cluster.yml 
--diff

注意:虽然Kubespray在Check ansible version阶段会检查Ansible版本,但是在某些Ansible版本里,get_url302跳转的处理存在问题,像etcd的github release下载地址需要多次跳转,会导致5次重试失败而退出部署,可以升级到最新的Ansible版本,或者手动为get_url开启force: true参数。

部署完成后,集群状态如下:

使用 Kubespray 定制化部署 Kubernetes 集群

节点增减模式

worker节点的增减是管理K8S集群的高频操作,下面介绍在精简模式的环境下,如何上线和下线一个worker节点。

上线节点

更新Inventory清单,增加一个节点。

[all]
node1   ansible_host=192.168.1.11 ip=192.168.1.11
node2   ansible_host=192.168.1.12 ip=192.168.1.12

[etcd]

node1

[k8s_cluster:children]

kube_control_plane
kube_node

[kube_control_plane]

node1

[kube_node]

node1
node2

针对新增节点执行扩容剧本:

ansible-playbook -i inventory/cls/inventory.ini 
--limit=node2 
-b scale.yml 
--diff

扩容完成后,架构现状如下:

使用 Kubespray 定制化部署 Kubernetes 集群

查看集群信息:

使用 Kubespray 定制化部署 Kubernetes 集群

下线节点

将上线的节点重新下线,只要执行如下剧本:

ansible-playbook 
-i inventory/cls/inventory.ini 
--limit=node2 
-e 'node=node2' 
-b remove-node.yml 
--diff

过程中会有一次pause来提示确认下线,输入yes继续执行。

集群高可用模式

介绍
生产环境里,K8S 作为最基础的应用基础架构,自身的高可用是不能忽视的,这里也简单介绍下如何使用 Kubespray 来部署一个高可用的 K8S 集群。

架构规划

Control Plane: Kubernetes v1.27.5
Control LB: kube-vip
CRI: containerd
etcd deploy: cluster (on host)
CNI: calico (ipip mode)

架构图

使用 Kubespray 定制化部署 Kubernetes 集群

实施
这里是使用Kubespray内部的组件来完成,如果有外部的LB,最好使用外部的高可用LB,如果有外部etcd集群,也最好使用外部的高性能etcd。
为了满足部署要求,进行配置修改。

# inventory/cls/group_vars/k8s_cluster/k8s-cluster.yml
# 激活 kube-vip
kube_vip_enabled: true
kube_vip_controlplane_enabled: true
# 分配的 VIP
kube_vip_address: 192.168.1.100
loadbalancer_apiserver:
  address: "{{ kube_vip_address }}"
  port: 6443
kube_vip_interface: enp0s8
# 这里只考虑控制面 LB,禁用 SVC 的 LB
kube_vip_services_enabled: false
# 开启 arp
kube_proxy_strict_arp: true
kube_vip_arp_enabled: true
# 设置 CNI 为 calico
kube_network_plugin: calico
# 开启未 GA 的特性
# https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
kube_apiserver_feature_gates: [ 'EphemeralContainers=true' ]
kube_controller_feature_gates: [ 'RotateKubeletServerCertificate=true', 'EphemeralContainers=true' ]
kube_scheduler_feature_gates: [ 'EphemeralContainers=true' ]
kube_proxy_feature_gates: []
kubelet_feature_gates: [ 'EphemeralContainers=true' ]
kubeadm_feature_gates: []

# inventory/cls/group_vars/k8s_cluster/k8s-net-calico.yml
# calico 开启 IPIP 隧道
calico_ipip_mode: Always
calico_vxlan_mode: Never
# IPIP 需要开启 BGP 路由广播
calico_network_backend: bird

# inventory/cls/group_vars/etcd.yml
# 开启 etcd 全量监控
etcd_metrics: extensive
# 主机模式部署 etcd 集群
etcd_deployment_type: host

配置Ansible Inventory:

[all]
node1   ansible_host=192.168.1.11 ip=192.168.1.11
node2   ansible_host=192.168.1.12 ip=192.168.1.12
node3   ansible_host=192.168.1.13 ip=192.168.1.13
node4   ansible_host=192.168.1.14 ip=192.168.1.14

[etcd]

node1
node2
node3

[k8s_cluster:children]

kube_control_plane
kube_node

[kube_control_plane]

node1
node2
node3

[kube_node]

node4

开始执行部署:

ansible-playbook 
-i inventory/cls/inventory.ini 
-b cluster.yml 
--diff

总结

在K8S生态发展状态,或者说是一家独大之后,自动化部署的项目如雨后春笋般蓬勃发展,让人眼花缭乱。每一种方案都有其适配性,选择最满足当前需求的,才是最应该考虑的。这里的Kubespray也许是一个不错的选择,能够结合学习成本不高的Ansible来扩展,但缺点就是剧本的生命周期太复杂,也使得整个发布时长比kubeadm要长的多,利弊相衡,也按需选择吧。


原文始发于微信公众号(AcidPool):使用 Kubespray 定制化部署 Kubernetes 集群

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/171033.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!