介绍
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)
架构图
实施
为了满足部署要求,进行配置修改。
# 修改 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_url
对302
跳转的处理存在问题,像etcd的github release下载地址需要多次跳转,会导致5次重试失败而退出部署,可以升级到最新的Ansible版本,或者手动为get_url
开启force: true
参数。
部署完成后,集群状态如下:
节点增减模式
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
扩容完成后,架构现状如下:
查看集群信息:
下线节点
将上线的节点重新下线,只要执行如下剧本:
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内部的组件来完成,如果有外部的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