kubernetes 1.23.6
# 搭建K8S集群
- 服务器要求
- 三台服务器
- k8s-master 192.168.8.128
- k8s-node1 192.168.8.129
- k8s-node2 192.168.8.130
- 最低配置: 2核、2G内存、20G硬盘
- 最好联网,不能联网话需要提供对应镜像私有仓库
- 软件环境
- 操作系统: Centos7
- Docker: 20+
- k8s: 1.23.6 (在这个版本之上不支持Docker)
## 1. 安装步骤一: 初始化操作
```bash
systemctl stop firewalld
systemctl disable firewalld
# 关闭selinux,
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0
# 关闭 swap, 然后重启虚拟机
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
# 根据规划设置主机名
hostnamectl set-hostname <hostname>
# 添加 hosts
cat >> /etc/hosts << EOF
192.168.8.128 k8s-master1
192.168.8.129 k8s-node1
192.168.8.130 k8s-node2
EOF
# 系统调优
cat >> /etc/security/limits.conf << EOF
* soft nofile 655360
* hard nofile 655350
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited
EOF
# 升级内核更新
rpm -import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
yum -y --enablerepo=elrepo-kernel install kernel-ml.x86_64 kernel-ml-devel.x86_64
yum update -y && grub2-set-default 1 && reboot
# 重启后查看内核是否是更新后的内核, uname -a
# 内核模块配置 注意: kernel < 4.19 使用 nf_conntrack_ipv4 并去除ip_vs_fo, kernel > 4.19 使用 nf_conntrack
yum install ipvsadm ipset sysstat conntrack libseccomp -y
cat >> /etc/modules-load.d/ipvs.conf << EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
systemctl enable --now systemd-modules-load.service
# 内核参数调优
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
sysctl --system # 生效
# 时间同步。 写入计划任务比较好
yum install ntpdate -y
ntpdate time.windows.com2. 安装步骤二: 安装基础软件(所有节点)
3. 安装步骤三: 部署 Kubernetes Master
4. 安装步骤四: 加入 Kubernetes Node
5. 安装步骤五:部署 CNI 网络插件
https://docs.tigera.io/archive/ 选择与 kubernetes 对应的版本 https://docs.tigera.io/archive/v3.23/getting-started/kubernetes/quickstart 这里使用: Tigera 操作員來安裝 Calico
效果
calicoctl是用来查看管理calico的命令行工具,定位上有点类似于calico版本的kubectl (可不安装)
参考: https://docs.tigera.io/archive/v3.23/maintenance/clis/calicoctl/install
6. 测试 Kubernetes 集群
7. 命令行工具 kubectl
api-server 只有 master 上可以执行,为了让所有节点都可以与 api-server 通信
K8S的资源清单
必须存在的属性
主要对象
额外参数
version说明
深入Pod
1. 配置文件
2. 探针
StartupProbe 探针
3. 生命周期

资源调度
Lable 和 Selector
Deployment 无状态
创建
滚动更新
由于当前副本数只有一个,我们扩容一下
只有修改 容器部分 containers ,才会滚动更新
回归版本
比如操作失误,导致更新的pod无法启动,那么我们想回滚到上一个版本
扩容缩容
滚动更新的暂停和恢复
常用于增加pod或者服务器的时候
StatefulSet 有状态
创建
由于没有 存储卷,这里就不设置了
扩容和缩容
滚动更新
镜像更新(目前还不支持直接更新image,需要patch来间接实现) 和 deployment 类似
灰布发布/金丝雀发布
目标: 将项目上线后产生问题的影响,尽量降到最低
过程: 先更新一部分,如果正常没有问题了,再逐渐更新
利用滚动更新中的 partition 属性,可以实现简易的灰度发布的效 例如我们有5个pqd.如果当前 partition 设置为3,那么此时滚动更新时,只会更新那些序号 >= 3的pod 利用该机制,我们可以通过控制partition的值,来决定只更新其中一部分pod,确认没有问题后再主健增大更新的pod数量,最终实现全部pod更新
删除更新
只有删除 Pod 的时候才实现更新
级联删除和非级联删除
删除PVC
DaemonSet 守护进程
为每一个匹配的Node都部署-一个守护进程

配置文件
滚动更新
只有删除的时候才更新
HPA
Pod自动扩容: 可以根据CPU使用率或自定义指标(metrics)
●控制管理器每隔30s (可以通过-horizontal-pod-autoscaler-sync-period惨改)查询metrics的资源使用情况
●支持三种metrics类型
。预定义metrics (比如Pod的CPU) 以利用率的方式计算
。自定义的Pod metrics, 以原始值(raw value) 的方式计算
。自定义的object metrics
●支持两种metrics查询方式: Heapster和白定义的REST API
●支持多metrics
HPA 开启指标服务
CPU、内存指标监控
实现cpu或内存的监控,首先有个前提条件是该对象必须配置了 resources.requests.cpu 或** resources.requests.memory** 才可以,
可以配置当cpu/memory达到上述配置的百分比后进行扩容或缩容
创建一个HPA:流程:
1.先准备好一个有做资源限制的deployment、service
2.执行命令
kubectl autoscale deploy <deploy. name> --cpu-percent= 20 --min=2 --max=53.通过
kubectl get hpa可以获取HPA信息
自定义 metrics
●控制管理器开启
-horizontal-pod-autoscaler-use-rest-clients●控制管理器的--apiserver指向
API Server Aggregator●在 API Server Aggregator 中注册自定义的metrics API
服务发布-services


配置与基础命令
Service 访问外部服务
推荐方式(不需要经常改动,管理方便)
比如现有业务无感迁移, 无状态相关应用使用 deploy, 数据库相关的使用 service 代理外部服务,后期数据库迁移过来时,也容易修改,只需要更新 service 即可
实现方式:
1.编写 service 配置文件时,不指定 selector 属性
2.自己创建 endpoint
常用类型
ClusterIP 集群内部使用
ExternalName 返回定义的 CNAME 别名, 可以配置为域名
NodePort
会在所有安装了kube-proxy 的节点都绑定一个端中, 此端口可以代理至对应的Pod,集群外部可以使用任意节点ip +NodePort的端口号访问到集群中对应Pod中的服务,当类型设置为NodePort后,可以在ports配置中增加nodePort配置指定端口,需要在下方的端口范團内,如果不指定会随机指定端口
端口范围: 30000~32767
端口范围配置在/ysteys/systey/kube-episevereservice
LoadBalancer 使用云服务商(阿里云、腾讯云等) 提供的负载均衡器服务
服务发布-Ingress
参考: https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
安装 Ingress
安装 Helm
官网: https://helm.sh/
添加 Helm 仓库
下载安装包
配置参数
创建 Namespace
安装 ingress
路径匹配和虚拟主机配置
多域名配置: rules 下面多复制几分,修改下 域名即可
配置与存储
ConfigMap
ConfigMap 创建
ConfigMap 使用和加载
热更新
ConfigMap 更新后滚动更新 Pod
Secret
Service Account
用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到
Pod的
Opaque
map类型,要求value是base64编码格式:
kubernetes.io/dockerconfigjson
持久化存储
Volumes-HostPath
将节点上的文件或目录挂载到Pod上,此时该目录会变成持久化存储目录,即使Pod被删除后重启,也可以重新加载到该目录,该目录下的文件不会丢失
空字符串(默认) 默认类型,不做任何检查
DirectoryOrCreate 如果在给定的路径上不存在,则创建一个空目录,权限 0755
Directory 目录,必须存在。
FileOrCreate 如果在给定的路径上不存在,则创建一个空文件,权限设 0644
File 必须存在文件。
Socket UNIX 套接字,必须存在 。
CharDevice 字符设备,必须存在
BlockDevice 块设备,必须存在
Volumes-EmptyDir
EmptyDir主要用于一个Pod中不同的Container共享数据使用的,由于只是在Pod内部使用,因此与其他volume比较大的区别是,当Pod如果被删除了,那么emptyDir也会被删除。
存储介质可以是任意类型,如SSD、磁盘或网络存储。可以将 emptyDir.medkam 设置为Memory让k8s使用tmpfs (内存支持文件系统),速度比较快,但是重启tmpfs节点时,数据会被清除,且设置的大小会计入到Container的内存限制中。
NFS 挂载
安装 NFS
如何使用
创建两个测试的 pod, 测试 nfs 挂载目录文件
动态 StorageClass
参考: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
PV与PVC
生命周期
构建
1.1 静态构建
集群管理员创建若干PV卷。这些卷对象带有真实存储的细节信息,并且对集群用户可用(可见)。卷对象存在于Kubernetes API中,可供用户消费(使用)
1.2 动态构建
如果集群中已经有的PV无法满足PVC的需求,那么集群会根据PVC自动构建-个PV,该操作是通过StorageClass实现的。
想要实现这个操作,前提是PVC必须设置StorageClass,否则会无法动态构建该PV,可以通过启用DefaultStorageClass来实现PV的构建。
绑定
当用户创建一个PVC对象后,主节点会监测新的PVC对象,并且寻找与之匹配的PV卷,找到PV卷后将二者绑定在一起。
如果找不到对应的PV,则需要看PVC是否设置StorageClass来决定是否动态创建PV,若没有配置,PVC 就会致处于未绑定状态,直到有与之匹配的bV后才会申领绑定关系。
使用
Pod将PVC当作存储卷来使用,集群会通过PVC找到绑定的PV,并为Pod挂载该卷。Pod - -旦使用PVC绑定PV后,为了保护数据,避免数据丢失问题,PV 对象会受到保护,在系统中无法被删除。
回收策略
当用户不再使用其存储卷时,他们可以从API中将PVC对象删除,从而允许该资源被回收再利用。 PersistentVolume 对象的回收策略告诉集群,当其被从申领中释放时如何处理该数据卷。 目前,數据卷可以被
Retained(保留)、Recycred(回收)或Deleted(删除)。
Retained(保留)
回收策略Retain 使得用户可以手动回收资源。当PersistentVolumeClaim对象被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为“已释放(released) ”.由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他用领。管理员可以通过下面的步骤来手动回收该卷:
Deleted删除
对于支持Delete回收策略的卷插件,删除动作会将PersistentVolume对象以Kubernetes中移除,同时也会从外部基础设施(如 AWS EBS、GCE PD、Azure Disk或Cinder卷)中移除所关联的存储资产。动态制备的卷 会继承其StorageClass中设置的回收策略,该策略默认为 Delete.管理员需要根据用户的期望来配置StorageClass;否则PV卷被创建之后必须要被编辑或者修补。
Recycred回收
警告:回收策略Recycle已被废弃。取而代之的建议方案是使用动态制备。 如果下层的卷播件支持,回收策鰭Recycle会在卷上执行-些基本的擦除(rm -rf /thevolume/")操作,之后允许该卷用于新的PVC申领。
PV
状态
Available: 空闲,未被绑定
Bound: 已经被 PVC 绑定
Released: PVC 被删除,资源已回收,但是 PV 未被重新使用
Failed: 自动回收失败
配置文件
PVC
测试PV与PVC
StorageClass动态
制备器
NFS 动态支部案例
nfs-provisioner
StorageClass配置
RBAC配置
PVC处于Pending状态
PVC测试配置
高级调度
CronJob 计划任务
在k8s中周期性运行计划任价与linux中的crontab相同 注意点: CronJob 执行的时间是controller-manager的时间,所以定要确保contrller-manager时间是准确的,另外cronjob
配置文件
应该是: successfulJobsHistoryLimit
初始化容器
污点和容忍
污点
NoSchedule: 节点污点,无法被调度到此,已存在pod不受影响
NoExecute: 驱逐Pod,调用到其他节点
容忍
Equal: 容忍和污点对比, key、value 必须相同才可以调度
Exists: 容忍和污点只对比 key,key存在则容忍
3。 污点驱逐类型
node.kubernetes.io/not-ready:节点未准备好。这相当于节点状况 Ready 的值为 "False"。
node.kubernetes.io/unreachable:节点控制器访问不到节点. 这相当于节点状况 Ready 的值为 "Unknown"。
node.kubernetes.io/memory-pressure:节点存在内存压力。
node.kubernetes.io/disk-pressure:节点存在磁盘压力。
node.kubernetes.io/pid-pressure: 节点的 PID 压力。
node.kubernetes.io/network-unavailable:节点网络不可用。
node.kubernetes.io/unschedulable: 节点不可调度。
node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个“外部”云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在 cloud-controller-manager 的一个控制器初始化这个节点后,kubelet 将删除这个污点。
污点:是标注在节点上的,当我们在一个节点 上打上污点以后,k8s会认为尽量不要将pod调度到该节点上,除非该pod上面表示可以容忍该污点,且-个节点可以打多个污点,此时则需要pod容忍所有污点才会被调度该节点。
场景一
场景二
场景三
亲和力和反亲和力
详情查看官网: https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/
Node 亲和性 || Pod 亲和性
requiredDuringSchedulingIgnoredDuringExecution 硬亲和性, 规则被满足的时候才能执行调度
preferredDuringSchedulingIgnoredDuringExecution 软(反)亲和性,如果没有匹配规则节点,则可以继续调度
例如: 混合云机房
身份认证与权限
认证
User Account 普通账户
Service Accounts 服务账户
Service Account Adminision Controller
Token Controller
Service Account Controller
授权
Role (命名空间级别)
代表一个角色,会包含-组权限, 没有拒绝规则,只是附加允许。它是Namespace级别的资源,只能作用与Namespace之内。
ClusterRole (集群空间级别)
RoleBinding
ClusterRoleBinding
Helm 包管理器
管理 chart、config、release
安装
参考安装: ingress-nginx 部分
Helm 常用命令
Helm 目录结构
Helm 实践 Redis chart
需要动态storageclasses: (managed-nfs-storage)名字
3主3从
修改 helm 源
搜索 redis chart
传变量在线安装
已经设置了 nfs 为默认存储, 那这里就不需要 存储参数了
修改配置安装
查看安装情况
连接
Redis 集群验证服务
提供服务给外部
升级与回滚
helm 卸载 redis
Helm 实践 kube-prometheus-stack
动态存储: 如何创建, 查看 动态NFS StorageClass 步骤
方法一: Helm 方式安装(推荐)
参考: kube-prometheus-stack安装及使用 - 墨天轮 (modb.pro) 参考: 一文搞懂基于 Helm 部署 Prometheus Stack 全家桶 - Luga Lee - twt企业IT交流平台 (talkwithtrend.com) 参考: prometheus-operator/kube-prometheus: Use Prometheus to monitor Kubernetes and applications running on Kubernetes (github.com)
修改values.yaml,将storageClassName值替换为创建的managed-nfs-storage
存在则更新
检查
使用 Ingress 提供服务
方法二: Yaml 方式安装
Helm 实战 RadonDB MySQL Operator 集群
官网: https://radondb.com/ 备份: 查看官网
** 访问集群**
在 Kubernetes 集群内,支持使用 service_name 或者 clusterIP 方式,访问 RadonDB MySQL。 RadonDB MySQL 提供 Leader 和 Follower 两种服务,分别用于客户端访问主从节点。Leader 服务始终指向主节点(可读写),Follower 服务始终指向从节点(只读)。
卸载
k8s 删除 ns、pod 卡住的解决办法
在某些情况下,在k8s中会无法删除某个namespace,它会一直卡在terminating状态下。解决这个问题的步骤为:
但是大部分时候,这些资源也杀不掉,解决办法是执行
然后找到里面的"finalizers",把它的值设置成一个空数组。
解决这些资源后,参照以下文档删除那个ns:
Last updated