Kubernetes
基础概念
控制面(Control Plane):负责管理整个集群。 控制面协调集群中的所有活动,例如调度应用、维护应用的所需状态、应用扩容以及推出新的更新。
节点(Node):是一个虚拟机或物理机,充当工作机器的角色。节点使用控制面暴露的 Kubernetes API 与控制面通信。
Kubernetes对象
在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。Kubernetes 对象是一种“意向表达(Record of Intent)”。这就是 Kubernetes 集群所谓的期望状态(Desired State)。
每个对象都可以用yaml来进行描述。下面是一个具体的例子
1 | apiVersion: apps/v1 |
在想要创建的 Kubernetes 对象所对应的清单(YAML 或 JSON 文件)中,需要配置的字段如下:
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本kind
- 想要创建的对象的类别metadata
- 帮助唯一标识对象的一些数据,包括一个name
字符串、UID
和可选的namespace
spec
- 你所期望的该对象的状态
Minikube
1、使用minikube
在本地创建一个单集群k8s
1 | minikube start |
minikube的其他指令:
1 | # 启动 Minikube |
Kubectl基础
kubectl是k8s的命令行工具,用于和Kubernetes 集群进行交互和管理。它是 Kubernetes 的客户端工具之一,可以通过命令行界面(CLI)执行各种操作,如创建和管理资源、查看集群状态、调试应用程序等。
Q:kubectl如何建立和某个指定的Kubernetes集群的连接
A:kubectl通过集群config
配置文件来建立和k8s集群之间的连接。kubectl会自动搜索主机上类似以下路径的配置文件,并尝试根据配置文件中集群的配置信息和集群建立连接。
1 | $HOME/.kube/config |
如何查看连接是否成功,如果连接成功,会返回集群中节点的信息。
1 | kubectl get nodes |
上下文管理
如果本机存在多个Kubernetes集群的话,需要指定kubectl去连接哪个集群。
1 | kubectl config <sub-command> |
查看所有可用的context
1 | kubectl config get-contexts |
这里我使用minikube和docker-desktop分别启动了k8s集群,显示的内容如上,并且表示当前启用的是名为minikube
的上下文。
查看当前启用的context
1 | kubectl config current-context |
切换context
1 | kubectl config use-context <NAME> |
部署应用
创建部署
1 | kubectl create deployment <deployment-name> --image=<image-name> |
查看所有部署
1 | kubectl get deployments |
当创建Deployment后,K8s会创建一个Pod来托管该应用实例。Pod是由一个或多个应用容器构成的,一个pod中的容器能共享一些资源:
- 共享存储,当作卷
- 网络,每个pod都有不同且唯一的IP地址
- 有关每个容器如何运行的信息,例如容器镜像版本或要使用的特定端口
一些kubectl的相关命令
1、获取现存的所有Pods
1 | kubectl get pods |
2、查看pods详情,包括IP 地址、使用的端口以及 Pod 生命期有关的事件列表。
1 | kubectl describe pods |
3、查看pods的日志
1 | kubectl logs <pod-name> |
4、在容器中执行命令
1 | kubectl exec <pod-name> -- <command> |
节点(Node)
Pod 总是运行在节点上。节点是 Kubernetes 中参与计算的机器,可以是虚拟机或物理计算机,具体取决于集群。 每个节点由控制面管理。节点可以有多个 Pod,Kubernetes 控制面会自动处理在集群中的节点上调度 Pod。 控制面的自动调度考量了每个节点上的可用资源。
节点至少包括:
- Kubelet:负责 Kubernetes 控制面和节点之间通信的进程;它管理机器上运行的 Pod 和容器。
- 容器运行时:(如 Docker)负责从镜像仓库中提取容器镜像、解压缩容器以及运行应用。
服务(Service)
Kubernetes的Service是一个抽象层,它定义了一组Pod的逻辑集,并为这些Pod支持外部流量暴露、负载均衡和服务发现。Kubernetes 中的服务(Service)是一种抽象概念,它定义了 Pod 的逻辑集和访问 Pod 的协议。
尽管每个 Pod 都有一个唯一的 IP 地址,但是如果没有 Service,这些 IP 不会被公开到集群外部。 Service 允许你的应用接收流量。 通过设置 Service 的 spec
中的 type
,你可以用不同的方式公开 Service:
- _ClusterIP_(默认)- 在集群的内部 IP 上公开 Service。这种类型使得 Service 只能从集群内访问。
- NodePort - 使用 NAT 在集群中每个选定 Node 的相同端口上公开 Service 。使用
<NodeIP>:<NodePort>
从集群外部访问 Service。是 ClusterIP 的超集。 - LoadBalancer - 在当前云中创建一个外部负载均衡器(如果支持的话),并为 Service 分配一个固定的外部IP。是 NodePort 的超集。
- ExternalName - 将 Service 映射到
externalName
字段的内容(例如foo.bar.example.com
),通过返回带有该名称的CNAME
记录实现。不设置任何类型的代理。这种类型需要kube-dns
的 v1.7 或更高版本,或者 CoreDNS 的 0.8 或更高版本。
标签(Label)
Service 通过标签和选择算符来匹配一组 Pod,它们是允许对 Kubernetes 中的对象进行逻辑操作的一种分组原语。 标签是附加在对象上的键/值对,可以以多种方式使用:
- 指定用于开发、测试和生产的对象
- 嵌入版本标记
- 使用标记将对象分类
创建服务
1、查看集群中的Services
1 | kubectl get services |
2、暴露服务
1 | kubectl expose deployment <deployment-name> --port=<port> --type=<service-type> |
3、使用标签
使用describe
查看标签名称,app=kubernetes-bootcamp
1 | kubectl describe deployment |
通过标签名来查询pod,service
1 | kubectl get pod -l app=kubernetes-bootcamp |
添加新标签
1 | kubectl label pods <pod-name> <label key=label value> |
4、 删除服务
1 | kubectl delete service -l app=kubernetes-bootcamp |
应用扩缩
扩缩 是通过改变 Deployment 中的副本数量来实现的。
查看由 Deployment 创建的 ReplicaSet
1 | kubectl get rs |
扩容
1 | kubectl scale deployments/kubernetes-bootcamp --replicas=4 |
查看
1 | kubectl get pods -o wide |
应用更新
滚动更新 允许通过使用新的实例逐步更新 Pod 实例,实现零停机的 Deployment 更新。 新的 Pod 将被调度到具有可用资源的节点上。
滚动更新允许以下操作:
- 将应用程序从一个环境升级到另一个环境(通过容器镜像更新)
- 回滚到以前的版本
- 持续集成和持续交付应用程序,无需停机
1 | kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 |
验证更新,可以看到已经是v=2版本
检查更新状态
1 | kubectl rollout status deployments/kubernetes-bootcamp |
回滚更新
先执行一次错误的更新(不存在的版本号)
1 | kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10 |
通过kubectl get pods
可以看到部分Pod的状态是ImagePullBackOff
。通过kubectl describe pods
可见在受影响的 Pod 的 Events
部分, 显示镜像的 v10
版本在仓库中不存在。
rollout undo
命令会恢复 Deployment 到先前的已知状态(v2 的镜像)。 更新是受版本控制的,你可以恢复 Deployment 到任何先前已知状态。
清理本地集群
1 | kubectl delete deployments/kubernetes-bootcamp services/kubernetes-bootcamp |
部署Redis服务
1、应用 Redis Deployment
1 | kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml |
也可以直接通过该yaml文件进行创建。
2、创建 Redis 领导者服务
1 | kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml |
3、创建Redis Follower
1 | kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml |
4、创建Redis Follower服务
1 | kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml |
5、查看所有服务
1 | kubectl get services |
6、创建前端Deployment
1 | kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml |
7、创建前端服务
1 | kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml |
8、由于使用docker作为容器驱动,需要开启minikube tunnel
1 | minikube service kubernetes-bootcamp --url |
打开上述url
存储
PersistentVolume(PV)
PersistentVolumeClaim(PVC)
StorageClass
StatefulSet基础
网络系统
涉及Kubernetes集群内部是如何通信的。包括:
- 容器间通信
- Pod间通信
- Pod和Service间通信
- 外部和Service间通信
Kubernetes 强制要求所有网络设施都满足以下基本要求(从而排除了有意隔离网络的策略):
- Pod 能够与所有其他节点上的 Pod 通信, 且不需要网络地址转译(NAT)
- 节点上的代理(比如:系统守护进程、kubelet)可以和节点上的所有 Pod 通信
Kubernetes 的 IP 地址存在于 Pod
范围内 —— 容器共享它们的网络命名空间 —— 包括它们的 IP 地址和 MAC 地址。 这就意味着 Pod
内的容器都可以通过 localhost
到达对方端口。 这也意味着 Pod
内的容器需要相互协调端口的使用,但是这和虚拟机中的进程似乎没有什么不同, 这也被称为“一个 Pod 一个 IP”模型。
参考:
一文让你全面了解K8s(Kubernetes) - 知乎 (zhihu.com)
官方文档:Kubernetes 文档 | Kubernetes