第一章:Kubernetes 集群架构

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

2.2 命令式对象管理

2.2.1 kubectl 命令

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

2.gif

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

3.gif

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

4.gif

2.2.2 操作(command)

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

5.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 中所有的内容都抽象为资源,可以通过下面的命令进行查看:
  1. kubectl api-resources

6.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 | | 配置 |
  • 示例:查询命名空间
  1. kubectl get ns

7.gif

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

8.gif

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

9.gif

2.3 命令式对象配置

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

  • 示例:

  • ① 创建一个 nginxpod.yaml 文件,内容如下:
  1. apiVersion: v1
  2. kind: Namespace
  3. metadata:
  4. name: dev
  5. ---
  6. apiVersion: v1
  7. kind: Pod
  8. metadata:
  9. name: nginxpod
  10. namespace: dev
  11. spec:
  12. containers:
  13. - name: nginx-containers
  14. image: nginx:1.17.1
  • ② 执行 create 命令,创建资源:
  1. kubectl create -f nginxpod.yaml
  • ③ 执行 get 命令,查看资源:
  1. kubectl get -f nginxpod.yaml
  • ④ 执行 delete 命令,删除资源:
  1. kubectl delete -f nginxpod.yaml

10.gif

2.4 声明式对象配置

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

  • 示例:

  • ① 创建一个 nginxpod.yaml 文件,内容如下:
  1. apiVersion: v1
  2. kind: Namespace
  3. metadata:
  4. name: dev
  5. ---
  6. apiVersion: v1
  7. kind: Pod
  8. metadata:
  9. name: nginxpod
  10. namespace: dev
  11. spec:
  12. containers:
  13. - name: nginx-containers
  14. image: nginx:1.17.1
  • ② 执行 apply 命令:
  1. kubectl apply -f nginxpod.yaml

11.gif

2.5 总结

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

2.6 故障排除(必须记住)

2.6.1 显示资源列表

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

12.gif

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

13.gif

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

14.gif

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

15.gif

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

16.gif

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

17.gif

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

18.gif

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

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

19.gif

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

20.gif

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

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

21.gif

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

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

22.gif

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

23.png

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

24.gif

  • 原理:

25.png

第四章:应用程序探索

4.1 概述

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

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

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

28.png

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

29.png

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

30.gif

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

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

31.png

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

32.gif

第七章:执行滚动升级

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

33.gif

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

8.1 部署一个 Deployment

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

35.gif

8.2 暴露应用

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

36.gif

第九章:安装 DashBoard

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

37.gif

  • 修改 yaml 文件:
  1. vim recommended.yaml
  1. kind: Service
  2. apiVersion: v1
  3. metadata:
  4. labels:
  5. k8s-app: kubernetes-dashboard
  6. name: kubernetes-dashboard
  7. namespace: kubernetes-dashboard
  8. spec:
  9. type: NodePort # 新增
  10. ports:
  11. - port: 443
  12. targetPort: 8443
  13. nodePort: 30009 # 新增
  14. selector:
  15. k8s-app: kubernetes-dashboard
  1. kubectl apply -f recommended.yaml

38.gif

  • 创建账户,并授权:
  1. vim dash-admin.yaml
  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRoleBinding
  3. metadata:
  4. name: kubernetes-dashboard
  5. namespace: kubernetes-dashboard
  6. roleRef:
  7. apiGroup: rbac.authorization.k8s.io
  8. kind: ClusterRole
  9. name: cluster-admin
  10. subjects:
  11. - kind: ServiceAccount
  12. name: kubernetes-dashboard
  13. namespace: kubernetes-dashboard
  1. kubectl create -f dash-admin.yaml

39.gif

  • 令牌:
  1. kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

40.gif