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.com

2. 安装步骤二: 安装基础软件(所有节点)

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=5

      • 3.通过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

  1. 安装 Helm

    • 官网: https://helm.sh/

  1. 添加 Helm 仓库

  1. 下载安装包

  1. 配置参数

  1. 创建 Namespace

  1. 安装 ingress

路径匹配和虚拟主机配置

  • 多域名配置: rules 下面多复制几分,修改下 域名即可

配置与存储

ConfigMap

  1. ConfigMap 创建

  1. ConfigMap 使用和加载

  1. 热更新

ConfigMap 更新后滚动更新 Pod

Secret

  • Service Account

    • 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod

  • Opaque

    • map 类型,要求 valuebase64 编码格式:

  • 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.1 静态构建

      • 集群管理员创建若干PV卷。这些卷对象带有真实存储的细节信息,并且对集群用户可用(可见)。卷对象存在于Kubernetes API中,可供用户消费(使用)

    • 1.2 动态构建

      • 如果集群中已经有的PV无法满足PVC的需求,那么集群会根据PVC自动构建-个PV,该操作是通过StorageClass实现的。

      • 想要实现这个操作,前提是PVC必须设置StorageClass,否则会无法动态构建该PV,可以通过启用DefaultStorageClass来实现PV的构建。

  2. 绑定

    • 当用户创建一个PVC对象后,主节点会监测新的PVC对象,并且寻找与之匹配的PV卷,找到PV卷后将二者绑定在一起。

    • 如果找不到对应的PV,则需要看PVC是否设置StorageClass来决定是否动态创建PV,若没有配置,PVC 就会致处于未绑定状态,直到有与之匹配的bV后才会申领绑定关系。

  3. 使用

Pod将PVC当作存储卷来使用,集群会通过PVC找到绑定的PV,并为Pod挂载该卷。Pod - -旦使用PVC绑定PV后,为了保护数据,避免数据丢失问题,PV 对象会受到保护,在系统中无法被删除。

  1. 回收策略

当用户不再使用其存储卷时,他们可以从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

初始化容器

污点和容忍

  1. 污点

  • NoSchedule: 节点污点,无法被调度到此,已存在pod不受影响

  • NoExecute: 驱逐Pod,调用到其他节点

  1. 容忍

  • 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 软(反)亲和性,如果没有匹配规则节点,则可以继续调度

例如: 混合云机房

身份认证与权限

  1. 认证

    • User Account 普通账户

    • Service Accounts 服务账户

      • Service Account Adminision Controller

      • Token Controller

      • Service Account Controller

  2. 授权

    • Role (命名空间级别)

      • 代表一个角色,会包含-组权限, 没有拒绝规则,只是附加允许。它是Namespace级别的资源,只能作用与Namespace之内。

    • ClusterRole (集群空间级别)

    • RoleBinding

    • ClusterRoleBinding

Helm 包管理器

管理 chart、config、release

安装

参考安装: ingress-nginx 部分

Helm 常用命令

Helm 目录结构

Helm 实践 Redis chart

  • 需要动态storageclasses: (managed-nfs-storage)名字

  • 3主3从

  1. 修改 helm 源

  1. 搜索 redis chart

  1. 传变量在线安装

已经设置了 nfs 为默认存储, 那这里就不需要 存储参数了

  1. 修改配置安装

  1. 查看安装情况

  1. 连接 Redis 集群 验证服务

  1. 提供服务给外部

  1. 升级与回滚

  1. helm 卸载 redis

Helm 实践 kube-prometheus-stack

  • 动态存储: 如何创建, 查看 动态NFS StorageClass 步骤

  • 方法一: Helm 方式安装(推荐)

参考: kube-prometheus-stack安装及使用 - 墨天轮 (modb.pro)arrow-up-right 参考: 一文搞懂基于 Helm 部署 Prometheus Stack 全家桶 - Luga Lee - twt企业IT交流平台 (talkwithtrend.com)arrow-up-right 参考: prometheus-operator/kube-prometheus: Use Prometheus to monitor Kubernetes and applications running on Kubernetes (github.com)arrow-up-right

修改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