Skip to content

Kubernetes(v1.21)基础入门

第一章:Kubernetes 集群架构

1646968626787-0ce64f2a-3098-4931-b706-5a1d4a03fa30.png

  • Docker 是每一个节点(包括 Master 节点和 Node 节点)的运行时环境。
  • kubelet 负责控制所有容器的启动和停止等,保证每个节点(包括 Master 节点和 Node 节点)正常工作,并且帮助 Node 节点和 Master 节点进行交互。
  • Master 节点的关键组件:
    • kubelet(监工):所有节点必备的。控制当前节点所有 Pod 的生命周期以及与 api-server 交互等工作。
    • kube-api-server:负责接收所有请求。集群内对集群的任何修改都是通过命令行、UI 将请求发给 api-server 才能执行的。api-server 是整个集群操作对内、对外的唯一入口,不包含我们后来部署应用暴露端口的方式。
    • kube-proxy:整个节点的网络流量负责。
    • cri:容器运行时环境(如:Docker 、Podman 等)。
    • ……
  • Node 节点的关键组件:
    • kubelet(监工):所有节点必备的。控制当前节点所有 Pod 的生命周期以及与 api-server 交互等工作。
    • kube-proxy:整个节点的网络流量负责。
    • cri:容器运行时环境(如:Docker 、Podman 等)。

第二章:资源管理方式

2.1 概述

  • ① 命令式对象管理:直接通过命令去操作 Kubernetes 的资源。
kubectl run nginx-pod --image=nginx:1.17.1 --port=80
  • ② 命令式对象配置:通过命令配置和配置文件去操作 Kubernetes 的资源。
kubectl create/patch/delete -f nginx-pod.yaml
  • ③ 声明式对象配置:通过 apply 命令和配置文件去操作 Kubernetes 的资源。
kubectl apply -f nginx-pod.yaml
  • 总结:
类型 操作 适用场景 优点 缺点
命令式对象管理 对象 测试 简单 只能操作活动对象,无法审计、跟踪
命令式对象配置 文件 开发 可以审计、跟踪 项目大的时候,配置文件多,操作麻烦
声明式对象配置 目录 开发 支持目录操作 意外情况下难以调试

2.2 命令式对象管理

2.2.1 kubectl 命令

  • kubectl 是 Kubernetes 集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装和部署。
  • kubectl 命令的语法如下:
kubectl [command] [type] [name] [flags]
  • 参数:
    • command:指定要对资源执行的操作,如:create、get 、delete 等。
    • type:指定资源的类型,如:deployment 、pod 、service 等。
    • name:指定资源的名称,名称大小写敏感。
    • flags:指定额外的可选参数。

1646968634587-172f0ecc-b3f7-4436-8e71-74f53b44563b.gif

  • 示例:查看所有的 Pod
kubectl get pod

1646968648969-e8008871-c12b-4bf5-a11a-79567a6b77a7.gif

  • 示例:以 yaml 格式查看某个 Pod
kubectl get pod xxx -o yaml

1646968654098-792f2d07-2ed8-4d6e-8ab7-5ea925d4dbc3.gif

2.2.2 操作(command)

  • Kubernetes 允许对资源进行多种操作,可以通过 --help 查看详细的操作命令:
kubectl --help

1646968659397-463f0e44-e76d-4fce-874f-75c375f41dde.gif

  • 经常使用的操作如下所示:
  • ① 基本命令:
命令 翻译 命令作用
create 创建 创建一个资源
edit 编辑 编辑一个资源
get 获取 获取一个资源
patch 更新 更新一个资源
delete 删除 删除一个资源
explain 解释 展示资源文档
  • ② 运行和调试:
命令 翻译 命令作用
run 运行 在集群中运行一个指定的镜像
expose 暴露 暴露资源为 Service
describe 描述 显示资源内部信息
logs 日志 输出容器在 Pod 中的日志
attach 缠绕 进入运行中的容器
exec 执行 执行容器中的一个命令
cp 复制 在 Pod 内外复制文件
rollout 首次展示 管理资源的发布
scale 规模 扩(缩)容 Pod 的数量
autoscale 自动调整 自动调整 Pod 的数量
  • ③ 高级命令:
命令 翻译 命令作用
apply 应用 通过文件对资源进行配置
label 标签 更新资源上的标签
  • ④ 其他命令:
命令 翻译 命令作用
cluster-info 集群信息 显示集群信息
version 版本 显示当前 Client 和 Server 的版本

2.2.3 资源类型(type)

  • Kubernetes 中所有的内容都抽象为资源,可以通过下面的命令进行查看:
kubectl api-resources

1646968670878-56d36034-7f42-45b3-819e-cc21335fc11d.gif

  • 经常使用的资源如下所示:
  • ① 集群级别资源:
资源名称 缩写 资源作用
nodes no 集群组成部分
namespaces ns 隔离 Pod
  • ② Pod资源:
资源名称 缩写 资源作用
Pods po 装载容器
  • ③ Pod资源控制器:
资源名称 缩写 资源作用
replicationcontrollers rc 控制 Pod 资源
replicasets rs 控制 Pod 资源
deployments deploy 控制 Pod 资源
daemonsets ds 控制 Pod 资源
jobs 控制 Pod 资源
cronjobs cj 控制 Pod 资源
horizontalpodautoscalers hpa 控制 Pod 资源
statefulsets sts 控制 Pod 资源
  • ④ 服务发现资源:
资源名称 缩写 资源作用
services svc 统一 Pod 对外接口
ingress ing 统一 Pod 对外接口
  • ⑤ 存储资源:
资源名称 缩写 资源作用
volumeattachments 存储
persistentvolumes pv 存储
persistentvolumeclaims pvc 存储
  • ⑥ 配置资源:
资源名称 缩写 资源作用
configmaps cm 配置
secrets 配置
  • 示例:查询命名空间
kubectl get ns

1646968677252-4e46bdf6-e3e2-40af-b3aa-3584dfa997e6.gif

  • 示例:创建命名空间
kubectl create ns dev

1646968684221-140df658-7adc-4f55-aba7-d7a823ed2997.gif

  • 示例:删除命名空间
kubectl delete ns dev

1646968688843-6c8a255a-2bbf-49c2-ad7d-b410e480771c.gif

2.3 命令式对象配置

  • 命令式对象配置就是通过命令配置和配置文件去操作 Kubernetes 的资源。
  • 命令式对象配置的方式操作资源,可以简单的认为:命令 + yaml 配置文件(里面是命令需要的各种参数)。

  • 示例:

  • ① 创建一个 nginxpod.yaml 文件,内容如下:
apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: Pod
metadata:
  name: nginxpod
  namespace: dev
spec:
  containers:
    - name: nginx-containers
      image: nginx:1.17.1
  • ② 执行 create 命令,创建资源:
kubectl create -f nginxpod.yaml
  • ③ 执行 get 命令,查看资源:
kubectl get -f nginxpod.yaml
  • ④ 执行 delete 命令,删除资源:
kubectl delete -f nginxpod.yaml

1646968705475-4aef3924-35f1-4268-bba7-9db2c5777296.gif

2.4 声明式对象配置

  • 声明式对象配置:通过 apply 命令和配置文件去操作 Kubernetes 的资源。
  • 声明式对象配置和命令式对象配置类似,只不过它只有一个 apply 命令。
  • apply 命令相当于 create 命令和 patch 命令。

  • 示例:

  • ① 创建一个 nginxpod.yaml 文件,内容如下:
apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: Pod
metadata:
  name: nginxpod
  namespace: dev
spec:
  containers:
    - name: nginx-containers
      image: nginx:1.17.1
  • ② 执行 apply 命令:
kubectl apply -f nginxpod.yaml

1646968717444-888cca72-0dfe-4c1e-b892-c3f0f3d49fd6.gif

2.5 总结

  • 创建和更新资源使用声明式对象配置:kubectl apply -f xxx.yaml。
  • 删除资源使用命令式对象配置:kubectl delete -f xxx.yaml。
  • 查询资源使用命令式对象管理:kubectl get(describe) 资源名称。

2.6 故障排除(必须记住)

2.6.1 显示资源列表

  • 命令:
kubectl get 资源类型
  • 示例:获取类型为 Deployment 的资源列表
kubectl get deployment

1646968732164-6103dc21-0fde-4121-9780-dfe7c46faef5.gif

  • 示例:获取类型为 Pod 的资源列表
kubectl get pod

1646968739495-65ddbe0b-affe-4a6d-ba0a-f5bafda7a44a.gif

  • 示例:获取类型为 Node 的资源列表
kubectl get node

1646968744697-de9b4004-6261-46bb-9cda-18190ffffc21.gif

  • 示例:显示所有名称空间下的 Deployment
kubectl get deployment -A
kubectl get deployment --all-namespaces

1646968749466-90ce4e6a-1872-4780-a2bd-6f0c41c3e05a.gif

  • 示例:查看 kube-system 名称空间下的 Deployment
kubectl get deployment -n kube-system

1646968755117-4251cb97-67a9-4f2d-b28e-220bc61763a9.gif

  • 示例:查看在名称空间下的资源对象
kubectl api-resources --namespaced=true

1646968759785-203a61d0-3cea-4e2a-8233-cc304e9dadcb.gif

  • 示例:查询不在名称空间下的资源对象(理解:就是受 Kubernetes 集群统一调度,而不受到具体名称空间的约束)
kubectl api-resources --namespaced=false

1646968765038-e27dd254-19ef-4c2c-bcc3-b2d5a04a365a.gif

2.6.2 显示有关资源的详细信息

  • 命令:
kubectl describe 资源类型 资源名称
  • 示例:查询名称为 nginx-pod 的 Pod 的信息
kubectl describe pod nginx-pod

1646968770311-15590843-f52d-446d-8aec-9efa12b48afb.gif

  • 示例:显示名称为 nginx 的 Deployment 的信息
kubectl describe deployment nginx

1646968774647-949bfb5d-685c-4c4c-b64a-5cf49f3ef923.gif

2.6.3 查询 Pod 中的容器的打印日志

  • 命令:类似于 Docker 的 docker logs -f xxx
kubectl logs -f Pod名称
  • 示例:查询名称为 nginx-pod 的 Pod 日志
kubectl logs -f nginx-pod

1646968788797-b3a12c69-df0d-4c26-a7ad-f58cd5b1fe87.gif

2.6.4 在 Pod 中的容器环境内执行命令

  • 命令:类似于 Docker 的 docker exec -it xxx /bin/bash
kubectl exec -it xxx -- /bin/bash
  • 示例:在名称为 nginx-pod 的容器中执行命令
kubectl exec -it nginx-pod -- /bin/bash

1646968794506-a978078b-9ea7-4a2d-aafe-28d822c030bb.gif

第三章:部署(Deployment)一个应用

1646968804586-b6ae2890-bbb1-46ab-8000-0bd7a4b86e35.png

  • 在 Kubernetes 中,通过创建 Deployment ,可以创建应用程序(如同 Docker 的 image)的实例(如同 Docker 的容器),这个实例被包含在 Pod 的概念中,Pod 是 Kubernetes 中的最小管理单元。
  • 在 Kubernetes 集群中创建 Deployment 之后,Deployment 将指示 Kubernetes 集群如何创建和更新应用程序的实例,Master 节点将应用程序实例调度到集群中的具体的节点上。
  • 创建应用程序实例之后,Kubernetes 的 Deployment Controller 将会持续监控这些实例。如果运行这些实例的 Node 节点关机或者被删除,则 Kubernetes 的 Deployment Controller 将在集群中的资源最优的另一个 Node 节点上重新创建一个新的实例,这就提供了一种 自我修复机制 来解决机器故障或维护问题。
  • 在容器编排之前的时代,各种安装脚本通常用于启动应用程序,但是却不能使得应用程序从机器故障中恢复。通过创建应用程序实例并确保它们在集群节点中的运行实例个数,Kubernetes 的 Deployment 提供了一种完全不同的方式来管理应用程序。
  • 语法(命令式):
kubectl create deployment 部署的名称 --image=镜像名称 --replicas=部署的副本数量 --port=容器暴露的端口
  • 示例:
kubectl create deployment my-nginx --image=nginx --replicas=3 --port=80

1646968810629-d6a1ee5b-0134-4a8c-b124-ba3614fbac0e.gif

  • 原理:

1646968816449-ae7ac2f9-22f0-46d6-a43a-369f9ad54401.png

第四章:应用程序探索

4.1 概述

  • 创建 Deployment 之后,Kubernetes 会创建一个 Pod(容器组)来放置应用程序实例(container 容器)。

1646968823395-797d4d00-5e9c-4bce-aa85-3f0bb8e91d56.png

4.2 Pod

  • Pod(容器组)是一个 Kubernetes 中的一个抽象概念,用于存放一组 Container(可以包含一个或多个 Container 容器,如:上图中的小正方体)以及这些 Container(容器)的一些共享资源。这些资源包括:
    • 共享存储,称为卷(Volume),如:上图中的紫色圆柱体。
    • 网络,每个 Pod(容器组)在集群中有一个唯一的 IP,Pod(容器组)中的 Container(容器)共享该 IP 地址。
    • Container(容器)的基本信息,如:容器的镜像版本、对外暴露的端口等。
  • Pod(容器组)是 Kubernetes 集群上的最基本的单元。当我们在 Kubernetes 集群上创建 Deployment 的时候,会在 Kubernetes  集群上创建包含容器的 Pod (而不是直接创建容器)。每个 Pod 都和运行它的 Node 节点绑定,并保持在哪里直到终止或被删除。如果 Node 节点发生了故障,则会在集群中的其他可用的 Node 节点上运行相同的 Pod(从同样的镜像创建 Container,使用同样的配置,IP 地址不同,Pod 名称不同)。

温馨提示:

  • Pod 是一组容器(可包含一个或多个应用程序容器),以及共享存储(卷 Volumes)、IP 地址和有关如何运行容器的信息。
  • 如果多个容器紧密耦合并且需要共享磁盘等资源,则他们应该被部署在同一个Pod(容器组)中。

4.3 Node

1646968830403-b4f1899e-d24b-43db-acf2-002f7eaba1aa.png

  • Pod(容器组)总是在 Node(节点)上运行。Node(节点)是 Kubernetes 集群中的计算机,可以是虚拟机或物理机。每个 Node(节点)都由 Master 管理。一个 Node(节点)可以有多个Pod(容器组),kubernetes 的 Master 会根据每个 Node(节点)上可用资源的情况,自动调度 Pod(容器组)到最佳的 Node(节点)上。
  • 每个 Kubernetes 的 Node(节点)至少运行:
    • Kubelet,负责 Master节点和 Node 节点之间通信的进程;管理 Pod(容器组)和 Pod(容器组)内运行的 Container(容器)。
    • kube-proxy,负责进行流量转发。
    • 容器运行环境(如:Docker)负责下载镜像、创建和运行容器等。

第五章:应用程序外部可见(Service)

5.1 概述

  • Kubernetes 中的 Pod 是转瞬即逝,Pod 有自己的 生命周期 ,当一个工作的 Node 挂掉后,在 Node 上运行的 Pod 也会随之消亡。Deployment(Deployment 其实是驱动 ReplicaSet) 会自动的创建新的 Pod 驱动集群回到目标状态,以保证应用程序正常运行。
  • Kubernetes 的 Service 是一个抽象层,它定义了一组 Pod 的逻辑集,并为这些 Pod 支持外部流量暴露、负载均衡和服务发现。
  • Service 使从属 Pod 之间的松耦合成为可能。 和其他 Kubernetes 对象一样, Service 用 YAML (更推荐) 或者 JSON 来定义.。Service 下的一组 Pod 通常由 LabelSelector (请参阅下面的说明为什么您可能想要一个 spec 中不包含selector的服务)来标记。
  • 尽管每个 Pod 都有一个唯一的 IP 地址,但是如果没有 Service ,这些 IP 不会暴露在群集外部。Service 允许您的应用程序接收流量。Service 也可以用在 ServiceSpec 标记type的方式暴露。
    • ClusterIP(默认) :在集群的内部 IP 上公开 Service 。这种类型使得 Service 只能从集群内访问。
    • NodePort:使用 NAT 在集群中每个选定 Node 的相同端口上公开 Service 。使用<NodeIP>:<NodePort> 从集群外部访问 Service。是 ClusterIP 的超集。
    • LoadBalancer:在当前云中创建一个外部负载均衡器(如果支持的话),并为 Service 分配一个固定的外部 IP 。是 NodePort 的超集。
    • ExternalName:通过返回带有该名称的 CNAME 记录,使用任意名称(由 spec 中的externalName指定)公开 Service 。不使用代理。这种类型需要 kube-dns 的 v1.7 或更高版本。

5.2 Service 和 Label

1646968836856-449ebc81-eb30-4dcd-ac43-e989ccba984b.png

  • Service 通过一组 Pod 路由通信。Service 是一种抽象,它允许 Pod 死亡并在 Kubernetes 中复制,而不会影响应用程序。在依赖的 Pod (如:应用程序中的前端和后端组件)之间进行发现和路由是由 Kubernetes Service 处理的。
  • Service 匹配一组 Pod 是使用 标签(Label)和选择器(Selector), 它们是允许对 Kubernetes 中的对象进行逻辑操作的一种分组原语。标签( Label )是附加在对象上的键/值对,可以以多种方式使用:
    • 指定用于开发,测试和生产的对象。
    • 嵌入版本标签。
    • 使用 Label 将对象进行分类。

1646968842331-7b653651-75d6-4b5a-b4cc-e0a0b88b7211.png

  • 命令:
# --port:集群内访问 service 的端口 8912
# --target-port: pod容器的端口 80
kubectl expose deployment nginx --port=8912 --target-port=80 --type=NodePort

1646968847195-64397b53-507a-4e17-b864-8ff5c49c8161.gif

第六章:伸缩应用程序-扩缩容

  • 当创建了一个 Deployment,然后通过 Service 提供访问 Pod 的方式,但是当流量增加的时候,需要对应用程序进行伸缩操作以满足系统性能的需求。

1646968852239-b7476805-6333-4ced-9256-502036c1b43f.png

  • 命令:
kubectl scale --replicas=数量 deployment 部署名称
  • 示例:
kubectl scale --replicas=3 deployment nginx

1646968857442-526eb471-3871-4920-a210-5c420879ac62.gif

第七章:执行滚动升级

  • 滚动升级允许通过使用新的示例逐步更新 Pod 实例,从而实现 Deployment 更新,0 停机。
  • 与应用程序扩展类似,如果暴露了 Deployment,服务(Service)将在更新期间仅对可用的 pod 进行负载均衡,可用 Pod 是应用程序可用的实例。
  • 滚动更新允许以下操作:
    • ① 将应用程序从一个环境提升到另一个环境(通过容器镜像更新)。
    • ② 回滚到以前的版本。
    • ③ 持续集成和持续交付应用程序,无需停机。
  • 命令:
# 镜像升级 nginx:1.17 到 nginx:latest 
# --record 表示记录变更
kubectl set image deployment 应用部署名称 Pod中容器的名称=容器的镜像 --record
# 查看历史记录
kubectl rollout history deployment 应用部署名称
# 默认回滚到上一个版本
kubectl rollout undo deployment 应用部署名称
# 默认回滚到第一个版本
kubectl rollout undo deployment 应用部署名称 --to-revision=1
  • 示例:
watch -n 1 kubectl get deployment,pod
kubectl create deployment nginx-deploy --image=nginx:1.17 --replicas=3
kubectl set image deployment nginx-deploy nginx=nginx:1.18 --record
kubectl set image deployment nginx-deploy nginx=nginx:1.19 --record
kubectl set image deployment nginx-deploy nginx=nginx --record
kubectl rollout history deployment nginx-deploy
kubectl rollout undo deployment nginx-deploy --to-revision=1

1646968866350-e939a0fb-51dd-4e10-9009-ef27b40af1a0.gif

第八章:使用声明式对象配置模拟上述效果

8.1 部署一个 Deployment

  • 命令:
vim deployment.yaml
apiVersion: apps/v1 #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment    #该配置的类型,我们使用的是 Deployment
metadata:           #译名为元数据,即 Deployment 的一些基本属性和信息
  name: nginx-deployment    #Deployment 的名称
  labels:       #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: nginx  #为该Deployment设置key为app,value为nginx的标签
spec:           #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
  replicas: 1   #使用该Deployment创建一个应用程序实例
  selector:     #标签选择器,与上面的标签共同作用,目前不需要理解
    matchLabels: #选择包含标签app:nginx的资源
      app: nginx
  template:     #这是选择或创建的Pod的模板
    metadata:   #Pod的元数据
      labels:   #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:       #期望Pod实现的功能(即在pod中部署)
      containers:   #生成container,与docker中的container是同一种
      - name: nginx #container的名称
        image: nginx:1.17   #使用镜像nginx:1.17创建container,该container默认80端口可访问
kubectl apply -f deployment.yaml

1646968876409-8dead3e5-b3ef-452f-8c11-fadbfb174eb6.gif

8.2 暴露应用

  • 命令:
vim service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service   #Service 的名称
  labels:       #Service 自己的标签
    app: nginx  #为该 Service 设置 key 为 app,value 为 nginx 的标签
spec:       #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
  selector:     #标签选择器
    app: nginx  #选择包含标签 app:nginx 的 Pod
  ports:
  - name: nginx-port    #端口的名字
    protocol: TCP       #协议类型 TCP/UDP
    port: 80            #集群内的其他容器组可通过 80 端口访问 Service
    nodePort: 32600   #通过任意节点的 32600 端口访问 Service
    targetPort: 80  #将请求转发到匹配 Pod 的 80 端口
  type: NodePort    #Serive的类型,ClusterIP/NodePort/LoaderBalancer
kubectl apply -f service.yaml

1646968883382-e52dafe7-6901-4b57-aff3-14e44830d609.gif

第九章:安装 DashBoard

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml

1646968889179-1475a7bc-16ab-4de5-ba45-38f61dbd0b04.gif

  • 修改 yaml 文件:
vim recommended.yaml
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort # 新增
  ports:
  - port: 443
    targetPort: 8443
    nodePort: 30009 # 新增
selector:
    k8s-app: kubernetes-dashboard
kubectl apply -f recommended.yaml

1646968896437-fda3f839-c0c9-4f09-8163-251a8c6aee05.gif

  • 创建账户,并授权:
vim dash-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard
kubectl create -f dash-admin.yaml

1646968902319-60b26101-f3d1-4233-864d-a886beee2abf.gif

  • 令牌:
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
  • 访问地址:https://192.168.65.100:30009 。

1646968909000-87745505-50be-49ce-b284-bfb8f933a141.gif

更新: 2023-03-14 03:03:50
原文: https://www.yuque.com/fairy-era/yg511q/eu30ue

Comments