第一章:Kubernetes 集群架构
- 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:指定额外的可选参数。
- 示例:查看所有的 Pod
kubectl get pod
- 示例:以 yaml 格式查看某个 Pod
kubectl get pod xxx -o yaml
2.2.2 操作(command)
- Kubernetes 允许对资源进行多种操作,可以通过 —help 查看详细的操作命令:
kubectl --help
- 经常使用的操作如下所示:
- ① 基本命令: | 命令 | 翻译 | 命令作用 | | —- | —- | —- | | 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
- 经常使用的资源如下所示:
- ① 集群级别资源: | 资源名称 | 缩写 | 资源作用 | | —- | —- | —- | | 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
- 示例:创建命名空间
kubectl create ns dev
- 示例:删除命名空间
kubectl delete ns dev
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
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
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
- 示例:获取类型为 Pod 的资源列表
kubectl get pod
- 示例:获取类型为 Node 的资源列表
kubectl get node
- 示例:显示所有名称空间下的 Deployment
kubectl get deployment -A
kubectl get deployment --all-namespace
- 示例:查看 kube-system 名称空间下的 Deployment
kubectl get deployment -n kube-system
- 示例:查看在名称空间下的资源对象
kubectl api-resources --namespaced=true
- 示例:查询不在名称空间下的资源对象(理解:就是受 Kubernetes 集群统一调度,而不受到具体名称空间的约束)
kubectl api-resources --namespaced=false
2.6.2 显示有关资源的详细信息
- 命令:
kubectl describe 资源类型 资源名称
- 示例:查询名称为 nginx-pod 的 Pod 的信息
kubectl describe pod nginx-pod
- 示例:显示名称为 nginx 的 Deployment 的信息
kubectl describe deployment nginx
2.6.3 查询 Pod 中的容器的打印日志
- 命令:类似于 Docker 的
docker logs -f xxx
kubectl logs -f Pod名称
- 示例:查询名称为 nginx-pod 的 Pod 日志
kubectl logs -f nginx-pod
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
第三章:部署(Deployment)一个应用
- 在 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
- 原理:
第四章:应用程序探索
4.1 概述
- 创建 Deployment 之后,Kubernetes 会创建一个 Pod(容器组)来放置应用程序实例(container 容器)。
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
- 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
- Service 通过一组 Pod 路由通信。Service 是一种抽象,它允许 Pod 死亡并在 Kubernetes 中复制,而不会影响应用程序。在依赖的 Pod (如:应用程序中的前端和后端组件)之间进行发现和路由是由 Kubernetes Service 处理的。
- Service 匹配一组 Pod 是使用 标签(Label)和选择器(Selector), 它们是允许对 Kubernetes 中的对象进行逻辑操作的一种分组原语。标签( Label )是附加在对象上的键/值对,可以以多种方式使用:
- 指定用于开发,测试和生产的对象。
- 嵌入版本标签。
- 使用 Label 将对象进行分类。
- 命令:
# --port:集群内访问 service 的端口 8912
# --target-port: pod容器的端口 80
kubectl expose deployment nginx --port=8912 --target-port=80 --type=NodePort
第六章:伸缩应用程序-扩缩容
- 当创建了一个 Deployment,然通过 Service 提供访问 Pod 的方式,但是当流量增加的时候,需要对应用程序进行伸缩操作以满足系统性能的需求。
- 命令:
kubectl scale --replicas=数量 deployment 部署名称
- 示例:
kubectl scale --replicas=3 deployment nginx
第七章:执行滚动升级
- 滚动升级允许通过使用新的示例逐步更新 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
第八章:使用声明式对象配置模拟上述效果
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
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
第九章:安装 DashBoard
- 下载 yaml 文件(网速不行,请点这里recommended.yaml):
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml
- 修改 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
- 创建账户,并授权:
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
- 令牌:
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
- 访问地址:https://192.168.65.100:30009 。