目录

  1. 1. 前言
  2. 2. 基础
    1. 2.1. 组件
    2. 2.2. 对象
    3. 2.3. Pod
      1. 2.3.1. Pod 模板
      2. 2.3.2. Pod 更新与替换
      3. 2.3.3. Pod 存储
      4. 2.3.4. Pod 联网
  3. 3. 环境搭建
    1. 3.1. Kind 搭建
    2. 3.2. 配置 kubectl
  4. 4. kubectl 命令行工具
    1. 4.1. 查看和查找资源
  5. 5. 部署应用
↑

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

Kubernetes

2026/2/10 DevOps
  |     |   总文章阅读量:次

前言

参考:

https://github.com/bfengj/Cloud-Security/blob/main/Kubernetes/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86.md

https://cn.kubeblocks.io/docs/preview/user-docs/installation/prepare-a-local-k8s-cluster/

https://zhuanlan.zhihu.com/p/8518707020

https://kubernetes.io/zh-cn/docs/reference/kubectl/quick-reference/


基础

Kubernetes 又称 k8s,是 Google 在 2014 年开源的一个用来管理容器的平台

是一个用于自动化部署、扩展和管理容器化应用程序的开源系统

组件

k8s 主要由以下核心组件组成:

  • etcd 保存了整个集群的状态,k8s 的配置信息存储于此处
  • API Server 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制
  • Controller Manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
  • Scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上
  • Kubelet 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理
  • Container Runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI)
  • Kube-proxy 负责为 Service 提供 Cluster 内部的服务发现和负载均衡

一个 k8s 集群包含两种类型的资源:

  • 控制面(Control Plane)调度整个集群,其中的组件包括 apiserver、etcd、scheduler、controller manager
  • 节点(Nodes)负责运行应用,其中的组件包括 kubelet(负责 master 节点和 worker 节点之间通信的进程;管理 Pod 和 Pod 内运行的 Container)、kube-proxy、container runtime

对象

k8s 对象是 k8s 系统中的持久性实体,k8s 使用这些实体表示集群状态:

  • 哪些容器化应用正在运行(以及在哪些节点上运行)
  • 可以被应用使用的资源
  • 关于应用运行时行为的策略,比如重启策略、升级策略以及容错策略

操作 k8s 对象需要使用 Kubernetes API,使用 kubectl 时 cli 就会调用相应的 api

几乎每个 k8s 对象包含两个负责管理对象配置的字段:spec 对象规约与 status 状态

创建 k8s 对象时,必须提供对象的 spec,用来描述该对象的期望状态,以及关于对象的一些基本信息,一般通过 yaml 清单转换为 json 为 kubectl 提供信息

demo:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 帮助唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 你所期望的该对象的状态,该字段格式参考 Kubernetes API

Pod

Pod 是可在 k8s 中创建和管理的、最小的可部署的计算单元,一个 Node 节点可以有多个 Pod

Pod 内部是一组容器,k8s 通过操作 Pod 来操作容器,这些容器共享存储、网络以及运行容器的规约。

Pod 中的内容在共享的上下文中运行,包含一组 Linux 命名空间、控制组(cgroup)和一些可能的隔离方面,即采用隔离容器的技术,类似于共享命名空间与文件系统的一组容器

Pod 的用法:

  • 运行单个容器的 Pod,可以将 Pod 看作单个容器的包装器
  • 多个容器协同工作的 Pod

demo:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Pod 模板

工作负载资源的控制器通常使用 Pod 模板(Pod Template) 来替你创建 Pod 并管理它们

Pod 模板是包含在工作负载对象中的规范,用来创建 Pod。这类负载资源包括 Deployment、 Job 和 DaemonSet 等。

工作负载的控制器会使用负载对象中的 PodTemplate 来生成实际的 Pod。 PodTemplate 是你用来运行应用时指定的负载资源的目标状态的一部分。

创建 Pod 时,可以在 Pod 模板中包含 Pod 中运行的容器的环境变量。

demo:template 指示启动一个容器。该 Pod 中的容器会打印一条消息之后暂停

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # 这里是 Pod 模板
    spec:
      containers:
      - name: hello
        image: busybox:1.28
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure
    # 以上为 Pod 模板

Pod 更新与替换

  • Pod 的绝大多数元数据都是不可变的。例如,你不可以改变其 namespace、name、 uid 或者 creationTimestamp 字段。
  • 如果 metadata.deletionTimestamp 已经被设置,则不可以向 metadata.finalizers 列表中添加新的条目。
  • Pod 更新不可以改变除 spec.initContainers[*].image、spec.activeDeadlineSeconds、 spec.terminationGracePeriodSeconds、spec.tolerations 或 spec.schedulingGates 之外的字段。对于 spec.tolerations,你只被允许添加新的条目到其中。
  • 在更新 spec.activeDeadlineSeconds 字段时,以下两种更新操作是被允许的:
    1. 如果该字段尚未设置,可以将其设置为一个正数;
    2. 如果该字段已经设置为一个正数,可以将其设置为一个更小的、非负的整数。

Pod 存储

一个 Pod 可以设置一组共享的存储卷。 Pod 中的所有容器都可以访问该共享卷,从而允许这些容器共享数据。卷还允许 Pod 中的持久数据保留下来,即使其中的容器需要重新启动。

Pod 联网

每个 Pod 都在每个地址族中获得一个唯一的 IP 地址。 Pod 中的每个容器共享网络名字空间,包括 IP 地址和网络端口。 Pod 内的容器可以使用 localhost 互相通信。当 Pod 中的容器与 Pod 之外的实体通信时,它们必须协调如何使用共享的网络资源(例如端口)。

在同一个 Pod 内,所有容器共享一个 IP 地址和端口空间,并且可以通过 localhost 发现对方。 他们也能通过如 SystemV 信号量或 POSIX 共享内存这类标准的进程间通信方式互相通信。 不同 Pod 中的容器的 IP 地址互不相同,如果没有特殊配置,就无法通过 OS 级 IPC 进行通信。 如果某容器希望与运行于其他 Pod 中的容器通信,可以通过 IP 联网的方式实现。

Pod 中的容器所看到的系统主机名与为 Pod 配置的 name 属性值相同。


环境搭建

主机是 MacOS

前置工具:Docker、kubectl(命令行工具)

有三种轻量级工具可以本地创建 k8s 集群:

  • Minikube:Minikube 支持在本地机器的虚拟机或容器中运行单节点的 Kubernetes 集群
  • K3d:k3d 是一个轻量级工具,它在 Docker 容器中运行 k3s(一个轻量的 Kubernetes 发行版)
  • Kind:Kind 是 Kubernetes IN Docker 的缩写。它在 Docker 容器中运行 Kubernetes 集群,非常适合在本地进行 Kubernetes 测试

Kind 搭建

那我们选择使用 Kind 进行搭建

brew install kind

通过 Kind 创建 k8s 集群:

kind create cluster --name mykindcluster

该命令将创建一个单节点的 k8s 集群,运行在 Docker 容器中

检查集群是否启动

kubectl get nodes

如果要配置多节点集群,则可以通过配置文件:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  role: control-plane
  role: worker
  role: worker
kind create cluster --name multinode-cluster --config kind-config.yaml

删除集群

kind delete cluster --name mykindcluster

配置 kubectl

为了使 kubectl 能够管理 Kind 集群,需要将 Kind 集群的配置添加到 kubectl 的配置文件中:

kind get kubeconfig > ~/.kube/config

kubectl version 查看 kubectl 是否配置成功


kubectl 命令行工具

先配置一下自动补全

brew install bash-completion
source <(kubectl completion zsh)  # 在 zsh 中设置当前 shell 的自动补全
echo '[[ $commands[kubectl] ]] && source <(kubectl completion zsh)' >> ~/.zshrc # 在你的 zsh shell 中永久地添加自动补全

然后再开始学习使用 kubectl

kubectl 命令的常见格式是:kubectl action resource,这会对指定的资源(如 node 或 deployment)执行指定的操作(如 create、describe 或 delete)

查看和查找资源

# get 命令的基本输出
kubectl get services                          # 列出当前命名空间下的所有 Service
kubectl get pods --all-namespaces             # 列出所有命名空间下的全部的 Pod
kubectl get pods -o wide                      # 列出当前命名空间下的全部 Pod 并显示更详细的信息
kubectl get deployment my-dep                 # 列出某个特定的 Deployment
kubectl get pods                              # 列出当前命名空间下的全部 Pod
kubectl get pod my-pod -o yaml                # 获取一个 Pod 的 YAML

部署应用

创建一个简单的 nginx 部署

kubectl create deployment nginx --image=nginx

这个过程中执行了以下操作:

  • 搜索应用实例可以运行的合适节点(我们只有一个可用的节点)
  • 调度应用在此节点上运行
  • 配置集群在需要时将实例重新调度到新的节点上

在 Kubernetes 内运行的 Pod 运行在一个私有的、隔离的网络上。 默认这些 Pod 可以从同一 Kubernetes 集群内的其他 Pod 和服务看到,但超出这个网络后则看不到。 当我们使用 kubectl 时,我们通过 API 端点交互与应用进行通信。

kubectl proxy 命令可以创建一个代理,将通信转发到集群范围的私有网络

现在我们在主机(终端)和 Kubernetes 集群之间有一个连接。此代理能够从这些终端直接访问 API,可以直接访问 8001 端口查看 API

创建一个服务来暴露 nginx

kubectl expose deployment nginx --type=LoadBalancer --port=80

由于 kind 是把 node 运行在 docker 里的,因此即使在 k8s 集群中使用 nodePort 方式将服务暴露出来,在宿主机上依旧无法访问,所以需要在 kind 启动集群时指定把某些端口映射出来

或者直接使用 kubectl 转发:

kubectl port-forward deployment/nginx 30080:80

编写 config 重新启动集群,注意 kind 会继承宿主机的环境变量,如果设置了 http_proxy 等为 127.0.0.1 的则需要 unset 再启动

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 80
    hostPort: 30080
  - containerPort: 443
    hostPort: 30443
kind create cluster --config kind-config.yaml
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --type=LoadBalancer --port=80