Kubernetes(k8s)入门与进阶实战
2026/5/7 8:07:16 网站建设 项目流程

k8s核心概念

什么是k8s

Kubernetes是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S。

K8S是Google内部一个叫Borg的容器集群管理系统衍生出来的,Borg已经在Google大规模生产运行十年之久。

K8S主要用于自动化部署、扩展和管理容器应用,提供了资源调度、部署管理、服务发现、扩容缩容、监控等一整套功能。2015年7月,Kubernetes v1.0正式发布,截止到2021年3月9日最新稳定版本是v1.20。

有了docker为什么还要用k8s

回答这个问题,得从为什么需要引入Docker这个问题先开始。你会说,因为需要容器化部署。那为什么需要容器化部署呢?就这个问题还可以走得更远一点。这里我就偷懒了,先打住。看看容器化部署后出现的新问题,即容器实例越来越多。因为容器实例越来越多,就像鸡蛋太多需要一个篮子来装一样,Kubernetes就是那个篮子。

容器技术是Kubernetes平台的基础。容器技术主要作用是隔离,通过对系统的关键资源的隔离,实现了主机抽象。Kubernetes平台则是在抽象主机的基础上,实现了集群抽象。

如果用一句话做个总结,就是:容器,提供应用级的主机抽象;Kubernetes,提供应用级的集群抽象。

k8s组件介绍

Master组件

Master组件是集群的控制平台(control plane),负责集群中的全局决策(例如,调度)可以运行于集群中的任何机器上。但是,为了简洁性,通常在同一台机器上运行所有的 master 组件,且不在此机器上运行用户的容器。

kube-apiserver

提供 Kubernetes API。这是Kubernetes控制平台的前端(front-end),可以水平扩展(通过部署更多的实例以达到性能要求)。kubectl / kubernetes dashboard / kuboard 等Kubernetes管理工具就是通过 kubernetes API 实现对 Kubernetes 集群的管理。

etcd

支持一致性和高可用的名值对存储组件,Kubernetes集群的所有配置信息都存储在 etcd 中。

kube-scheduler

监控所有新创建尚未分配到节点上的 Pod,并且自动选择为 Pod 选择一个合适的节点去运行。

影响调度的因素有:

  • 单个或多个 Pod 的资源需求
  • 硬件、软件、策略的限制
  • 亲和与反亲和(affinity and anti-affinity)的约定
  • 数据本地化要求
  • 工作负载间的相互作用
kube-controller-manager

运行了所有的控制器,逻辑上来说,每一个控制器是一个独立的进程,但是为了降低复杂度,这些控制器都被合并运行在一个进程里。

kube-controller-manager 中包含的控制器有:

  • 节点控制器: 负责监听节点停机的事件并作出对应响应
  • 副本控制器: 负责为集群中每一个 副本控制器对象(Replication Controller Object)维护期望的 Pod 副本数
  • 端点(Endpoints)控制器:负责为端点对象(Endpoints Object,连接 Service 和 Pod)赋值
  • Service Account & Token控制器: 负责为新的名称空间创建 default Service Account 以及 API Access Token

Node 组件

Node 组件运行在每一个节点上(包括 master 节点和 worker 节点),负责维护运行中的 Pod 并提供 Kubernetes 运行时环境。

kubelet

运行在每一个集群节点上的代理程序。它确保 Pod 中的容器处于运行状态。Kubelet 通过多种途径获得 PodSpec 定义,并确保 PodSpec 定义中所描述的容器处于运行和健康的状态。Kubelet不管理不是通过 Kubernetes 创建的容器。

kube-proxy

一个网络代理程序,运行在集群中的每一个节点上,是实现 Kubernetes Service 概念的重要部分。

kube-proxy 在节点上维护网络规则。这些网络规则使得您可以在集群内、集群外正确地与 Pod 进行网络通信。

容器引擎

容器引擎负责运行容器。Kubernetes支持多种容器引擎:Docker (opens new window)、containerd (opens new window)、cri-o (opens new window)、rktlet (opens new window)以及任何实现了 Kubernetes容器引擎接口 (opens new window)的容器引擎

centos 部署k8s

k8s的三种部署方式

Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,尝试Kubernetes或日常开发的用户使用。不能用于生产环境。

kubeadm可帮助你快速部署一套kubernetes集群。kubeadm设计目的为新用户开始尝试kubernetes提供一种简单的方法。

从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。目前企业生产环境中主要使用该方式。

使用kubeadm部署方式较为简单,且官方已经开始推荐使用,下面我们以它作为示范。

部署环境

操作系统:

CentOS 7

集群节点之间可以通信,关闭防火墙

每个节点唯一主机名,MAC地址和product_uuid

检查MAC地址:使用ip link或者ifconfig -a

检查product_uuid:cat /sys/class/dmi/id/product_uuid

禁止swap分区。这样才能使kubelet正常工作

角色

IP

组件

k8s-master

192.168.85.128

etcd

kube-apiserver

kube-controller-manager

kube-scheduler

k8s-node1

192.168.85.129

kubelet

kube-proxy

docker

k8s-node2

192.168.85.130

kubelet

kube-proxy

docker

部署流程(默认在集群上所有节点配置)

host配置
cat >>/etc/hosts<<EOF 192.168.85.128 k8s-master 192.168.85.129 k8s-node1 192.168.85.130 k8s-node2 EOF
设置主机名
hostnamectl set-hostname k8s-master hostnamectl set-hostname k8s-node1 hostnamectl set-hostname k8s-node2
时间同步
# 重启ntp systemctl restart chronyd.service && systemctl enable chronyd.service # 查看状态 timedatectl status
关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
关闭selinux
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0
禁用swap分区
swapoff -a && sysctl -w vm.swappiness=0 # 要永久禁掉swap分区,打开/etc/fstab文件注释掉swap那一行 sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
网络模块和内核参数优化
# 确保网络模块开机自动加载 cat > /etc/modules-load.d/docker.conf <<EOF overlay br_netfilter EOF # 查看 modprobe overlay && modprobe br_netfilter && lsmod | grep -Ei 'overlay| br_netfilter' # 设置允许路由转发,不对bridge的数据进行处理 cat >/etc/sysctl.d/k8s.conf<<EOF net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 net.ipv6.conf.all.forwarding = 1 EOF # 生效配置文件 sysctl --system # 查看是否生成相关文件 ls /proc/sys/net/bridge # 配置资源限制文件 cat >> /etc/security/limits.conf <<EOF * soft nofile 65536 * hard nofile 65536 * soft nproc 65536 * hard nproc 65536 * soft memlock unlimited * hard memlock unlimited EOF
docker部署与调优
# 安装基础软件和docker yum install -y yum-utils device-mapper-persistent-data lvm2 vim wget net-tools yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 列出可安装的版本 yum list docker-ce.x86_64 --showduplicates | sort -r # k8s 官方建议安装19.03版本 yum install docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.io # 修改 cgroup 驱动为systemd [k8s官方推荐]、限制容器日志量、修改存储类型,最后的 docker家目录 mkdir /etc/docker cat > /etc/docker/daemon.json <<EOF { "registry-mirrors": ["https://dx5z2hy7.mirror.aliyuncs.com"], //镜像加速地址 "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "graph":"/mnt/docker", //容器安装位置,以实际为准 "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF # 自启和启动 systemctl enable docker && systemctl start docker
k8s组件安装
# 配置阿里云k8s源,安装k8s cat >/etc/yum.repos.d/kubernetes.repo<<EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 EOF # 安装1.20.0版本,不要默认安装最新版本(阿里云镜像仓没有镜像),node 节点无需安装kubectl yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0 # 自启和启动 systemctl enable kubelet && systemctl start kubelet
在master上执行
# 在master上生成配置文件 kubeadm config print init-defaults > kubeadm.yaml 修改kubeadm.yaml文件中 advertiseAddress: 192.168.85.128(为API Server的地址) 修改mageRepository: registry.aliyuncs.com/google_containers(为阿里云镜像仓库) 在serviceSubnet之后增加podSubnet: 10.244.0.0/16(Pod网络) # master初始化安装,此时会打印安装组件信息,等到安装完成。 kubeadm init --config kubeadm.yaml # 按提示配置master,复制kubeadm join 字符串到node节点执行加入操作。 # 查看组件状态 kubectl get cs

查看组件状态(若是有组件是unhealthy,出现这种情况,是1.18.6版本以上/etc/kubernetes/manifests下的kube-controller-manager.yaml和kube-scheduler.yaml设置的默认端口是0,在文件中注释掉就可以了)

CNI网络插件

CNI意为容器网络接口,它是一种标准的设计,为了让用户在容器创建或销毁时都能够更容易地配置容器网络。目前最流行的CNI插件:Flannel、Calico、Weave和Canal(技术上是多个插件的组合)。这些插件既可以确保满足k8s的网络要求,又能为集群管理员提供他们所需的某些特定的网络功能。一般常用Flannel,我们就重点介绍下他。

Flannel

由CoreOS开发的项目Flannel,可能是最直接和最受欢迎的CNI插件。它是容器编排系统中最成熟的网络结构示例之一,旨在实现更好的容器间和主机间网络。随着CNI概念的兴起,Flannel CNI插件算是早期的入门。

与其他方案相比,Flannel相对容易安装和配置。它被打包为单个二进制文件flanneld,许多常见的Kubernetes集群部署工具和许多Kubernetes发行版都可以默认安装Flannel。Flannel可以使用Kubernetes集群的现有etcd集群来使用API存储其状态信息,因此不需要专用的数据存储。

Flannel配置第3层IPv4 overlay网络。它会创建一个大型内部网络,跨越集群中每个节点。在此overlay网络中,每个节点都有一个子网,用于在内部分配IP地址。在配置pod时,每个节点上的Docker桥接口都会为每个新容器分配一个地址。同一主机中的Pod可以使用Docker桥接进行通信,而不同主机上的pod会使用flanneld将其流量封装在UDP数据包中,以便路由到适当的目标。

Flannel有几种不同类型的后端可用于封装和路由。默认和推荐的方法是使用VXLAN,因为VXLAN性能更良好并且需要的手动干预更少。

总的来说,Flannel是大多数用户的不错选择。从管理角度来看,它提供了一个简单的网络模型,用户只需要一些基础知识,就可以设置适合大多数用例的环境。一般来说,在初期使用Flannel是一个稳妥安全的选择,直到你开始需要一些它无法提供的东西。

# 部署flane网络插件 kubectl apply -f "https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
集群查看
# 查看所有空间的pod kubectl get pods --all-namespaces 部分pod处于Pending状态,需要等待网络插件的Pod状态变成Running之后其他pod也会正常。 # 查看node节点状态 kubectl get nodes 所有Pod的状态都变成Running之后,这个时候再次node状态,所有节点都处于Ready状态。

至此k8s集群部署完成

测试nginx部署

简单易用部署可通过命令来完成,比如部署一个nginx测试服务

# 命令创建pod kubectl create deployment nginx --image=nginx:alpine

为应用增加一个service

# 发布pod,为Nginx增加Service,会创建一个Cluster IP,从Master初始化的--service-cidr=10.1.0.0/16地址段中进行分配,并开启NodePort是在Node节点上进行端口映射,进行外部访问。 kubectl expose deployment nginx --port=80 --type=NodePort

查看svc

[root@k8s-master ~]# kubectl get svc |grep nginx nginx NodePort 10.97.95.163 <none> 80:32391/TCP 28s

应用弹性扩容

# 现在将Nginx应用的Pod副本数量拓展到2个节点 kubectl scale deployment nginx --replicas=2

集群内测试访问:curl http://10.97.95.163

集群外测试访问:http://192.168.85.128:32391/

应用暴露方式

通过pod

hostPort相当于docker run -p 8081:8080,不用创建svc,因此端口只在容器运行的vm上监听 hostNetwork相当于 docker run --net=host ,不用创建svc,因此端口只在容器运行的vm上监听 Port Forward通过kubectl port-forward 命令为 Pod 设置端口转发,通过在本机指定监听端口,访问这些端口的请求将会被转发到 Pod 的容器中对应的端口上。

通过service

Service 目前有三种类型:ClusterIP、NodePort 和 LoadBalancer。 ClusterIP 是 Service 的缺省类型,这种类型的服务会自动分配一个只能在集群内部可以访问的虚拟 IP,即:ClusterIP。ClusterIP 为你提供一个集群内部其它应用程序可以访问的服务,外部无法访问。 NodePort-svc级别,由kube-proxy操控,,nodeport会监听在所有的节点上(如果不指定,即是随机端口,由apiserver指定--service-node-port-range '30000-32767'),即使有1个pod,任意访问某台的nodeport都可以访问到这个服务 LoadBalancer 是基于 NodePort 和云服务供应商提供的外部负载均衡器,通过这个外部负载均衡器将外部请求转发到各个 NodeIP:NodePort 以实现对外暴露服务。 LoadBalancer 只能在 Service 上定义。externalIPs 通过svc创建,在指定的node上监听端口,适用想通过svc来负载,但要求某台指定的node上监听,而非像nodeport所有节点监听.

常用方式为NodePort,LoadBalancer,ingress为外部应用反向代理方式,重点讲ingress:

helm repo add apphub https://apphub.aliyuncs.com #阿里云chart 库,速度最快 helm repo update helm search repo ingress helm pull apphub/nginx-ingress # 配置value.yaml,在244行,配置集群的内网ip(配置那个ingress就从那个访问),这里全部配上 externalIPs: [192.168.85.128, 192.168.85.129, 192.168.85.130] helm install nginx-ingress ./nginx-ingress # 查看svc信息 [root@k8s-master ~]# kubectl get svc |grep ingress nginx-ingress-controller LoadBalancer 10.106.168.205 192.168.85.128,192.168.85.129,192.168.85.130 80:31042/TCP,443:32408/TCP 21h nginx-ingress-default-backend ClusterIP 10.101.171.37 <none> 80/TCP 21h # 访问测试, 指定任意node的ip+外部映射端口如(http://192.168.85.128:32408),会默认访问到backend并返回404

持久化存储

名次解释

Persistent Volume Claims( PVC):应用 Pod 从集群请求存储资源的对象,可以理解为应用 Pod 可以访问和使用多少存储空间的凭证。 通过 PVC,可以指定存储服务器类型(SC),可以指定需要多大的存储空间(PV),可以配置卷的访问模式(单主机读写、多主机只读、多主机读写)。

Persistent Volume(PV):在 Storage 上划分的一块用于存储数据的空间。

Storage Class(SC):对接后端存储服务器(Storage)的驱动(插件),配置 Storage Class 对象时,需要提供对接存储的相关信息,比如存储地址、认证用户名和密码等。

Storage:真实存储数据的服务器,包含服务器地址和认证等信息。

pod运行中所产生的数据默认在pod里面存储,当pod的生命周期结束时,数据也会随之丢失,不能持久的保存。在某些环境中我们需要把对数据进行持久化,介绍两种常用的方式nfs(小规模使用)和longhorn。

nfs:

# 安装nfs服务(server和client都要安装) # pv会自动挂载不需要手动mount挂载,pv不能直接挂载共享的根目录下 yum -y install nfs-utils mkdir /nfs && chmod -R 777 /nfs echo "/nfs *(rw,no_root_squash,sync)" > /etc/exports #启动rpcbind、nfs服务,配置为自动启动(先启动rpc后启动nfs) systemctl restart rpcbind && systemctl enable rpcbind systemctl restart nfs-server && systemctl enable nfs-server #不用重启nfs服务,配置文件就会生效 exportfs -arv # 在客户端查看共享目录 showmount -e 192.168.85.128

longhorn:

#集群所有节点安装longhorn依赖 yum install -y iscsi-initiator-utils systemctl enable --now iscsid #部署longhorn helm repo add longhorn https://charts.longhorn.io helm repo update helm pull longhorn/longhorn # 解压并配置values中defaultDataPath,defaultReplicaCount启用ingress helm install longhorn ./longhorn # 查看就绪的storageclass kubectl get sc

# 查看默认的ingress

[root@k8s-master ~]# kubectl get ing

NAME CLASS HOSTS ADDRESS PORTS AGE

longhorn-ingress <none> xip.io 192.168.85.129 80 5h29m

可通过本地解析的方式把xip.io映射到集群的中任意ip,如192.168.85.129,可访问longhorn的存储管理页面。

容器编排和应用编排

当我们在说容器编排的时候,我们在说什么?

在传统的单体式架构的应用中,我们开发、测试、交付、部署等都是针对单个组件,我们很少听到编排这个概念。而在云的时代,微服务和容器大行其道,除了为我们显示出了它们在敏捷性,可移植性等方面的巨大优势以外,也为我们的交付和运维带来了新的挑战:我们将单体式的架构拆分成越来越多细小的服务,运行在各自的容器中,那么该如何解决它们之间的依赖管理,服务发现,资源管理,高可用等问题呢?

在容器环境中,编排通常涉及到三个方面:

  • 资源编排 - 负责资源的分配,如限制 namespace 的可用资源,scheduler 针对资源的不同调度策略;
  • 工作负载编排 - 负责在资源之间共享工作负载,如 Kubernetes 通过不同的 controller 将 Pod 调度到合适的 node 上,并且负责管理它们的生命周期;
  • 服务编排 - 负责服务发现和高可用等,如 Kubernetes 中可用通过 Service 来对内暴露服务,通过 Ingress 来对外暴露服务。

在 Kubernetes 中有 5 种我们经常会用到的控制器来帮助我们进行容器编排,它们分别是 Deployment, StatefulSet, DaemonSet, CronJob, Job。

在这 5 种常见资源中,Deployment 经常被作为无状态实例控制器使用; StatefulSet 是一个有状态实例控制器; DaemonSet 可以指定在选定的 Node 上跑,每个 Node 上会跑一个副本,它有一个特点是它的 Pod 的调度不经过调度器,在 Pod 创建的时候就直接绑定 NodeName;最后一个是定时任务,它是一个上级控制器,和 Deployment 有些类似,当一个定时任务触发的时候,它会去创建一个 Job ,具体的任务实际上是由 Job 来负责执行的。

一个简单的例子

我们来考虑这么一个简单的例子,一个需要使用到数据库的 API 服务在 Kubernetes 中应该如何表示:

客户端程序通过 Ingress 来访问到内部的 API Service, API Service 将流量导流到 API Server Deployment 管理的其中一个 Pod 中,这个 Server 还需要访问数据库服务,它通过 DB Service 来访问 DataBase StatefulSet 的有状态副本。由定时任务 CronJob 来定期备份数据库,通过 DaemonSet 的 Logging 来采集日志,Monitoring 来负责收集监控指标。

应用编排

什么是应用?

一个对外提供服务的应用,首先它需要一个能够与外部通讯的网络,其次还需要能运行这个服务的载体 (Pods),如果这个应用需要存储数据,这还需要配套的存储,所以我们可以认为:

应用单元 = 网络 + 服务载体 +存储

那么我们很容易地可以将 Kubernetes 的资源联系起来,然后将他们划分为 4 种类型的应用:

  • 无状态应用 = Services + Volumes + Deployment
  • 有状态应用 = Services + Volumes + StatefulSet
  • 守护型应用 = Services + Volumes + DaemonSet
  • 批处理应用 = Services + Volumes + CronJob/Job

我们来重新审视一下之前的例子:

应用层面的四个问题

通过前面的探索,我们可以引出应用层面的四个问题:

  1. 应用包的定义
  2. 应用依赖管理
  3. 包存储
  4. 运行时管理

yaml文件编排方式

结合持久化存储给出两个例子,单主的mysql部署nfs方式:

apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv spec: capacity: storage: 2Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: nfs nfs: server: 192.168.85.128 path: "/nfsdata/mysql" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: nfs --- apiVersion: v1 kind: Service metadata: name: mysql-service spec: selector: app: mysql type: NodePort ports: - nodePort: 30001 protocol: TCP targetPort: 3306 port: 3306 --- apiVersion: apps/v1 kind: Deployment metadata: name: mysql namespace: default labels: app: mysql spec: selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - image: mysql:5.6 name: mysql imagePullPolicy: Always env: - name: MYSQL_ROOT_PASSWORD value: "123456" ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pvc

mysql的持久化存储longhorn方式:

apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv namespace: apps labels: name: mysql-data type: longhorn spec: capacity: storage: 5G volumeMode: Filesystem storageClassName: longhorn accessModes: - ReadWriteOnce csi: driver: io.rancher.longhorn fsType: ext4 volumeAttributes: numberOfReplicates: '2' staleReplicaTimeout: '20' volumeHandle: mysql-data --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim labels: type: longhorn # app: example spec: storageClassName: longhorn accessModes: - ReadWriteOnce resources: requests: storage: 5Gi --- apiVersion: v1 kind: Service metadata: name: mysql-service spec: selector: app: mysql type: NodePort ports: - nodePort: 30001 protocol: TCP targetPort: 3306 port: 3306 --- apiVersion: apps/v1 kind: Deployment metadata: name: mysql namespace: default labels: app: mysql spec: selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - image: mysql:5.6 name: mysql imagePullPolicy: IfNotPresent env: - name: MYSQL_ROOT_PASSWORD value: "123456" ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim

helm包管理器的使用

helm分为2和3,helm2权限管理比较复杂,推荐使用helm3部署

#helm3部署 wget https://mirrors.huaweicloud.com/helm/v3.5.2/helm-v3.5.2-linux-amd64.tar.gz # 解压压缩包 tar -zxvf helm-v3.3.0-linux-amd64.tar.gz # 把 helm 指令放到bin目录下 cp linux-amd64/helm /usr/bin/helm # 添加阿里云chart 库,速度最快 helm repo add apphub https://apphub.aliyuncs.com helm repo update

重点看上面公共的的ingress和Longhorn部署。企业内开发需要自定义仓库地址,构建自定义chart包并编排服务。

k8s集群运维

iptables和ipvs区别

从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables同样基于Netfilter,但是ipvs采用的hash表,iptables采用一条条的规则列表。iptables又是为了防火墙设计的,集群数量越多iptables规则就越多,而iptables规则是从上到下匹配,所以效率就越是低下。因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能 iptables 因为它纯粹是为防火墙而设计的,并且基于内核规则列表,集群数量越多性能越差。 一个例子是,在5000节点集群中使用 NodePort 服务,如果我们有2000个服务并且每个服务有10个 pod,这将在每个工作节点上至少产生20000个 iptable 记录,这可能使内核非常繁忙。 IPVS代理模式基于netfilter hook函数,该函数类似于iptables模式,但使用hash表作为底层数据结构,在内核空间中工作。这意味着IPVS模式下的kube-proxy使用更低的重定向流量。其同步规则的效率和网络吞吐量也更高。

pod异常定位和运维操作

# describe—显示关于一个或多个资源的详细信息 kubectl describe pods/kube-proxy-4v7x9 -n kube-system # ogs—显示容器日志 kubectl logs pods/kube-proxy-4v7x9 -n kube-system

rancher可视化面板

docker run --privileged -d --restart=unless-stopped -p 80:80 -p 443:443 -v /opt/rancher:/var/lib/rancher/ rancher/rancher:stable

kubectl集群管理命令

# 查看当前可用的API版本 kubectl api-versions # 查看资源 kubectl get pod,svc # 查看pv kubectl get pv # 查看pvc kubectl get pvc # 查看组件 kubectl get cs # 查看默认空间node kubectl get nodes # 查看所有空间的pod kubectl get pods --all-namespaces # 查看默认空间pod的详细信息 kubectl get pods -o wide # 查看node的详细信息 kubectl get nodes -o wide # 查看守候进程 kubectl get daemonset --all-namespaces # 查看node标签 kubectl get nodes --show-labels # 为node打标签(在pod的yaml文件中对pod进行策略调度) kubectl label node k8s-slave1 zone=test

集群pod调度

创建httpd的资源httpd.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: httpd spec: replicas: 5 selector: matchLabels: app: httpd template: metadata: labels: app: httpd spec: containers: - name: httpd image: httpd imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: web nodeSelector: # 调度到拥有zone=test标签的node zone: test

集群node扩展与缩容

增加node

1 在master节点上的hosts文件追加新机器的指向 2 在master重新生成集群加入命令 kubeadm token create --print-join-command 3 在新的node上进行部署安装,部署流程见上

移除nodes, 删除nodes2

# 使节点不可被调度 kubectl cordon k8s-node2 # 强制驱赶node2上面的pod到其他节点 kubectl drain k8s-node2 --delete-local-data --force --ignore-daemonsets # 确认下是否驱赶完成 kubectl get pods -o wide # 删除节点 kubectl delete node k8s-slave2 # 在slave2上执行残留文件 重置kubernetes服务,重置网络。删除网络配置,link kubeadm reset # 关闭kubelet systemctl stop kubelet #停止docker systemctl stop docker #重置cni rm -rf /var/lib/cni/ rm -rf /var/lib/kubelet/* rm -rf /etc/cni/ ifconfig cni0 down ifconfig flannel.1 down ifconfig docker0 down ip link delete cni0 ip link delete flannel.1 # 删除iptables iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X # 清除表中所有的记录 ipvsadm -C

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询