基础概念

控制面(Control Plane):负责管理整个集群。 控制面协调集群中的所有活动,例如调度应用、维护应用的所需状态、应用扩容以及推出新的更新。

节点(Node):是一个虚拟机或物理机,充当工作机器的角色。节点使用控制面暴露的 Kubernetes API 与控制面通信。

Kubernetes对象

在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。Kubernetes 对象是一种“意向表达(Record of Intent)”。这就是 Kubernetes 集群所谓的期望状态(Desired State)

每个对象都可以用yaml来进行描述。下面是一个具体的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

在想要创建的 Kubernetes 对象所对应的清单(YAML 或 JSON 文件)中,需要配置的字段如下:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 帮助唯一标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 你所期望的该对象的状态

Minikube

1、使用minikube在本地创建一个单集群k8s

1
minikube start

minikube的其他指令:

1
2
3
4
5
6
7
8
# 启动 Minikube 
minikube start
# 查看 Minikube 状态
minikube status
# 停止 Minikube
minikube stop
# 删除 Minikube 集群
minikube delete

Kubectl基础

kubectl是k8s的命令行工具,用于和Kubernetes 集群进行交互和管理。它是 Kubernetes 的客户端工具之一,可以通过命令行界面(CLI)执行各种操作,如创建和管理资源、查看集群状态、调试应用程序等。

Q:kubectl如何建立和某个指定的Kubernetes集群的连接
A:kubectl通过集群config配置文件来建立和k8s集群之间的连接。kubectl会自动搜索主机上类似以下路径的配置文件,并尝试根据配置文件中集群的配置信息和集群建立连接。

1
2
$HOME/.kube/config
$KUBECONFIG

如何查看连接是否成功,如果连接成功,会返回集群中节点的信息。

1
kubectl get nodes

上下文管理

如果本机存在多个Kubernetes集群的话,需要指定kubectl去连接哪个集群。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
kubectl config <sub-command>
==============================
current-context Display the current-context
delete-cluster Delete the specified cluster from the kubeconfig
delete-context Delete the specified context from the kubeconfig
delete-user Delete the specified user from the kubeconfig
get-clusters Display clusters defined in the kubeconfig
get-contexts Describe one or many contexts
get-users Display users defined in the kubeconfig
rename-context Rename a context from the kubeconfig file
set Set an individual value in a kubeconfig file
set-cluster Set a cluster entry in kubeconfig
set-context Set a context entry in kubeconfig
set-credentials Set a user entry in kubeconfig
unset Unset an individual value in a kubeconfig file
use-context Set the current-context in a kubeconfig file
view Display merged kubeconfig settings or a specified kubeconfig file

查看所有可用的context

1
2
3
4
5
kubectl config get-contexts

CURRENT NAME CLUSTER AUTHINFO NAMESPACE
docker-desktop docker-desktop docker-desktop
* minikube minikube minikube default

这里我使用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
2
3
kubectl logs <pod-name>

kubectl logs <pod-name> -c <container-name>

4、在容器中执行命令

1
2
3
kubectl exec <pod-name> -- <command>

kubectl exec <pod-name> -c <container-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
2
3
kubectl expose deployment <deployment-name> --port=<port> --type=<service-type>

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

3、使用标签
使用describe查看标签名称,app=kubernetes-bootcamp

1
kubectl describe deployment

通过标签名来查询pod,service

1
2
3
kubectl get pod -l app=kubernetes-bootcamp

kubectl get service -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