目录
- 前言
- 一、创建 Deployment
- 二、创建 Service
- 三、集群外部访问
前言
首先我们要清楚,Pod 中的容器很可能因为各种原因故障而死掉,如果真的发生故障,那 Deployment 等 Controller 会通过动态创建和销毁 Pod 来保证应用整体的健壮性。而每个 Pod 都有自己的 IP 地址,当 Controller 用新的 Pod 代替已发生故障的 Pod 时,新的 Pod 就会分配到新的 IP 地址。那这样就产生了一个问题:如果一组 Pod 对外提供服务,那它的 IP 是很有可能发生变化的,那客户端如何找到并访问这个服务呢?K8s 官方给出的解决方案是:Service。
Service 在 K8s 中是一个 REST 对象,和 Pod 类似。Service 从逻辑上代表了一组 Pod,具体是哪些 Pod 则是由 label 标签来挑选的。Service 有自己的 IP,而且这个 IP 是不变的。K8s 建立和维护了 Service 与 Pod 的映射关系,客户端只需要访问 Service 的 IP 即可,无论后端 Pod 如何变化,对客户端都不会有任何影响,因为 Service 是不会变的。
一、创建 Deployment
vim nginx.yml
apiVersion: apps/v1 # 指定deployment的api版本
kind: Deployment # 指定创建资源的角色/类型
metadata: # 指定Deployment的元数据
name: nginx # 创建名为nginx的Deployment
labels: # 指定Deployment的标签(可自定义多个),这里的标签不需要与任何地方的标签匹配,根据实际场景随意自定义即可
app: demo
spec: # Deployment的资源规格
replicas: 2 # Deployment将创建2个Pod副本(默认为 1)
selector: # 匹配标签选择器,定义Deployment如何查找要管理的Pod,因此这里必须与Pod的template模板中定义的标签保持一致
matchLabels:
app: demo
template: # 指定Pod模板
metadata: # 指定Pod的元数据
labels: # 指定Pod的标签(可自定义多个)
app: demo
spec: # Pod的资源规格
containers: # 指定Pod运行的容器信息
- name: nginx # 指定Pod中运行的容器名
image: nginx:1.20.0 # 指定Pod中运行的容器镜像与版本(不指定镜像版本号则默认为latest)
ports:
- containerPort: 80 # 指定容器的端口(即Nginx默认端口)
kubectl apply -f nginx.yml
这时可看到我们启动了 2 个 Pod 副本,标签是 app: demo
,service 将会用这个标签来挑选 Pod。
同时,我们也可以看到,每个 Pod 都分配到了自己的 IP,这些 Pod 的 IP 只能被 K8s 集群中的容器和节点访问。
在 Host 节点上访问这个 Pod 的 IP,是可以正常响应的,如下图所示:
二、创建 Service
上面说到 service 将会通过标签来挑选 Pod,那接下来就要创建 Service 资源。
vim nginx-srv.yml
apiVersion: v1 # service的APIversion
kind: Service
metadata:
name: nginx-srv # Service的资源名(自定义)
spec:
selector: # 选择那些label为app:demo的Pod作为Service的后端
app: demo
ports:
- protocol: TCP # 将Service的80端口映射到Pod的80端口,使用TCP协议
port: 80 # service的端口(这个端口任意定义,与Host端口是否冲突无关,即使Host有80端口或其他Service也是80端口,这都是不冲突的,只要保证是不同的Service Name即可)
targetPort: 80 # 即镜像默认的端口号,如nginx为80,mysql为3306...
type: NodePort # 提供了集群外部客户端访问service的一种方式(即提供了集群外部客户端访问service的端口)
kubectl apply -f nginx-srv.yml
查看一下 Service 以及 Service 负载的 Pod
可看到 service
三、集群外部访问
访问方式:http://NodeIP:NodePort
本案例为:http://192.168.56.161:30580/
NodeIP 为整个 K8s 集群中任意一个都是能正常访问的。
大概流程就是:当我们通过 K8s 节点访问 Pod 时,会先访问到我们的 Service 的 IP+端口,然后 Service 再将我们的请求转发到后端 Pod。