Kubernetes快速实战与核心原理
Kubernetes快速实战与核心原理
1. K8S 概览
1.1 K8S 是什么
K8S官网文档**:**https://kubernetes.io/zh/docs/home/
K8S 是Kubernetes的全称,源于希腊语,意为“舵手”或“飞行员”。Kubernetes 是用于自动部署、扩缩和管理容器化应用程序的开源系统。 Kubernetes 源自Google 15 年生产环境的运维经验,同时凝聚了社区的最佳创意和实践。
Docker:作为开源的应用容器引擎,可以把应用程序和其相关依赖打包生成一个 Image 镜像文件,是一个标准的运行环境,提供可持续交付的能力;
Kubernetes:作为开源的容器编排引擎,用来对容器化应用进行自动化部署、 扩缩和管理;
1.2 K8S核心特性
- 服务发现与负载均衡:无需修改你的应用程序即可使用陌生的服务发现机制。
- 存储编排:自动挂载所选存储系统,包括本地存储。
- Secret和配置管理:部署更新Secrets和应用程序的配置时不必重新构建容器镜像,且不必将软件堆栈配置中的秘密信息暴露出来。
- 批量执行:除了服务之外,Kubernetes还可以管理你的批处理和CI工作负载,在期望时替换掉失效的容器。
- 水平扩缩:使用一个简单的命令、一个UI或基于CPU使用情况自动对应用程序进行扩缩。
- 自动化上线和回滚:Kubernetes会分步骤地将针对应用或其配置的更改上线,同时监视应用程序运行状况以确保你不会同时终止所有实例。
- 自动装箱:根据资源需求和其他约束自动放置容器,同时避免影响可用性。
- 自我修复:重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器。
1.3 K8S 核心架构
K8S 的核心功能:自动化运维管理多个容器化程序。K8S 的设计思想。首先看下图:

K8S 是属于Master-Worker架构,即有 Master 节点负责核心的调度、管理和运维,Worker 节点则执行用户的程序。但是在 K8S 中,主节点一般被称为Master Node ,而从节点则被称为Worker Node 或者 Node。
注意:Master Node 和 Worker Node 是分别安装了 K8S 的 Master 和 Woker 组件的实体服务器,每个 Node 都对应了一台实体服务器(虽然 Master Node 可以和其中一个 Worker Node 安装在同一台服务器,但是建议 Master Node 单独部署),所有 Master Node 和 Worker Node 组成了 K8S 集群,同一个集群可能存在多个 Master Node 和 Worker Node。
首先来看Master Node都有哪些组件:
- kube-apiserver。K8S 的请求入口服务。API Server 负责接收 K8S 所有请求(来自 UI 界面或者 CLI 命令行工具),然后,API Server 根据用户的具体请求,去通知其他组件干活。
- Scheduler。K8S 所有 Worker Node 的调度器。当用户要部署服务时,Scheduler 会选择最合适的 Worker Node(服务器)来部署。
- Controller Manager。K8S 所有 Worker Node 的监控器。Controller Manager 有很多具体的 Controller, Node Controller、Service Controller、Volume Controller 等。Controller 负责监控和调整在 Worker Node 上部署的服务的状态,比如用户要求 A 服务部署 2 个副本,那么当其中一个服务挂了的时候,Controller 会马上调整,让 Scheduler 再选择一个 Worker Node 重新部署服务。
- etcd。K8S 的存储服务。etcd 存储了 K8S 的关键配置和用户配置,K8S 中仅 API Server 才具备读写权限,其他组件必须通过 API Server 的接口才能读写数据。
接着来看Worker Node的组件:
- Kubelet。Worker Node 的监视器,以及与 Master Node 的通讯器。Kubelet 是 Master Node 安插在 Worker Node 上的“眼线”,它会定期向 Master Node 汇报自己 Node 上运行的服务的状态,并接受来自 Master Node 的指示采取调整措施。负责控制所有容器的启动停止,保证节点工作正常。
- Kube-Proxy。K8S 的网络代理。Kube-Proxy 负责 Node 在 K8S 的网络通讯、以及对外部网络流量的负载均衡。
- Container Runtime。Worker Node 的运行环境。即安装了容器化所需的软件环境确保容器化程序能够跑起来,比如 Docker Engine运行环境。
1.4 K8S集群安装
官方文档: https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
k8s v1.20.1 https://note.youdao.com/s/MignGqZj
k8s v1.24.3 https://docs.qq.com/doc/DUWRRQmZpeE1Sd1dC
k8s v1.27.1 https://note.youdao.com/s/Dxh3Qaaa
利用sealos快速安装kubernetes集群(Fox老师推荐): https://note.youdao.com/s/M2z4OzsL
2. 快速实战
2.1 kubectl命令使用
kubectl是apiserver的客户端工具,工作在命令行下,能够连接apiserver实现各种增删改查等操作 kubectl官方使用文档:https://kubernetes.io/zh/docs/reference/kubectl/overview/

2.2 Namespace
K8s 中,命名空间**(Namespace)** 提供一种机制,将同一集群中的资源划分为相互隔离的组。同一命名空间内的资源名称要唯一,命名空间是用来隔离资源的,不隔离网络。
Kubernetes 启动时会创建四个初始命名空间:
- default
Kubernetes 包含这个命名空间,以便于你无需创建新的命名空间即可开始使用新集群。
- kube-node-lease
该命名空间包含用于与各个节点关联的 Lease(租约)对象。 节点租约允许 kubelet 发送心跳, 由此控制面能够检测到节点故障。
- kube-public
所有的客户端(包括未经身份验证的客户端)都可以读取该命名空间。 该命名空间主要预留为集群使用,以便某些资源需要在整个集群中可见可读。 该命名空间的公共属性只是一种约定而非要求。
- kube-system
该命名空间用于 Kubernetes 系统创建的对象。
# 查看namespace
kubectl get namespace
#查看kube-system下的pod
kubectl get pods -n kube-system
#查看所有namespace下的pod
kubectl get pods -A
创建Namesapce示例
- 命令行方式
可以使用下面的命令创建Namespace:
kubectl create namespace tuling
- yaml方式
新建一个名为 my-namespace.yaml 的 YAML 文件,并写入下列内容:
apiVersion: v1
kind: Namespace
metadata:
name: tulingmall
然后运行:
kubectl apply -f my-namespace.yaml
删除namesapce
kubectl delete namespace tuling
kubectl delete -f my-namespace.yaml
2.3 Pod
Pod **是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。**Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个)容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。

创建Pod示例:运行一个NGINX容器
命令行方式
# 创建pod kubectl run mynginx --image=nginx:1.14.2
# 获取pod的信息,-owide 表示更详细的显示信息 -n 命名空间 查询对应namespace下的pod
kubectl get pod
kubectl get pod -owide
kubectl get pod -owide -n <namespace-name>
#查看pod的详情
kubectl describe pod <pod-name>
# 查看Pod的运行日志
kubectl logs <pod-name>
# 删除pod
kubectl delete pod <pod-name>
- yaml方式
kubectl apply -f nginx-pod.yaml
#vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: mynginx
name: mynginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
删除pod
kubectl delete -f nginx-pod.yaml
一个pod中可以运行多个容器
apiVersion: v1
kind: Pod
metadata:
labels:
run: myapp
name: myapp
spec:
containers:
- image: nginx:1.14.2
name: nginx
- image: tomcat:9.0.55
name: tomcat
2.4 Deployment
Deployment负责创建和更新应用程序的实例,使Pod拥有多副本,自愈,扩缩容等能力。创建Deployment后,Kubernetes Master 将应用程序实例调度到集群中的各个节点上。如果托管实例的节点关闭或被删除,Deployment控制器会将该实例替换为群集中另一个节点上的实例。这提供了一种自我修复机制来解决机器故障维护问题。

创建一个Tomcat应用程序
使用 kubectl create deployment 命令可以创建一个应用部署deployment与pod
#my-tomcat表示pod的名称 --image表示镜像的地址
kubectl create deployment my-tomcat --image=tomcat:9.0.55
#查看一下deployment的信息
kubectl get deployment
#删除deployment
kubectl delete deployment my-tomcat
#查看Pod打印的日志
kubectl logs my-tomcat-6d6b57c8c8-n5gm4
#使用 exec 可以在Pod的容器中执行命令
kubectl exec my-tomcat-6d6b57c8c8-n5gm4 -- env #使用 env 命令查看环境变量
kubectl exec my-tomcat-6d6b57c8c8-n5gm4 -- ls / # 查看容器的根目录下面内容
kubectl exec -it my-tomcat-6d6b57c8c8-n5gm4 -- sh #进入Pod容器内部并执行bash命令,如果想退出容器可以使用exit命令

自愈
#查看pod信息,-w意思是一直等待观察pod信息的变动
kubectl get pod -w
#开另外一个命令窗口执行如下命令,同时观察之前命令窗口的变化情况
kubectl delete pod my-tomcat-6d6b57c8c8-n5gm4
之前那个tomcat的pod被销毁,但是又重新启动了一个新的tomcat pod,这是k8s的服务自愈功能,

2.5 Service
Service是一个抽象层,它定义了一组Pod的逻辑集,并为这些Pod支持外部流量暴露、负载均衡和服务发现。
尽管每个Pod 都有一个唯一的IP地址,但是如果没有Service,这些IP不会暴露在群集外部。Service允许您的应用程序接收流量。Service也可以用在ServiceSpec标记type的方式暴露,type类型如下:
- ClusterIP(默认):在集群的内部IP上公开Service。这种类型使得Service只能从集群内访问。
- NodePort:使用NAT在集群中每个选定Node的相同端口上公开Service。使用 : 从集群外部访问Service。是ClusterIP的超集。
- LoadBalancer:在当前云中创建一个外部负载均衡器(如果支持的话),并为Service分配一个固定的外部IP。是NodePort的超集。
- ExternalName:通过返回带有该名称的CNAME记录,使用任意名称(由spec中的externalName指定)公开Service。不使用代理。

2.6 存储
Volume
Volume指的是存储卷,包含可被Pod中容器访问的数据目录。容器中的文件在磁盘上是临时存放的,当容器崩溃时文件会丢失,同时无法在多个Pod中共享文件,通过使用存储卷可以解决这两个问题。
Kubernetes 支持很多类型的卷。 Pod 可以同时使用任意数目的卷类型。 临时卷类型的生命周期与 Pod 相同,但持久卷可以比 Pod 的存活期长。 当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不过 Kubernetes 不会销毁持久卷。 对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。
卷的核心是一个目录,其中可能存有数据,Pod 中的容器可以访问该目录中的数据。 所采用的不同卷的类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。常用的卷类型有 configMap、emptyDir、local、nfs、secret 等。
- ConfigMap:可以将配置文件以键值对的形式保存到 ConfigMap 中,并且可以在 Pod 中以文件或环境变量的形式使用。ConfigMap 可以用来存储不敏感的配置信息,如应用程序的配置文件。
- EmptyDir:是一个空目录,可以在 Pod 中用来存储临时数据,当 Pod 被删除时,该目录也会被删除。
- Local:将本地文件系统的目录或文件映射到 Pod 中的一个 Volume 中,可以用来在 Pod 中共享文件或数据。
- NFS:将网络上的一个或多个 NFS 共享目录挂载到 Pod 中的 Volume 中,可以用来在多个 Pod 之间共享数据。
- Secret:将敏感信息以密文的形式保存到 Secret 中,并且可以在 Pod 中以文件或环境变量的形式使用。Secret 可以用来存储敏感信息,如用户名密码、证书等。
使用方式
使用卷时, 在 .spec.volumes 字段中设置为 Pod 提供的卷,并在 .spec.containers[*].volumeMounts 字段中声明卷在容器中的挂载位置。 容器中的进程看到的文件系统视图是由它们的容器镜像的初始内容以及挂载在容器中的卷(如果定义了的话)所组成的。 其中根文件系统同容器镜像的内容相吻合。 任何在该文件系统下的写入操作,如果被允许的话,都会影响接下来容器中进程访问文件系统时所看到的内容。