一、Kubernetes概述

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效。

Kubernetes集群包含master节点(控制节点)和node节点(计算节点/工作节点),应用部署在node节点上,且可以通过配置选择应用部署在某些特定的节点上。

master与node架构图:

Kubernetes具有的扩展性:

Kubernetes开放了容器运行时接口(CRI)、容器网络接口(CNI),这些接口让Kubernetes的扩展性变得最大化,而Kubernetes本身则专注于容器调度。

  • CRI(Container Runtime Interface):容器运行时接口,提供计算资源,CRI隔离了各个容器引擎之间的差异,而通过统一的接口与各个容器引擎之间进行互动。
  • CNI(Container Network Interface):容器网络接口,提供网络资源,通过CNI接口,Kubernetes可以支持不同网络环境。

主节点服务- Master

作为管理集群状态的 Master 节点,负责接收客户端的请求,安排容器的执行并且运行控制循环,将集群的状态向目标状态进行迁移。是集群的管理控制中心。

  1. API Server

采用Restful的方式对外暴露Kubernetes的API接口,是外界进行资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;

  1. Scheduler

负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;就是监视新创建的 Pod,如果没有分配节点,就选择一个节点供他们运行,这就是pod的调度;

  1. Controller Manager

集群内部的管理控制中心,负责集群资源管理和维护集群的状态,比如故障检测、自动扩展、滚动更新等;它是以Pod方式运行的,每个控制器都是Pod内运行进程的一个线程,负责后台处理集群中的常规任务。

  1. Etcd

Kubernetes的后端数据库,key/vaule方式存储,所有的Kubernetes集群的数据都存放在此处。保存了整个集群对象的状态信息和元信息配置。

一些其他的概念

  • kubectl是Kubernetes命令行工具,它是用于与Kubernetes集群交互的主要工具。通过kubectl可以执行各种操作,如创建和管理Pod、Service、Deployment等资源,查看集群状态、调试应用程序等。kubectl相当于用户与Kubernetes集群之间的桥梁,提供了一种方便的方式来管理和操作集群中的资源。
  • Coredns负责为整个集群提供DNS服务
  • Dashboard是一个基于Web的Kubernetes集群管理工具,提供了图形化的界面,方便用户查看和管理Kubernetes资源。通过kubectl命令行工具和yaml文件部署起来的。
  • Prometheus提供资源监控

工作节点 - Node

  1. kubelet:

kubelet主要负责同Container Runtime打交道,并与API Server交互,管理节点上的容器。

  1. kube-proxy:

Kube-proxy 是 Kubernetes 中的一个组件,用于在集群内部提供网络代理服务。应用组件间的访问代理,解决节点上应用的访问问题。它的主要作用是为 Kubernetes 中的 Pod 容器提供网络连接,并确保它们能够与其他容器和节点进行通信。运行在每个计算节点上,负责 Pod 网络代理。定时从 etcd 获取到 service 信息来做相应的策略。

  1. Fluentd 是一种常用的日志收集和处理工具,用于帮助管理和分析容器化应用程序的日志数据。

一些其它的概念:

  • Container Runtime: 容器运行环境是负责运行容器的软件。最主要的功能是下载镜像和运行容器。

其中etcd、apiserver、controller manager、scheduler、kubelet、Container runtime、kube-proxy是核心组件。

二、Kubernetes概念

Pod、Service、Volume 和 Namespace 是 Kubernetes 集群中基本对象,它们能够表示系统中部署的应用、工作负载、网络和磁盘资源,共同定义了集群的状态。Kubernetes 中很多其他的资源其实只对这些基本的对象进行了组合。

Pod

Pod是所有业务类型的基础,它是多个容器的组合,是容器运行的一个环境。同一个Pod内的容器地共享网络和存储的。

网络: 每一个Pod都会被指派一个唯一的Ip地址,在Pod中的每一个容器共享网络命名空间,包括Ip地址和网络端口。在同一个Pod中的容器可以同locahost进行互相通信。当Pod中的容器需要与Pod外的实体进行通信时,则需要通过端口等共享的网络资源。

存储: Pod能够被指定共享存储卷的集合,在Pod中所有的容器能够访问共享存储卷,允许这些容器共享数据。存储卷也允许在一个Pod持久化数据,以防止其中的容器需要被重启。

详述见:​​Kubernetes-核心资源之Pod_Kubernetes中文社区​

Service

虽然 每个 Pod 都会获取自己的 IP 地址,即使这些 IP 地址不总是稳定可依赖的。 这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 Pod 中的哪些 backend 呢?

Service 是一种抽象的服务,用于在 Kubernetes 集群内部或集群之间提供服务。Kubernetes中的Service是一个抽象层,用于定义一组Pod的访问方式和策略。它为Pod提供了一个稳定的网络地址和端口,使得其他应用能够通过这个地址和端口访问该组Pod。

例如,假定有一组 Pod,它们对外暴露了 9376 端口,同时还被打上 "app=MyApp" 标签。可以如下定义Service:

kind: Service
apiVersion: v1
//指的是Kubernetes api版本
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

上述配置将创建一个名称为 “my-service” 的 Service 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签 "app=MyApp" 的 Pod 上。

Service类型:

  1. ClusterIP:ClusterIP是默认的Service类型。它将创建一个内部Cluster IP地址,只能在集群内部访问。这种类型的Service通常用于内部服务之间的通信。
  2. NodePort:NodePort允许Service公开一个高于30000的端口,并将流量转发到后端Pod。这种类型的Service使得您可以从集群外部访问Service,通过Node的IP地址和指定的NodePort。NodePort适用于需要从外部访问Service的情况,但通常不建议用于生产环境。
  3. LoadBalancer:LoadBalancer允许Service通过云服务提供商(如AWS、GCP、Azure等)创建一个外部负载均衡器,并分配一个唯一的外部IP地址。这种类型的Service适用于需要在公共互联网上公开服务的情况。
  4. ExternalName:ExternalName类型的Service允许Service映射到一个外部域名,而不是Pod。当希望将Kubernetes Service与集群外部的服务集成时,可以使用ExternalName。

详见:​​Kubernetes Service _ Kubernetes(K8S)中文文档_Kubernetes中文社区​

Volume

集群中的存储卷解决了:

当容器挂掉,kubelet将重新启动它时,文件会丢失的问题;当​​Pod​​中同时运行多个容器,容器之间文件共享问题。

Kubernetes支持Volume类型有:emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、nfs、iscsi、fc (fibre channel)、flocker、glusterfs、rbd、cephfs、gitRepo、secret、persistentVolumeClaim、downwardAPI、projected、azureFileVolume、azureDisk、vsphereVolume、Quobyte、PortworxVolume、ScaleIO、StorageOS、local。

详见:​​Kubernetes Volume _ Kubernetes(K8S)中文文档_Kubernetes中文社区​

Namespace

命名空间为集群提供虚拟的隔离作用,可以实现资源隔离和访问控制。K8s集群初始有两个名字空间,分别是默认名字空间default和系统名字空间kube-system,除此以外,管理员可以可以创建新的名字空间满足需要。

Deployment

Deployment 是 Kubernetes 中用于管理应用程序副本的资源对象,它确保所需数量的 Pod 副本处于运行状态,并可以自动更新它们以实现滚动升级等操作。如果某个 Pod 发生故障或被删除,ReplicaSet 将负责创建新的 Pod 以保持所需数量的副本。

典型的应用场景包括:

  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment

只需要在Deployment中描述想要的目标状态是什么,Deployment controller就会帮你将Pod和Replica Set的实际状态改变到你的目标状态。比如一个简单的nginx应用可以定义为

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

扩容:

​kubectl scale deployment nginx-deployment --replicas 10​

更新镜像也比较简单:

​kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1​

回滚:

​kubectl rollout undo deployment/nginx-deployment​

详见:https://www.kubernetes.org.cn/deployment

控制器

Kubernetes中的控制器是用于管理和维护应用程序的核心组件之一。它们确保所需的副本数,状态和配置在Kubernetes集群中得到维护。用于管理其他Kubernetes资源(通常是Pods、ReplicaSets、Deployments、StatefulSets等)。控制器的作用是确保它所管理的资源的期望状态与实际状态保持一致。

应用负载

  1. Deployment: 用于管理ReplicaSets和Pods的滚动更新、回滚等操作。

Deployment中文意思为部署、调度,通过Deployment能操作RS(ReplicaSet),可以简单的理解为它是一种通过yml文件的声明,在Deployment 文件里可以定义Pod数量、更新方式、使用的镜像,资源限制等。无状态应用都用Deployment来创建,例:

apiVersion: extensions/v1beta1
kind: Deployment   # 定义是Deployment
metadata:
    name: nginx-deployment
spec:
    replicas: 2
    template:
        metadata:
          labels:
             app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.8.0
            ports:
            - containerPort: 80
  1. StatefulSet: 用于维护有状态应用程序的稳定标识和网络标识。

StatefulSet的出现是K8S为了解决 “有状态” 应用落地而产生的,Stateful这个单词本身就是“有状态”的意思。对于有状态应用落地K8S的可行性,StatefulSet很有效解决了这个问题。有状态应用一般都需要具备一致性,它们有固定的网络标记、持久化存储、顺序部署和扩展、顺序滚动更新等等。总结两个词就是需要稳定、有序。

那么StatefulSet如何做到Pod稳定、有序?主要概况起来有这几个方面:

  • 给Pod一个唯一和持久的标识(例:Pod name)
  • 给予Pod一份持久化存储
  • 部署Pod都是顺序性的,0 ~ N-1
  • 扩容Pod必须前面的Pod还存在着
  • 终止Pod,后面Pod也一并终止

举个例子:创建了zk01、zk02、zk03 三个Pod,zk01就是给的命名,如果要扩容zk04,那么前面01、02、03必须存在,否则不成功;如果删除了zk02,那么zk03也会被删除。

  1. DaemonSet: 用于在每个节点上运行一个Pod的实例,通常用于守护进程。

Daemon本身就是守护进程的意思,那么很显然DaemonSet就是K8S里实现守护进程机制的控制器。

比如我们需要在每个node里部署fluentd采集容器日志,那么我们完全可以采用DaemonSet机制部署。它的作用就是能确保全部(或者指定的node数里)运行一个fluentd Pod副本。当有 node加入集群时,也会为他们新增一个 Pod 。当有 node从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

所以,可以想象,DaemonSet 特别适合运行那些静默后台运行的应用,而且是连带性质的,非常方便。

  1. Job:执行一次性任务

那么在K8S里运行批处理任务用Job即可。执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。

  1. CronJob:执行定期任务。

三、Kubernetes网络

目前Kubernetes网络采用的是CNI标准,CNI(Container Network Interface)是托管于云原生计算基金会(Cloud Native Computing Foundation,CNCF)的一个项目,项目地址为https://github.com/containernetworking/CNI。它是由一组用于配置Linux容器的网络接口规范和库组成,同时还包含了一些插件。

CNI的基本思想是:在创建容器时,先创建好网络命名空间,然后调用CNI插件为这个命名空间配置网络,最后再启动容器内的进程。

在Kubernetes中,Pod是运行应用或服务的最小单元,其设计理念是在一个Pod中支持多个容器共享网络地址和文件系统。

Kubernetes集群中Pod通信

Kubernetes集群中的Pod通常会涉及到以下三种通信:

  • 同一个Pod内,容器和容器之间的通信

同一个Pod内容器之间的通信,由于其共享网络命名空间、共享Linux协议栈,因此它们之间的通信是最简单的,这些容器好像是运行在同一台机器上,直接使用Linux本地的IPC进行通信,它们之间的互相访问只需要使用localhost加端口号就可以。

例如,使用test.yaml创建同属一个Pod的两个容器redis和nginx。

apiVersion: v1
kind: Pod
metadata:
  name: dedis-nginx
  labels:
    app: web
spec:
  containers:
    - name: redis
      image: redis
      ports:
        - containerPort: 6379
    - name: nginx
      image: nginx:1.9
      ports:
        - containerPort: 80

进入容器查看各个容器的ip ,可以看到ip是一样的。

  • 同一个主机内不同Pod之间的通信

同一个主机上不同的Pod通过veth连接在同一个docker0网桥上,每个Pod从docker0动态获取IP地址,该IP地址和docker0的IP地址是处于同一网段的。这些Pod的默认路由都是docker0的IP地址,所有非本地的网络数据都会默认送到docker0网桥上,由docker0网桥直接转发,相当于一个本地的二层网络。

例如,在同一主机上使用如下nginx.yaml以及redis.yaml创建两个不同Pod,各自包含一个容器。

容器nginx与容器redis的通信过程为:

数据包通过nginx容器eth0发出,经由veth对到达docker0网桥上的vetha75b9e88接口,由docker0网桥直接转发出去到达redis容器的eth0接口

  • 跨主机Pod之间通信

跨主机的Pod之间通信较复杂,每个Pod的地址和其所在主机的docker0在同一个网段,而docker0和主机的物理网络是属于不同网段的,对于Kubernetes的网络模型来说本身是支持跨主机的Pod通信,但是默认却没有提供这种网络实现,需要借助于诸如Flannel、Calico等第三方插件来实现跨主机的Pod通信。具体的通信过程详见Flannel网络插件。

Flannel网络插件

采用Flannel插件,解析Kubernetes集群中不同主机Pod间的通信过程。

参考:https://cloud.tencent.com/developer/article/2145667

在配置Pod网络时,kubelet会在默认的/etc/cni/net.d/目录中去查找CNI JSON配置文件,然后通过type属性到/opt/cni/bin中查找相关的插件二进制文件,如下面的"portmap"。然后CNI插件调用IPAM插件(IP地址管理插件)来配置每个接口的IP地址:

  • ​"name": "cbr0"​​:这是CNI配置的名称,通常用于标识不同的网络配置。
  • ​"cniVersion": "0.3.1"​​:这指定了CNI的版本号,表明这个配置文件遵循CNI规范的哪个版本。
  • ​"plugins"​​:这是一个数组,包含了一系列CNI插件的配置。在这个例子中,有两个插件配置。

​"type": "flannel"​​:这是第一个插件配置,它指定了使用Flannel网络插件。

- ​​"delegate"​​:这是一个子配置,包含有关Flannel插件的详细配置。

- ​​"hairpinMode": true​​:这表示启用了Flannel插件的hairpin模式。Hairpin模式允许容器通过它们自己的IP地址访问同一主机上的其他容器。

- ​​"isDefaultGateway": true​​:这表示Flannel插件将设置为默认网关,以处理容器的出站流量。

​"type": "portmap"​​:这是第二个插件配置,它指定了使用Portmap网络插件。

- ​​"capabilities"​​:这是一个子配置,包含有关Portmap插件的详细配置。

- ​​"portMappings": true​​:这表示Portmap插件支持端口映射,允许容器内的端口映射到主机上。

CNI主要是定义容器网络模型规范,链接容器管理系统和网络插件,两者主要通过上面的JSON格式文件进行通信,实现容器的网络功能。CNI的主要核心是:在创建容器时,先创建好网络名称空间(netns),然后调用CNI插件配置网络,最后在启动容器内的进程。

对于Flannel插件而言,有两种为Pod分配IP的方式,一种是直接与Docker结合,通过docker0网桥来为Pod内容器分配IP;另一种是采用Kubernetes推荐的基于CNI的方式来为pause容器分配IP。 这里只介绍基于CNI的方式,容器IP的分配步骤如下所示:

① kubelet先创建pause容器生成网络命名空间;

② 使用CNI drvier调用具体的CNI插件Flannel;

③ Flannel给pause容器配置网络;

④ Pod中的其它容器共享pause容器网络。

整个集群(假设在Kubernetes集群,有两个Pod分别在node1和node2上)的网络拓扑图如下所示:

  1. ​veth​​(Virtual Ethernet Device):
  1. ​veth​​ 是一对虚拟的以太网设备,通常以成对出现,一个用于容器内部,另一个用于宿主机。
  2. ​veth​​ 设备通常用于容器的网络命名空间,它们负责将容器与宿主机的网络相连,使容器可以进行网络通信。
  1. ​eth0​​:
  1. ​eth0​​ 是一种网络接口的名称,通常用于物理或虚拟机器上,以太网设备上的默认网络接口名称。
  2. 在 Linux 系统中,​​eth0​​​ 通常是第一个以太网接口的默认名称,如果有多个以太网接口,可以有 ​​eth1​​​、​​eth2​​ 等。
  3. 它是宿主机或虚拟机器的默认网络接口,用于连接到物理网络或其他网络设备。
  1. ​cni0​​:网桥

过程描述

  1. 数据包通过位于 "node1" 主机上的一个 Nginx 容器的 ​​eth0​​ 网络接口发出。
  2. 数据包经过一个 ​​veth​​​ 对(通常由容器网络解决方案创建),到达 "cni0" 网桥上的接口。这里,​​veth​​ 设备用于将数据包从容器内部引导到主机网络。
  3. 数据包通过 "cni0" 网桥发送出去,通过主机的网络堆栈进入容器网络。
  4. 路由规则告诉系统,数据包需要通过 ​​flannel.1​​ 设备来到达目标网络 10.244.8.0/24。
  5. Flanneld 进程接收到通过 ​​flannel.1​​ 设备发送的数据包,并查询 etcd 存储,以了解目标子网 10.244.8.0/24 在 "node2" 主机上。
  6. 数据包被转发到 "node2" 主机,通过 "node1" 主机上的 ​​eth0​​ 网络接口。
  7. 在 "node2" 上的 Flanneld 进程接收到数据包,并解包它,然后将数据包转发给目标容器。

可以执行route -n 查看路由表:

# route -n
Kernel IP routing table
Destination      Gateway        Genmask        Flags Metric  Ref    Use Iface
0.0.0.0         10.244.0.1      0.0.0.0         UG    0      0        0 eth0
10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
10.244.0.0      10.244.0.1      255.255.0.0     UG    0      0        0 eth0
  • ​Destination​​:目的地列- 指示了要到达的目标网络或地址。
  • ​Gateway​​:网关列- 指示了数据包要经过哪个路由器或设备以到达目标。
  • ​Genmask​​:子网掩码列 -用于确定目标网络的范围。
  • ​Flags​​:标志列-包含路由表项的特殊标志。
  • ​Metric​​:Metric(度量值)是路由的优先级或成本,较低的值通常表示更优先的路由。
  • ​Ref​​:Ref(引用)列指示了该路由表项被多少个路由使用。
  • ​Use​​:Use(使用)列指示了该路由表项被使用的次数。
  • ​Iface​​:Iface(接口)列指示了数据包要经过的网络接口。
  1. 第一个表项 ​​0.0.0.0​​​ 表示默认路由,目的地为所有目标(0.0.0.0),网关为 ​​10.244.0.1​​​,子网掩码为 ​​0.0.0.0​​​。这意味着任何不匹配其他路由表项的数据包都将被发送到 ​​10.244.0.1​​ 这个网关上,通常是用于将所有未知目标发送到默认网关,以便访问外部网络。

  1. 第二个表项 ​​10.244.0.0​​​ 表示目标网络为 ​​10.244.0.0​​​,子网掩码为 ​​255.255.255.0​​​,没有指定网关,而是使用 ​​0.0.0.0​​​ 表示本地网络。这表示数据包目标是 ​​10.244.0.0/24​​​ 的本地网络,不需要经过网关,直接通过 ​​eth0​​ 网络接口进行路由。

  1. 第三个表项 ​​10.244.0.0​​​ 同样表示目标网络为 ​​10.244.0.0​​​,但是子网掩码为 ​​255.255.0.0​​​,网关为 ​​10.244.0.1​​​。这表示目标网络是一个更大的子网 ​​10.244.0.0/16​​​,并且数据包需要通过网关 ​​10.244.0.1​​ 来到达该网络。这可能用于特定的网络配置,以确保数据包按照正确的路径到达目标网络。

这个路由表用于控制数据包的流动和路由,根据目标地址和子网掩码来确定数据包的下一跳路径。这些表项用于管理与目标网络的通信,以及指示数据包如何到达目标。

ip -d link show cni0
//用于显示名为 cni0 的网络接口详细信息的命令

四、Kubernetes存储

常用的数据卷:

  • 本地(hostPath,emptyDir)
  • 网络(NFS,Ceph,GlusterFS)
  • 公有云(AWS EBS)
  • K8S资源(configmap,secret)

emptyDir(临时存储卷)

emptyDir卷:是一个临时存储卷,与Pod生命周期绑定一起,如果Pod删除了卷也会被删除。

应用场景:Pod中容器之间数据共享

emptyDir的实际存储路径在pod所在节点的​​/var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~empty-dir​​目录下

可以通过命令 kubectl get pod podname -o yaml查看yaml文件,通过volumes字段查看类型

kubectl get pod podname -o yaml
apiVersion: v1
kind: Pod
metadata:
   name: pod-emptydir
spec:
   containers:
   - name: write
     image: centos
     command: ["bash", "-c", "for i in {1..100}; do echo $i >> /data/hello; sleep 1; done"]
     volumeMounts:
      - name: data
       mountPath: /data
  - name: read
    image: centos
    command: ["bash", "-c", "tail -f /data/hello"]
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    emptyDir: {}

​volumeMounts​​​ 是容器配置中的一个字段,它用于将特定卷(​​volumes​​)挂载到容器的指定路径。

​volumes​​ 是在 Pod 配置中定义的一种抽象概念,它提供了一种将存储附加到容器的方法,使容器能够在其生命周期内共享数据或持久化存储。

hostPath(节点存储卷)

hostPath卷:挂载Node文件系统(Pod所在节点)上文件或者目录到Pod中的容器。

应用场景:Pod中容器需要访问​​宿主机​​文件

示例yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 36000
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    hostPath:
    path: /tmp
      type: Directory

​args​​​ 字段定义了容器的启动参数,它运行一个长时间的 ​​sleep​​ 命令来保持容器处于运行状态

​hostPath​​​ 字段定义了 hostPath 卷的配置。在这个配置中,​​path​​ 指定了要挂载到容器的路径,这里是宿主节点的 "/tmp" 目录。

这里type字段的可选值如下:

DirectoryOrCreate # 目录存在就使用,不存在就先创建再使用

Directory # 目录必须存在

FileOrCreate # 文件存在就使用,不存在就先创建再使用

File # 文件必须存在

Socket # unix套接字必须存在

CharDevice # 字符设备必须存在

BlockDevice # 块设备必须存在

HostPath可以解决数据持久化的问题,但是一旦Node节点故障了,Pod如果转移到了别的节点,又会出现问题了,此时需要准备单独的网络存储系统,比较常用的用NFS

NFS(网络存储卷)

NFS卷提供对NFS挂载支持,可以自动将NFS共享路径挂载到Pod中

配置nfs服务端,nfs-utils包每个节点都需安装

[root@k8s-node1 ~]# yum install nfs-utils
//在服务器上安装 NFS 工具,它包括 NFS 服务器和客户端组件
[root@k8s-node1 ~]# mkdir -p /ifs/kubernetes
//创建一个共享目录 /ifs/kubernetes,
[root@k8s-node1 ~]# echo "/ifs/kubernetes *(rw,no_root_squash)" >> /etc/exports
//这个命令将 NFS 共享的配置信息添加到 /etc/exports 文件中。指定了 /ifs/kubernetes 目录可以以读写(rw)方式共享,而 no_root_squash 选项表示不压制 root 用户的权限,允许 root 用户在共享目录中执行操作。
[root@k8s-node1 ~]# systemctl start nfs && systemctl enable nfs
//启动服务并配置系统启动以后自启动

示例yaml

apiVersion: v1
kind: Service
metadata:
name: nginx-nfs
  labels:
  app: nginx-nfs
....
  volumes:
  - name: www
        nfs:
        server: k8s-node1
          path: /ifs/kubernetes/
  • ​server: k8s-node1​​:这是 NFS 服务器的主机名或 IP 地址,即要从哪个 NFS 服务器上挂载数据。
  • ​path: /ifs/kubernetes/​​:这是 NFS 服务器上共享的路径,即要挂载的目标目录。容器将能够访问该目录中的数据。

pv和pvc(持久存储卷)

方便用户使用, kubernetes引入PV和PVC两种资源对象。

  • PV(Persistent Volume)是持久化卷的意思,是对底层的​​共享存储​​的一种抽象。一般情况下PV由kubernetes管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。
  • PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC其实就是用户向kubernetes系统发出的一种资源需求申请。让用户不需要关心具体的Volume实现细节

使用了PV和PVC之后,工作可以得到进一步的细分:

  • 存储:存储工程师维护
  • PV: kubernetes管理员维护
  • PVC:kubernetes用户维护

PV是存储资源的抽象,下面是资源清单文件:

apiVersion: v1  
kind: PersistentVolume
metadata:
  name: pv2
spec:
  nfs: # 存储类型,与底层真正存储对应
  capacity:  # 存储能力,目前只支持存储空间的设置
    storage: 2Gi
  accessModes:  # 访问模式
  storageClassName: # 存储类别
  persistentVolumeReclaimPolicy: # 回收策略

PV 的关键配置参数说明:

  • 存储类型 底层实际存储的类型,kubernetes支持多种存储类型,每种存储类型的配置都有所差异
  • 存储能力(capacity)
  • 访问模式(accessModes) 用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
  • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
  • ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载
  • ReadWriteMany(RWX):读写权限,可以被多个节点挂载
  • 回收策略(persistentVolumeReclaimPolicy) 当PV不再被使用了之后,对其的处理方式。目前支持三种策略:
  • Retain (保留) 保留数据,需要管理员手工清理数据
  • Recycle(回收) 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*
  • Delete (删除) 与 PV 相连的后端存储完成 volume 的删除操作,当然这常见于云服务商的存储服务
  • 存储类别 PV可以通过storageClassName参数指定一个存储类别
  • 状态(status) 一个 PV 的生命周期中,可能会处于4种不同的阶段:
  • Available(可用): 表示可用状态,还未被任何 PVC 绑定
  • Bound(已绑定): 表示 PV 已经被 PVC 绑定
  • Released(已释放): 表示 PVC 被删除,但是资源还未被集群重新声明
  • Failed(失败): 表示该 PV 的自动回收失败

pv示例

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:- ReadWriteMany
  nfs:
    server: k8s-node1
    path: /ifs/kubernetes

pvc示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:- ReadWriteMany
  resources:
  requests:
  storage: 5Gi

deployment示例

apiVersion: v1
kind: Service
metadata:
  name: nginx-pvc
 ....
  volumes:
  - name: www-pvc
     persistentVolumeClaim:
        claimName: my-pvc

ConfigMap(配置存储)

ConfigMap是一种比较特殊的存储卷,它的主要作用是用来存储配置信息的。

用于存储非密钥/值数据,例如配置文件、环境变量和命令行参数等。

创建configmap.yaml,内容如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap
  namespace: dev
data:
  test-conf: |+
    SESSION_LIFETIME: 3600
    URL: "http://test-server:8080"

接下来,使用此配置文件创建configmap

# 创建configmap
[root@k8s-master01 ~]# kubectl create -f configmap.yaml
configmap/configmap created

接下来写一个pod-configmap.yaml,将上面创建的configmap挂载进去

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap
  namespace: dev
spec:
  containers:- name: nginx
    image: nginx:1.17.1
    volumeMounts: # 将configmap挂载到目录
    - name: config
      mountPath: /configmap/config  # 挂载路径
  volumes: # 引用configmap
  - name: config
    configMap:name: configmap
# 创建pod
[root@k8s-master01 ~]# kubectl create -f pod-configmap.yaml
pod/pod-configmap created

# 查看pod
[root@k8s-master01 ~]# kubectl get pod pod-configmap -n dev
NAME            READY   STATUS    RESTARTS   AGE
pod-configmap   1/1     Running   0          6s

#进入容器
[root@k8s-master01 ~]# kubectl exec -it pod-configmap -n dev /bin/sh
# cd /configmap/config/
# ls
info
# more info
//可以看到configmap的数据了

Secret

在kubernetes中,还存在一种和ConfigMap非常类似的对象,称为Secret对象。它主要用于存储敏感信息,例如密码、秘钥、证书等等。

编写secret.yaml,并创建Secret

apiVersion: v1
kind: Secret
metadata:
  name: secret
  namespace: dev
type: Opaque
data:
  username: YWRtaW4=
  password: MTIzNDU2
 //YWRtaW4=,MTIzNDU2是经过base64编码的用户名和密码
# 创建secret
[root@k8s-master01 ~]# kubectl create -f secret.yaml
secret/secret created

# 查看secret详情
[root@k8s-master01 ~]# kubectl describe secret secret -n dev
Name:         secret
Namespace:    dev
Labels:       <none>
Annotations:  <none>
Type:  Opaque
Data
====
password:  6 bytes
username:  5 bytes

然后创建pod-secret.yaml,将上面创建的secret挂载进去:

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    volumeMounts: # 将secret挂载到目录
    - name: config
      mountPath: /secret/config
  volumes:
  - name: config
    secret:
       secretName: secret

然后创建pod即可。

五、Kubernetes常用命令

下面是一些常用的Kubernetes命令,用于管理集群和应用程序。

kubectl语法

使用以下语法从终端窗口运行 ​​kubectl​​ 命令:

kubectl [command] [TYPE] [NAME] [flags]

其中 ​​command​​​、​​TYPE​​​、​​NAME​​​ 和 ​​flags​​ 分别是:

  • ​command​​​:指定要对一个或多个资源执行的操作,例如 ​​create​​​、​​get​​​、​​describe​​​、​​delete​​。
  • ​TYPE​​:指定资源类型。资源类型不区分大小写, 可以指定单数、复数或缩写形式。例如,以下命令输出相同的结果:
kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1
  • ​NAME​​​:指定资源的名称。名称区分大小写。 如果省略名称,则显示所有资源的详细信息。例如:​​kubectl get pods​​。在对多个资源执行操作时,你可以按类型和名称指定每个资源,或指定一个或多个文件:
  • ​flags​​​: 指定可选的参数。例如,可以使用 ​​-s​​​ 或 ​​--server​​ 参数指定 Kubernetes API 服务器的地址和端口。
  • ​Kubectl help​​ 帮助
kubectl 可操作资源对象类型

资源类型

缩写别名

apiservices

certificatesigningrequests

csr

clusters

clusterrolebindings

clusterroles

componentstatuses

cs

configmaps

cm

controllerrevisions

cronjobs

customresourcedefinition

crd

daemonsets

ds

deployments

deploy

endpoints

ep

events

ev

horizontalpodautoscalers

hpa

ingresses

ing

jobs

limitranges

limits

namespaces

ns

networkpolicies

netpol

nodes

no

persistentvolumeclaims

pvc

persistentvolumes

pv

poddisruptionbudget

pdb

podpreset

pods

po

podsecuritypolicies

psp

podtemplates

replicasets

rs

replicationcontrollers

rc

resourcequotas

quota

rolebindings

roles

secrets

serviceaccounts

sa

services

svc

statefulsets

storageclasses

基础命令

在线调试网​​Kubernetes Playground 1.28 | Killercoda​​es

常用命令汇总表

命令

说明

kubectl apply

创建或更新资源对象

kubectl create

通过 yaml/json 文件或者标准输入创建一个资源对象,支持很多子命令 例如 namespace pod deployment service 等

kubectl expose

将 yaml/json 文件中定义的资源对象的端口暴露给新的 service 资源对象

kubectl run

创建并运行一个或多个容器镜像

kubectl set

配置资源对象设置特定功能

kubectl explain

查看资源对象的详细信息

kubectl get

获取一个或多个资源对象的信息

kubectl edit

使用默认编辑器编辑服务器上定义的资源对象

kubectl delete

通过 yaml/json 文件、资源名称或标签选择器来删除资源

kubectl rollout

对资源进行滚动或回滚,包括deployments、daemonsets

kubectl scale

扩容或者缩容 deployment replicaset replication contrller 等

kubectl autoscale

自动设置在 k8s 系统中运行的 pod 数量(水平自动伸缩)

kubectl cetificate

修改证书资源对象

kubectl cluster-info

查看集群信息

kubectl top

显示资源 cpu 内存 存储使用情况

kubectl cordon

标记节点为不可调度

kubectl uncordon

指定节点为可调度

kubectl drain

安全的驱逐节点的所有 pod

kubectl taint

将一个或多个节点设置为污点

kubectl describe

显示一个或多个资源对象的详细信息

kubectl logs

输出 pod 资源对象中一个容器的日志

kubectl attach

连接到命令行一个运行的容器,如果命令行中没有指定容器名称,默认容器是在 Pod 配置中第一个声明的容器

kubectl exec

在指定容器内执行命令

kubectl port-forward

将本机指定端口映射到 pod 资源对象的端口

kubectl proxy

将本机指定端口映射到 kube-apiserver

kubectl cp

用于 pod 与主机交换文件

kubectl auth

检查验证

kubectl label

增删改资源的标签

kubectl annotate

更新一个或者多个资源对象的注释(annotaion)信息

kubectl completion

命令自动补全

kubectl diff

对比本地 yaml/json 文件与 kube-apiserver 中运行的配置文件是否有差异

kubectl apply

通过 yaml/json 文件 标准输入对资源进行配置更新或者创建

kubectl patch

通过 patch 方式修改资源对象字段(补丁式)

kubectl replace

通过 yaml/json 文件或者标准输入来替换资源对象

kubectl wait

在一个或者多个资源上等待条件达成

kubectl convert

用于将资源配置文件从一个 API 版本转换为另一个 API 版本。这个命令通常用于更新或迁移 Kubernetes 资源的配置文件,以适应不同的 API 版本的需求。

kubectl kustomize

定制 kubernetes 配置

kubectl config

管理 kubeconfig 配置文件

kubectl plugin

运行命令行插件功能

kubectl version

查看客户端服务端的系统版本信息

kubectl api-versions

列出当前 kubernetes 系统支持的资源组和资源版本表现形式为/

kubectl api-resources

列出当前 kubernetes 系统支持的 resource 资源列表

kubectl options

查看支持的参数列表

常用命令参数列表

参数名称

说明

--as string

以指定用户的身份执行操作

--as-group stringArray

模拟指定的组来执行操作,可以使用这个标志来指定多个组。

--cache-dir string

默认值: "$HOME/.kube/cache" 默认缓存目录

--certificate-authority string

指向证书机构的 cert 文件路径

--client-certificate string

TLS 使用的客户端证书路径

--client-key string

TLS 使用的客户端密钥文件路径

--cluster string

要使用的 kubeconfig 集群的名称

-h, --help

kubectl 操作的帮助命令

--log-dir string

如果不为空,则将日志文件写入此目录

--log-file string

如果不为空,则将使用此日志文件

--log-file-max-size uint 默认值: 1800

定义日志文件的最大尺寸。单位为兆字节。如果值设置为 0,则表示日志文件大小不受限制。

--log-flush-frequency duration 默认值: 5s

两次日志刷新操作之间的最长时间(秒)

--logtostderr 默认值: true

日志输出到 stderr 而不是文件中

--match-server-version

要求客户端版本和服务端版本相匹配

-n, --namespace string

如果存在,CLI 请求将使用此命名空间

--password string

API 服务器进行基本身份验证的密码

-s, --server string

Kubernetes API 服务器的地址和端口

--skip-headers

设置为 true 则表示跳过在日志消息中出现 header 前缀信息

--skip-log-headers

设置为 true 则表示在打开日志文件时跳过 header 信息

--token string

用于对 API 服务器进行身份认证的持有者令牌

--user string

指定使用 kubeconfig 配置文件中的用户名

--username string

用于 API 服务器的基本身份验证的用户名

--version version[=true]

打印 kubectl 版本信息并退出

--help

显示命令的帮助信息

输出选项

所有 ​​kubectl​​​ 命令的默认输出格式都是纯文本格式。要以特定格式在终端窗口输出详细信息, 可以将 ​​-o 或 --output​​​ 参数添加到受支持的 ​​kubectl​​ 命令中。

输出格式

描述

-o custom-columns=<spec>

使用逗号分隔的自定义列列表打印表

-o custom-columns-file=<filename>

从文件中获取自定义列名进行输出

-o json

输出JSON格式的API对象

-o jsonpath=<template>

打印jsonpath表达式定义的字段

-o jsonpath-file=<filename>

打印<filename>文件中jsonpath表达式定义的字段

-o name

仅打印资源名称而不打印任何其他内容

-o wide

以纯文本格式输出,包含所有附加信息

-o yaml

输出YAML格式的API对象

获取信息
describe – 获得资源的集群相关的信息

describe类似于get,同样用于获取resource的相关信息。不同的是,get获得的是更详细的resource个性的详细信息,describe获得的是resource集群相关的信息。describe命令同get类似,但是describe不支持-o选项,对于同一类型资源,describe输出的信息格式,内容域相同。

说明:如果发现是查询某个resource的信息,使用get命令能够获取更加详尽的信息。但是如果想要查询某个资源的状态,如某个pod并不是在running状态,这时需要获取更详尽的状态信息时,就应该使用describe命令。

命令格式如下:

kubectl describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)

例如:

1)查看ubuntu-148该节点信息

kubectl describe node ubuntu-148

2)查看kube-system命名空间下etcd-master-151的业务详细信息

kubectl describe pod etcd-master-151 -n kube-system
explain – 查看文档或参考资料

用于获取有关 Kubernetes 资源对象(如 Pod、Service、Deployment 等)的详细信息,包括其各种字段、字段类型、默认值和可用选项。通过使用该命令,可以查看有关资源对象的文档,以便更好地理解如何创建和配置它们。命令格式如下:

kubectl explain RESOURCE
  • ​RESOURCE​​​ 是您想要查看文档的 Kubernetes 资源类型,如 ​​pod​​​、​​service​​​、​​deployment​​ 等。

例如:

1)查看pod的相关文档:

kubectl explain pod

2)获取资源的特定字段(比如,pod.spec.containers)的文档

kubectl explain pod.spec.containers
get – 获取列出一个或多个资源的信息

get命令用于获取集群的一个或一些资源信息。该命令可以列出集群所有资源的详细信息,resource包括集群节点、运行的Pod、Deployment、Service等。命令格式如下:

Kubectl get [TYPE] [NAME] [flags]

部分参数说明:

[TYPE]可以是:node、pod、deployment、service等等

[NAME]为具体的资源对象名称:

写了具体的资源对象名称,就会返回指定的该资源对象信息;

没有写具体的资源名称,就会返回该资源所有对象信息。

[flags] kubectl 子命令的可选参数:

1)-n 指定命令空间(项目),没有此参数则是默认返回default命名空间资源信息;

2)-A 表示返回所有命名空间的资源信息;

3)-o 指定输出的格式,例如yaml(以yaml格式显示结果),json(以json格式显示结果),wide(输出额外信息,可以看到pod运行在那个node上)。

4)-l 用于根据标签(labels)选择资源。

例如:

1)获取default命名空间下所有pod的详细信息:

kubectl get po -o wide
//指定输出格式

对于输出的结果信息解释如下:

  • 名称(Name): 资源的名称,通常是资源的唯一标识符。
  • 准备就绪(READY): 对于 Pods,这表示容器是否已准备就绪。例如,​​1/1​​ 表示容器准备就绪。
  • 状态(STATUS): 资源的状态,例如对于 Pods,这表示它们是否正在运行。
  • 重启次数(RESTARTS): 对于 Pods,这是容器的重启次数。
  • 年龄(AGE): 资源存在的时间,通常以时、分、秒来表示。
  • IP 地址(IP): 对于 Pods,这是其分配的 IP 地址。
  • 节点(NODE): 对于 Pods,这是它们所在的节点。
  • 提名节点(Nominated Node):已经为 Pod 提名推荐的节点,即在调度时已经选择了一个节点,但还未最终分配。在节点调度过程的中间阶段使用,用于表示 Pod 已经有了一个候选节点,但尚未正式绑定到该节点。一旦节点绑定成功。这有助于跟踪节点调度过程中的状态。
  • 就绪性检查门(READINESS GATES):用于控制 Pod 是否被添加到 Service 负载均衡的一种机制。允许定义一组检查条件,只有在这些条件满足的情况下,Service 才会将流量引导到特定的 Pod。这可以确保只有真正就绪并能够处理请求的 Pod 才会接收流量,从而提高应用程序的可用性和稳定性。

2)获取kube-system命名空间下运行的所有pod

kubectl get pod -n  kube-system

3)获取所有namespace下运行的所有pod:

kubectl get po --all-namespaces

或者

kubectl get po -A

4)获取kube-system命名空间下运行的所有pod的标签:

kubectl get pod -n kube-system --show-labels

5)指定标签获取pod

kubectl get pods -l app=example

下图是获取指定命名空间下指定标签的pod

6)获取集群中的所有命名空间:

kubectl get namespace

7)以yaml格式输出pod的详细信息:

kubectl get po <podname> -o yaml

8)以json格式输出pod的详细信息:

kubectl get po <podname> -o json

9)查看所有的资源信息:

kubectl get all
//包括pod service deployment replicaset(控制器,管理副本)

  • ​DESIRED​​:期望的副本数为1。
  • ​CURRENT​​:表示当前正在运行的实际副本数量。
  • ​READY​​:表示当前正在运行的副本中有多少个已经准备好接收流量和请求。这是通过就绪性检查(Readiness Probe)来确定的,
  • ​AGE​​:Replicaset 创建后已经存在了41天。

10)查看服务的详细信息,显示了服务名称,类型,集群ip,端口,时间等信息

kubectl get svc
 kubectl get svc -n kube-system

  • ​NAME​​​:Service的名称是 ​​default-http-backend​​。
  • ​TYPE​​​:Service的类型是 ​​ClusterIP​​,这意味着它是一个集群内部可访问的Service,没有外部IP地址。
  • ​CLUSTER-IP​​​:Service的Cluster IP地址为 ​​10.97.155.5​​,这是Service在集群内部使用的IP地址。
  • ​EXTERNAL-IP​​​:由于类型是 ​​ClusterIP​​​,所以​​EXTERNAL-IP​​​字段为 ​​<none>​​,表示没有外部IP地址,只能在集群内部访问。
  • ​PORT(S)​​​:Service监听的端口是 ​​80/TCP​​,表示它将请求转发到Pod的端口80。
  • ​AGE​​:Service创建后已经存在了41天。

11)获取当前集群中所有的 ReplicaSet(副本集),以及他们的可用数量以及状态等信息

kubectl get rs

在上述示例中,列出了三个不同的 ReplicaSet,每个 ReplicaSet 都显示了所需、当前和就绪的副本数量,以及创建时间。

12)查看已经部署了的所有应用,可以看到容器,以及容器所用的镜像,标签等信息

kubectl get deploy -o wide
kubectl get deployments -o wide

  • ​READY​​​:表示 Deployment 中就绪的 Pod 副本数量,格式为 ​​当前已就绪的Pod数量/期望的Pod数量​​。1/1 表示有1个Pod副本已经就绪,达到了期望状态。表示哪些 Pod 副本已经通过健康检查并准备好服务请求。
  • ​UP-TO-DATE​​:表示 Deployment 中更新到最新状态的 Pod 副本数量。1 表示有1个Pod副本已经更新到了最新的状态。表示已经更新到最新版本的 Pod 副本的数量,通常和滚动升级有关
  • ​AVAILABLE​​:表示 Deployment 中可用的 Pod 副本数量。1 表示有1个Pod副本是可用的。
  • ​AGE​​:Deployment 创建后已经存在了41天。
  • ​CONTAINERS​​​:Deployment 中运行的容器名称是 ​​default-http-backend​​。
  • ​IMAGES​​:容器的镜像信息。
  • ​SELECTOR​​:用于匹配由该 Deployment 控制的 Pod 的标签选择器。

AVAILABLE 表示 Deployment 中的 Pod 数量,它们在部署的期望副本数量下可用,但不一定都已经就绪。READY 通常是 AVAILABLE 的子集。READY 用于确定当前处于活动状态且可以提供服务的 Pod 数量,而 AVAILABLE 考虑了所有在部署中的 Pod。

logs – 输出pod中一个容器的日志

logs命令用于显示pod运行中,容器内程序输出到标准输出的内容。如果要获得tail -f的方式,需使用-f选项。如果pod只包含一个容器则可以省略容器名。命令格式如下:

kubectl logs [-f] [-p] POD [-c CONTAINER]
  • ​-f​​​:此选项用于实时跟踪日志的输出,类似于 ​​tail -f​​ 命令。它会持续监视并显示新的日志条目,适用于实时监控应用程序的日志。
  • ​-p​​:此选项用于查看先前容器的日志,例如容器重新启动后的日志。如果容器曾经重新启动过,可以使用此选项来查看先前的日志。
  • ​POD​​:要查看日志的 Pod 的名称。
  • ​-c CONTAINER​​:如果 Pod 包含多个容器,可以使用此选项来指定要查看日志的容器名称。如果 Pod 只包含一个容器,通常不需要指定此选项。

例如:

1)返回名称为nginx的pod资源对象日志。

kubectl logs nginx

2)持续输出命名空间为kube-system名称为etcd-master-1的pod资源对象中容器etcd的日志。

kubectl logs  etcd-master-1 -n kube-system -c etcd
//健康检查日志

3)仅输出名为nginx的pod对象中最近的20条日志

kubectl logs --tail=20 nginx
top – 查看节点和 Pod 的 CPU 和内存使用情况。

用于查看 Kubernetes 集群中节点和 Pod 的 CPU 和内存使用情况

kubectl top nodes

状态管理
apply – 创建或更新资源对象

通过文件名或控制台输入,对资源进行配置。 如果资源不存在,将会新建一个。如果资源已存在,可对资源进行更新。命令格式如下:

kubectl apply -f <filename>

​kubectl apply​​ 命令通常用于在运行时应用或更新资源,而不需要手动删除旧资源。

create 与apply的区别是

kubectl create命令是创建新资源。 因此,如果资源对象创建完成后,再次运行create该命令,则会抛出错误,因为资源名称在名称空间中应该是唯一的。

apply命令将配置应用于资源。 如果资源对象不存在,那么它将被创建;如果资源对象已存在, 可对资源进行修改。

在首次创建新资源时,kubectl create -f test.yaml 和 kubectl apply -f test.yaml 效果一致。

例如,

1)应用一个配置文件

根据 ​​my-deployment.yaml​​ 文件中的定义创建或更新Kubernetes资源。例如,如果该文件包含一个Deployment的定义,它将创建一个新的Deployment或更新现有的Deployment。

kubectl apply -f my-deployment.yaml

2)应用多个配置文件

这个命令将应用目录 ​​config/​​ 中所有以 ​​.yaml​​ 或 ​​.json​​ 结尾的配置文件。这是一种批量应用配置文件的方式。

kubectl apply -f config/
annotate –为资源添加或修改注释

用于为 Kubernetes 资源添加或修改注释(annotations)。注释是键值对的形式,通常用于提供资源的额外信息、备注、描述等,与标签(labels)不同,注释的目的是提供更多的辅助性信息,而不用于资源的筛选或分类。

kubectl annotate RESOURCE NAME KEY_1=VALUE_1 KEY_2=VALUE_2 ...
  • ​RESOURCE​​​ 是要添加或修改注释的资源类型(例如,​​pod​​​、​​node​​​、​​service​​ 等)。
  • ​NAME​​ 是资源的名称,可以是资源的名称或注释选择器(如果想要为多个资源添加相同的注释)。
  • ​KEY_1=VALUE_1​​​、​​KEY_2=VALUE_2​​ 等是要添加或修改的注释键值对。

例如:

1)为pod添加注释:

kubectl annotate pod my-pod descriptinotallow="Web server pod"
create – 创建资源

kubectl命令用于根据文件或输入创建集群资源。如果已经定义了相应resource的yaml或json文件,通过以下命令可创建文件内定义的resource。如果资源对象已存在,再次运行create命令会报错,资源对象名称在名称空间中应该是唯一的。命令格式如下:

kubectl create -f <filename>

例如,

1)对已经编写好的test.yaml文件资源创建。

kubectl create -f test.yaml

先创建tomcat.yaml文件,再用.yaml文件创建deployment。

情况说明:

--image-pull-policy=IfNotPresent 这个参数在'kubectl create deployment 不存在,如果你想指定拉取策略,只能在yaml文件中指定。

cp – 主机与pod间文件传输

主要用于在本地系统和 Kubernetes Pod 之间复制文件。命令格式如下:

kubectl cp <file-spec-src> <file-spec-dest> [options]

如果pod内有多个容器,但是在cp命令中,没有指明是哪个容器,它会选择pod规范定义的第一个容器。

例如:

1)将“/home/shy”本地目录拷贝到默认命名空间的远端pod的“/home/shy”目录下。

kubectl cp /home/shy nginx:/home/shy
//源地址/home/shy
 //目的 nginx:/home/shy

2)将default命名空间下名为nginx的pod对象的容器内文件夹“/home/qwe”,拷贝到本地的目录“”/home/qwe1“

kubectl cp default/nginx:home/qwe /home/qwe1
 //源地址default/nginx:home/qwe
 //目的 /home/qwe1

3)将default命名空间下名为nginx的pod对象的容器内文件“/home/shy/test.yaml”,拷贝到本地的目录“/home/qwe1/test.yaml”。

kubectl cp default/nginx:home/shy/test.yaml /home/qwe1/test.yaml  
//源地址default/nginx:home/shy/test.yaml
//目的地址 /home/qwe1/test.yaml

4)将“home/qwe/testqwe.txt”本地目录下文件内容拷贝到默认命名空间的远端pod的“/home/shy/testqwe.txt”文件。

kubectl cp /home/qwe/testqwe.txt nginx:/home/shy/testqwe.txt

5)复制/tmp/foo本地文件到/tmp/bar在远程pod在一个特定的容器

kubectl cp /tmp/foo <some-pod>:tmp/bar -c <specific-container>

说明:从容器拷贝文件到本地的时候,建议pod冒号后直接加根目录,不能加“/”,否则报错,一般报错提示为“tar: Removing leading `/' from member names”。不过实验证明,加了“/”,也是可以拷贝成功的。

delete – 删除资源

根据resource名或label删除resource。命令格式如下:

kubectl delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])

这个命令可以按照以下两种方式使用:

  1. 通过文件名删除资源:
  1. ​kubectl delete -f FILENAME​​:这允许使用一个文件中定义的配置来删除一个或多个资源对象。在文件中,您可以定义要删除的资源类型和名称。
  1. 通过资源类型和名称或标签删除资源:
  1. ​kubectl delete TYPE NAME​​:这允许通过指定资源类型和名称来删除一个特定的资源对象。
  2. ​kubectl delete TYPE -l label​​:这允许通过标签选择器删除匹配标签的资源对象。
  3. ​kubectl delete TYPE --all​​:这允许删除指定类型的所有资源对象。

例如:

1)删除test命名空间下名为nginx的pod:

kubectl delete pod nginx -n test

或者(nginx.yaml是创建名为nginx的pod资源时的配置文件)

kubectl delete -f nginx.yaml

2)删除default命名空间下名为test的deployment:

kubectl delete deployment test

3)删除具有特定标签的资源

kubectl delete pod -l app=my-app

edit – 编辑资源

使用默认编辑器编辑服务器上定义的资源。命令格式如下:

kubectl edit (RESOURCE/NAME | -f FILENAME)

例如:

1)使用edit直接更新pod资源对象命令为:

kubectl edit po <podname>

上面命令的效果等同于:

kubectl get po <podname> -o yaml >> /tmp/nginx-tmp.yaml
vim /tmp/nginx-tmp.yaml
/*do some changes here */
kubectl replace -f /tmp/nginx-tmp.yaml
//    >> /tmp/nginx-tmp.yaml定向输出到文件

编辑pod的规范,如下字段都能进行修改。

expose – 将资源暴露为新的Kubernetes Service

将资源暴露为新的Kubernetes Service,​​kubectl expose​​ 命令是一种创建 Service 的方法之一。命令格式如下:

kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]

参数说明:

(-f FILENAME | TYPE NAME):可以使用 -f 选项并提供配置文件的路径 (FILENAME) 来创建 Service,或者直接指定资源的类型 (TYPE) 和名称 (NAME)。这两种方式之一都可以用于指定要创建 Service 的目标资源。

--port=port:指定 Service 的端口号。这是 Service 监听的端口,用于接收流量。

--protocol=TCP|UDP:指定服务的协议,可以是 TCP 或 UDP。

--target-port=number-or-name:指定要转发流量到的目标 Pod 的端口号或名称。

--name=name:指定要创建的 Service 的名称。

--external-ip=external-ip-of-service:指定外部 IP 地址,如果需要将 Service 暴露到集群外部(例如,NodePort 或 LoadBalancer 类型的 Service)。

--type=type:指定 Service 的类型,可以是 ClusterIP、NodePort 或 LoadBalancer。这决定了 Service 的访问方式和范围。

例如,

1)为名为nginx的deployment资源创建服务,该服务监听端口80上运行,并连接到 Deployment 中的8000端口上

kubectl expose deployment nginx-deployment --port=80 --target-port=8000

Kubernetes 将创建一个新的 Service,该 Service 允许通过集群内部的 IP 和端口 80 访问 Deployment 中运行的应用程序,而这个应用程序实际上在 Deployment 中的端口 8000 上运行。

默认创建的Service类型是ClusterIP。

2)为名为valid-pod的pod创建一个service,该服务在端口444上运行,创建的service名称为“frontend”。

kubectl expose pod valid-pod --port=444 --name=frontend
label – 为资源添加或修改标签。

用于为 Kubernetes 资源添加或修改标签。标签是键值对的形式,用于对资源进行分类、组织和筛选。

kubectl label RESOURCE NAME KEY_1=VALUE_1 KEY_2=VALUE_2
  • ​RESOURCE​​​ 是要添加或修改标签的资源类型(例如,​​pod​​​、​​node​​​、​​deployment​​ 等)。
  • ​NAME​​ 是资源的名称,可以是资源的名称或标签选择器(如果想要为多个资源添加相同的标签)。
  • ​KEY_1=VALUE_1​​​、​​KEY_2=VALUE_2​​ 等是要添加或修改的标签键值对。

例如:

为pod添加标签:

kubectl label pod my-pod envirnotallow=production
patch – 修改资源(局部修改)

如果一个容器已经在运行,这时需要对一些容器属性进行修改,又不想删除容器,或不方便通过replace的方式进行更新。kubernetes还提供了一种在容器运行时,直接对容器进行修改的方式,就是patch命令。 命令格式如下:

kubectl patch (-f FILENAME | TYPE NAME) -p PATCH

其中:

  • ​-f FILENAME​​:可以指定一个包含资源对象配置的文件。
  • ​TYPE​​​:是资源类型,例如 ​​pod​​​、​​service​​​、​​deployment​​ 等。
  • ​NAME​​:是资源对象的名称。
  • ​-p PATCH​​:指定要应用的补丁,通常以 JSON 或 YAML 格式提供。

例如:

1)已存在一个pod的label为app=nginx1,如果需要在运行过程中,将其修改为app=nginx2。

kubectl patch pod podname -p '{"metadata":{"labels":{"app":"nginx2"}}}'

2)修改命名为nginx的pod资源容器镜像为"172.172.30.199/library/httpd:alpine"

kubectl patch pod nginx -p '{"spec":{"containers":[{"name":"nginx","image":"172.172.30.199/library/httpd:alpine"}]}}'
replace – 修改资源(全局替换)

replace命令用于对已有资源进行更新、替换。都可以直接修改原yaml文件,然后执行replace命令。命令格式如下:

kubectl replace -f <filename>

例如:

1)修改完test.yaml配置文件后,直接运行如下命令,生成对资源的更新。

kubectl replace -f test.yaml

​kubectl replace​​​ 用于完全替换资源对象,而 ​​kubectl apply​​​ 用于部分更新资源对象。在大多数情况下,推荐使用 ​​kubectl apply​​,因为它更灵活且通常更安全。

  • ​kubectl replace​​ 适用于需要完全替换资源对象的情况,通常用于对现有资源进行重大更改或修复配置错误。
  • ​kubectl apply​​ 更适用于部分更新资源对象的情况,它可以用于添加、修改或删除资源对象的一部分配置,而不会影响其余配置。
set – 配置应用资源

配置应用资源,使用命令更改现有应用资源一些信息。命令格式如下:

kubectl set SUBCOMMAND

SUBCOMMAND子命令有

  • image 用来设置资源的images(镜像)。
  • resources 用来设置资源的resources(计算资源需求)。
  • selector 用来设置资源的selector(选择器)。
  • subject 用来更新RoleBinding / ClusterRoleBinding中User、Group 或 ServiceAccount。

例如:

1)将名为nginx的pod对象中容器镜像设置为“nginx:1.9.1”:

kubectl set image pod/nginx nginx=nginx:1.9.1

Kubernetes 将会找到目标 Pod(名为 ​​nginx​​​ 的 Pod),并将 ​​nginx​​​ 容器的镜像更新为 ​​nginx:1.9.1​​。这将触发 Pod 的滚动更新,逐步替换旧的容器实例为新的镜像版本。

2)将deployment的nginx容器cpu限制为“200m”,将内存设置为“512Mi”

kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi

3)对于名为test123的deployment对象中nginx123容器,删除cpu限制和内存限制:

kubectl set resources deployment  test123   -c=nginx123  --limits=cpu=0,memory=0
 //-c=nginx123 指定容器的名称

3)将名为 ​​my-service​​​ 的 Service 的标签选择器,使其只选择带有标签 ​​app=my-app​​​ 和 ​​env=staging​​ 的 Pod。

kubectl set selector service/my-service -l app=my-app,env=staging

详细命令见参考资料9中的中文文档。

关于​​kubectl replace​​​、​​kubectl apply​​​、​​kubectl patch​​​ 和 ​​kubectl set​​ 命令的对比说明

1. kubectl replace:适用于完全替换资源的情况,会删除并重新创建资源,可能会导致资源不可用。在命令中是使用yaml文件进行修改

2. kubectl apply:用于首次部署和后续更新资源,可以根据资源的存在与否来执行创建或更新操作。在命令中使用的yaml文件进行创建

3. kubectl patch:允许对资源的部分规范进行精细控制的修改,而不是整个规范。在命令中使用的以 JSON 或 YAML 格式进行修改,如{key:value}

4. kubectl set:用于修改资源的字段,例如标签和注释,而不需要编辑 YAML 文件。在命令中使用子命令进行修改,如 set image pod/nginx nginx=nginx:1.9.1

诊断和调试
attach – 连接到正在运行的容器。

用于连接到正在运行的容器,允许您与容器的标准输入(stdin)、输出(stdout)和错误输出(stderr)进行交互。

kubectl attach POD_NAME -c CONTAINER_NAME
  • ​POD_NAME​​ 是要连接的 Pod 的名称。
  • ​-c CONTAINER_NAME​​ 指定要连接的容器的名称。在 Pod 中有多个容器的情况下,您需要指定要连接的容器名称。

例如:

1)连接my-pod中my-container容器

kubectl attach my-pod -c my-container

一旦连接成功,您可以与容器进行交互,查看其输出,输入命令等。

2)获取正在运行中的pod 123456-7890的输出,默认连接到第一个容器

kubectl attach 123456-7890  -i -t

注意事项:

  • 运行 ​​kubectl attach​​​ 后,可能需要按下 ​​Ctrl+C​​ 来退出交互模式。
  • 使用 ​​-i​​​ 选项可以使 ​​kubectl attach​​ 命令保持标准输入(stdin)打开,以便能够向容器发送输入。
  • 使用 ​​-t​​ 选项可以分配一个伪终端,以便更好地处理终端交互。
run – 创建并运行一个或多个容器镜像。

创建并运行一个或多个容器镜像。

kubectl run NAME --image=image [--env="key=value"] [--port=port] [--dry-run=server|client] [--overrides=inline-json][--command] -- [COMMAND] [args...] [options]

例如:

1)基于10.8.59.115/appstore/nginx镜像,运行一个名为nginxtest的pod,容器开放端口为5701。

kubectl run nginxtest --image=10.8.59.115/appstore/nginx@sha256:25dedae0aceb6b4fe5837a0acbacc6580453717f126a095aa05a3c6fcea14dd4  --port=5701

说明:

  • ​kubectl create​​: 用于创建各种 Kubernetes 资源对象,如 Pod、Service、Namespace、ConfigMap 等。它的主要作用是创建和配置这些资源对象。参数是yaml文件
  • ​kubectl run​​: 用于创建一个新的 Pod,并在该 Pod 中运行一个容器。它的主要目的是方便快速创建并启动容器。参数是容器名称、镜像名称等。
debug – 启动一个调试容器并将其连接到指定的 Pod 上。

使用 ​​kubectl debug node​​ 命令将 Pod 部署到要排查故障的节点上。

kubectl debug -n <namespace> <pod-name> --image=<debug-container-image>
  • ​<namespace>​​ 是目标 Pod 所在的命名空间。
  • ​<pod-name>​​ 是你要调试的 Pod 的名称。
  • ​<debug-container-image>​​ 是用于调试的容器镜像的名称。
exec – 进入容器查看

与docker的exec用法相似,如果一个pod中,有多个容器,需要使用-c选项指定容器。命令格式如下:

kubectl exec POD [-c CONTAINER] -- COMMAND [args...]

例如:

1)打开一个 shell 访问名为nginx的pod中容器(只有一个容器)

kubectl exec -it nginx -- /bin/bash

2)打开一个 shell 访问名为nginxtest2的pod中容器nginx1

kubectl exec -it nginxtest2 -c nginx1 -- /bin/bash

3)在普通的命令窗口(而不是 shell)中,打印pod资源对象nginx中容器/目录下的文件名

kubectl exec nginx -- ls /

部署管理
patch – 修改资源

参见2.5节

rollout - 回滚操作

回滚操作。命令格式如下:

kubectl rollout SUBCOMMAND

子命令:

history 查看历史版本

pause 暂停资源

resume 恢复暂停资源

status 查看资源状态

undo 回滚版本

例如:

1)回滚到之前的deployment

kubectl rollout undo deployment/abc

2)查看daemonset的状态

kubectl rollout status daemonset/foo

3)检查 Deployment 的历史记录,包括版本

kubectl rollout history deployment/frontend

Pod的滚动更新及回滚可以实际操作可以看:https://zhuanlan.zhihu.com/p/90282741

扩缩容
scale - 对资源进行伸缩

对资源进行伸缩,扩容或缩容 Deployment、ReplicaSet、Replication Controller或 Job 中Pod数量。命令格式如下:

kubectl scale [--rekubectl source-versinotallow=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)

各个选项和参数的作用如下:

  • ​--rekubectl source-versinotallow=version​​:可选参数,用于在扩展或缩减操作中指定资源的版本。通常不需要手动设置这个选项,Kubernetes 会自动处理版本信息。
  • ​--current-replicas=count​​:可选参数,用于指定当前副本数量。这个选项通常也不需要手动设置,Kubernetes 会自动获取当前副本数量。
  • ​--replicas=COUNT​​:必需参数,用于指定要设置的新副本数量。
  • ​-f FILENAME​​:使用文件来指定要扩展或缩减的资源对象。FILENAME 是资源配置文件的路径。
  • ​TYPE NAME​​:使用资源类型和名称来指定要扩展或缩减的资源对象。

例如:

1)将名为foo中的pod副本数设置为3。

kubectl scale --replicas=3 rs/foo
//rs/foo 副本名称

2)将由“foo.yaml”配置文件中指定的资源对象和名称标识的Pod资源副本设为3。

kubectl scale --replicas=3 -f foo.yaml

3)如果当前副本数为2,则将其扩展至3。

kubectl scale --current-replicas=2 --replicas=3 deployment/mysql

4)设置多个RC中Pod副本数量。

同时扩展三个不同的 ReplicationController (RC),分别是 ​​rc/foo​​​、​​rc/bar​​​ 和 ​​rc/baz​​,将它们的副本数量都设置为 5。

kubectl scale --replicas=5 rc/foo rc/bar rc/baz

要检查 RC 的副本数量是否已经更新为 5,可以使用以下命令:

kubectl get rc/foo rc/bar rc/baz
集群管理命令
cordon

有时候会遇到这样一个场景,一个node需要升级,但是在该node上又有许多运行的pod,或者该node已经瘫痪,需要保证功能的完善,则需要使用这组命令,使用步骤如下:

使用cordon(关闭)命令将一个node标记为不可调度。这意味着新的pod将不会被调度到该node上。

kubectl cordon <nodename>
drain

使用drain(优雅的终止pod)命令,将运行在该node上运行的pod平滑的搬迁到其他节点上。

kubectl drain <nodename> --force --ignore-daemonsets --delete-local-data

#通常,​​drain​​​ 操作会在尝试迁移 Pod 时检查是否存在未完成的 Pod,如果有未完成的 Pod,则操作将失败。使用 ​​--force​​ 选项可以绕过这些检查, --force 直接删除不由workload对象(Deployment、Job等)管理的pod

#--ignore-daemonsets 忽略daemonset部署的pod,也会尝试将它们迁移到其他节点。通常情况下,​​drain​​ 操作会跳过 DaemonSet 控制器,因为它们被设计为在每个节点上运行。 # --delete-local-data 操作删除节点上的本地数据

uncordon

对该节点进行一些节点维护的操作,如升级内核、升级Docker等。

节点维护完后,使用uncordon(开启)命令解锁该node,使其重新变得可调度。

kubectl uncordon <nodename>

其他命令

api-versions – 打印受支持的API版本

打印受支持的API版本。

kubectl api-versions
api-resources – 打印支持的API资源

打印支持的API资源。

kubectl api-resources
help – 所有命令帮助

所有命令帮助。

kubectl help
version – 打印客户端和服务版本信息

打印客户端和服务版本信息。

kubectl version
config – 维护存储在本地的配置文件。

1)显示合并的 kubeconfig 配置。

kubectl config view

显示 配置文件 (​​~/.kube/config​​)

2)获取e2e用户密码。

kubectl config view -o jsnotallow='{.users[?(@.name == "e2e")].user.password}'

3)显示第一个用户

kubectl config view -o jsnotallow='{.users[].name}'

参考资料

  1. 华为CCE文档中的kubectl常用命令:https://support.huaweicloud.com/usermanual-cce/cce_01_0139.html
  2. K8S官方提供的kubectl命令大全:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
  3. 中文的k8S命令大全:https://kubernetes.io/zh-cn/docs/reference/kubectl/
  4. ​Docker 用户过渡到 kubectl 命令行指南 · Kubernetes 中文指南——云原生应用架构实战手册​
  5. ​mp.weixin.qq.com​​(pod的内部实现)
  6. ​Kubernetes Service _ Kubernetes(K8S)中文文档_Kubernetes中文社区​​(k8s中文文档)
  7. ​搜索结果 kube-proxy_Kubernetes中文社区​​(k8s中文社区)
  8. ​扁平网络 Flannel · Kubernetes 中文指南——云原生应用架构实战手册​
  9. ​cloud.tencent.com​
  10. ​Kubernetes kubectl set image 命令详解 _ Kubernetes(K8S)中文文档_Kubernetes中文社区​​(kubectl命令的详述)
  11. ​https://cloud.tencent.com/developer/article/1552128(k8s网络的,可参考)​
  12. ​https://cloud.tencent.com/developer/article/2139344(k8s存储,四个类型)​

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐