【九】Kubernetes 之 Service 概念图文讲解及功能演示
Service 概念
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。
Service 通常是通过 Label Selector
,也就是 Service 通过标签选择的方式匹配一组 Pod 对外提供访问的机制。
解释上图具体实现过程:
首先、定义一个 Nginx Deployment
由它创建三个Pod
,每个 Pod 中都有对应的标签mynginx
。
第二、定义一个Nginx Service
,标签为mynginx
,Service 会根据自己的标签去匹配后端的 Pod 标签,从而把它们加入队列中提供对外服务,当然标签可以定义多个。
第三、当我们Client
访问Nginx Service
的时候,Service 会以轮询的访问策略来对外提供服务。
第四、当我们后端的Pod
挂掉的时候,Nginx Deployment
会重新创建一个新的Pod
来满足期望值,Service 会自动的将新 Pod 加入到负载均衡队列中。
Service提供负载均衡的能力限制:
Service 只提供 4 层负载均衡能力,并没有 7 层功能,也就是说只能基于IP地址和端口进行转发实现负载均衡。
需要提供 7 层负载均衡能力可以通过 Ingress 负载均衡方案来实现,后面的文章中会介绍,欢迎关注我哦。
Service 类型讲解
Service 具有四种类型:
ClusterIP: 默认类型,自动分配一个集群内部虚拟IP地址,只能被集群内部访问。(常用)
NodePort: 通过每个节点上的 IP 和静态端口(NodePort
)暴露服务,提供对外访问。也就是说我们可以通过集群中任意一个节点 IP 地址和端口来访问后的 Pod 应用。(常用)
LoadBalancer: 使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort
服务和 ClusterIP
服务上。(摘自于官方)
ExternalName: 把集群外部的服务引入到集群内部来,在集群内部直接使用。
也就是说假设外部有一个数据库集群,集群内部的Service
只需要写集群外部IP地址信息,集群内部的Pod
就可以实现访问。
如果某一天外部集群 IP 地址发生变化,只需要更新集群内部的Service
信息,内部的Pod
还是可以正常访问外部数据库集群。
VIP 和 Service 代理
在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy
进程。 kube-proxy
负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName
的形式。
在 Kubernetes v1.0 版本,代理完全在 userspace 。在 Kubernetes V1.1 版本,新增了 iptables 代理,但并不是默认的运行代理模式。
从 Kubernetes V1.2 开始,默认代理模式为 iptables;在 Kubernetes V1.8.0-beta.0 中,添加了 IPVS 代理。
然后从 Kubernetes V1.14 版本开始默认使用 IPVS 代理模式。
userspace 代理模式
当 Client 需要访问 Pod 时,首先需要访问 iptables,再从防火墙访问到 Kube-proxy,再从 Kube-proxy 访问到对应的 Pod。
无论 Client 访问本地的 Pod 还是其他节点的 Pod 都需要通过 Kube-proxy 来代理,包括 apiserver 也会监控 Kube-proxy 进行服务更新等操作,这样会导致 Kube-proxy 压力巨大。
iptables 代理模式
通过如下图可以看到,所有的访问都是通过 iptables 来完成,而不需要通过 Kube-proxy 来调度,这样的话,访问速度加快,而 Kube-proxy 压力减少,稳定性就会提升。
IPVS 代理模式
IPVS 代理模式跟 iptables 代理模式中的区别只是把 iptables 变成 IPVS ,其他的没有变。IPVS 是在内核空间中工作,意味着通信的延迟更短,性能更好。如果没有安装 IPVS 模块,则 kube-proxy 将退回到以 iptables 代理模式运行。
Service 实验演示
ClusterIP 类型
首先创建 Deployment ,my-nginx.yaml
文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx # 标签匹配
replicas: 3
template:
metadata:
labels:
run: my-nginx # 定义标签
spec:
containers:
- name: my-nginx
image: hub.test.com/library/mynginx:v1
ports:
- containerPort: 80
创建 Deployment 以及查看状态信息
[root@k8s-master01 ~]# kubectl apply -f my-nginx.yaml
deployment.apps/my-nginx created
[root@k8s-master01 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
my-nginx 3/3 3 3 8s
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-94fb9fc7c-2xjqc 1/1 Running 0 11s
my-nginx-94fb9fc7c-rmwtr 1/1 Running 0 11s
my-nginx-94fb9fc7c-x969q 1/1 Running 0 11s
此时已经可以访问每一个 Pod ,为了防止后端的 Pod 挂掉之后重新创建新的 Pod ,IP地址也会随着改变,所以要通过 Service (服务发现)来保证可靠性。
接下来创建 Service,my-nginx-svc.yaml
配置文件如下
apiVersion: v1
kind: Service
metadata:
name: my-nginx-service # Service 名称
spec:
type: ClusterIP # Service 类型
selector:
run: my-nginx # 标签匹配后端 Pod
ports:
# 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
- port: 80
targetPort: 80
创建 Service 和查看状态
[root@k8s-master01 ~]# kubectl apply -f my-nginx-svc.yaml
service/my-nginx-service created
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
my-nginx-service ClusterIP 10.100.13.4 <none> 80/TCP 7s
查看 Service 详细事件时,可以看到后端的 IP 地址都对应着每一个 Pod。
访问 Service IP 地址实际是访问后端的 Pod,Service 做了一个轮询的访问策略。
[root@k8s-master01 ~]# curl 10.100.13.4
version: v1
hostname: my-nginx-94fb9fc7c-2xjqc
[root@k8s-master01 ~]# curl 10.100.13.4
version: v1
hostname: my-nginx-94fb9fc7c-x969q
[root@k8s-master01 ~]# curl 10.100.13.4
version: v1
hostname: my-nginx-94fb9fc7c-rmwtr
NodePort 类型
利用刚刚创建好的 Deployment,这里只需要修改 Service 文件重新创建即可。my-nginx-svc.yaml
文件如下
apiVersion: v1
kind: Service
metadata:
name: my-nginx-service # Service 名称
spec:
type: NodePort # Service 类型
selector:
run: my-nginx # 标签匹配后端 Pod
ports:
# 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
- port: 80
targetPort: 80
# 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
nodePort: 30001
创建 Service 和查看状态
[root@k8s-master01 ~]# kubectl apply -f my-nginx-svc.yaml
service/my-nginx-service created
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
my-nginx-service NodePort 10.104.50.48 <none> 80:30001/TCP 6s
外部访问端口30001
,集群中任意一个节点的IP地址加上端口访问即可。
由于实验环境原因LoadBalancer 类型
和ExternalName 类型
没有进行实验演示,下一章更新 Ingress 基本概念及功能演示的学习笔记,欢迎关注我。
【九】Kubernetes 之 Service 概念图文讲解及功能演示的更多相关文章
- Kubernetes 入门之Kubernetes 的基本概念和术语
Kubernetes是什么? 他是一个全新的基于容器技术分布式架构领先方案: 他也是一个开放的开发平台: 他也是一个完备的分布式系统支撑平台: Kubernetes的基本慨念和术 ...
- 通过搭建MySQL掌握k8s(Kubernetes)重要概念(上):网络与持久卷
上一篇"通过实例快速掌握k8s(Kubernetes)核心概念"讲解了k8s的核心概念,有了核心概念整个骨架就完整了,应付无状态程序已经够了,但还不够丰满.应用程序分成两种,无状态 ...
- 【转】android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创)
原文网址:http://www.cnblogs.com/zdz8207/archive/2012/11/27/android-ndk-install.html android 最新 NDK r8 在w ...
- kubernetes进阶(04)kubernetes的service
一.service概念 Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口.借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级.Service ...
- kubernetes入门(05)kubernetes的核心概念(2)
一.使用 kubectl run 创建 pod(容器) 命令 kubectl run类似于 docker run,可以方便的创建一个容器(实际上创建的是一个由deployment来管理的Pod): 等 ...
- android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创)
android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创) 一直想搞NDK开发却一直给其他事情耽搁了,参考了些网上的资料今天终于把 ...
- 通过实例快速掌握k8s(Kubernetes)核心概念
容器技术是微服务技术的核心技术之一,并随着微服务的流行而迅速成为主流.Docker是容器技术的先驱和奠基者,它出现之后迅速占领市场,几乎成了容器的代名词.但它在开始的时候并没有很好地解决容器的集群问题 ...
- 通过搭建MySQL掌握k8s(Kubernetes)重要概念(下):参数配置
本文通过搭建MySQL环境来了解k8s的重要概念,包括持久卷,网络和参数配置.这是下篇,专门讲解参数配置.如果你有些地方不能完全看明白,请先看上篇"通过搭建MySQL掌握k8s(Kubern ...
- Kubernetes的核心技术概念和API对象
Kubernetes的核心技术概念和API对象 API对象是K8s集群中的管理操作单元.K8s集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作.例如副本集 ...
随机推荐
- 使用 Azure Container Registry 储存镜像
Azure Container Registry(容器注册表)是基于 Docker Registry 2.0规范的托管专用 Docker 注册表服务. 可以创建和维护 Azure 容器注册表来存储与管 ...
- XCTF-shrine
shrine 直接看题 进来给了个python代码 import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os ...
- android之Tween Animation
android Tween Animation有四种,AlphaAnimation(透明度动画).ScaleAnimation(尺寸伸缩动画).TranslateAnimation(位移动画).Rot ...
- Error starting userland proxy: /forwards/expose/port returned unexpected status: 500.
欢迎关注微信公众号 Error starting userland proxy: /forwards/expose/port returned unexpected status: 500. dock ...
- layui中流加载layui.flow
1.引入layui.css和layui.js 2. html中定义容器 <div id="demo"></div> js部分: layui.use('flo ...
- [笔记] 《c++ primer》书店程序 Chapter 1
书店程序是<c++ primer>中重要的实例,涉及大部分重要知识点,但代码分散阅读不便,下面按照章节顺序总结 Sales_item.h #ifndef SALESITEM_H // we ...
- reboot 就是 poweroff 然后power on
halt Shut down and halt the system poweroff Shut down and power-off the system reboot [ARG] Shut dow ...
- Docker Swarm(二)常用命令
# 管理配置文件 docker config # 查看已创建配置文件 - docker config ls # 将已有配置文件添加到docker配置文件中 - dock ...
- 016.Python闭包函数以及locals和globals
一 闭包函数 内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数 1.1 闭包函数语法 def outer(): a = 5 def inner(): pr ...
- c# sql在where查询语句中使用字符串变量与int型变量
使用where语句访问数据库时where语句用上文中以及定义过的变量来查询. string sql3 = string.Format("update Ships set ContainerN ...