【概念解说】

当pod被实例化出来,如果运行 一段时间会销毁,虽然deployment和ds会注意管理和维护pod的数目,但是pod销毁后再重建,ip会发生变化,这对于服务来说,是很麻烦的。所以需要有一个中间层来屏蔽后端的这些变化,为前端提供一个稳定的环境。大家要访问服务的时候,都是先访问这个中间层,只要它不改变ip,那么我们访问服务的时候,就永远只要访问这个IP即可。另外,这个中间层收了流量,肯定需要转发出去,如果可以自动进行负载均衡,就再好不过了,比如像LVS,但是这不是云原生的,所以Kubernetes 又专门定义了一个新的对象:Service,在集群内部,做这个中间层,并负责负载均衡。

客户只用访问serveice的固定IP,service会根据iptables来转发请求,这个iptables,是每个节点的kube-proxy组件自动维护的。

【YAML描述】

service创建YAML的方式,为kubectl expose,这个命令同样适用于创建pod,deployment,daemonset的YAML。

apiVersion: v1
kind: Service
metadata:
name: xxx-svc

使用 kubectl expose 指令时还需要用参数 --port 和 --target-port 分别指定映射端口和容器端口,而 Service 自己的 IP 地址和后端 Pod 的 IP 地址可以自动生成。

export out="--dry-run=client -o yaml"
kubectl expose deploy ngx-dep --port=80 --target-port=80 $out

如下是一个service YAML示例:

apiVersion: v1
kind: Service
metadata:
name: ngx-svc spec:
selector:
app: ngx-dep ports:
- port: 80
targetPort: 80
protocol: TCP

1)selector:用来过滤出要代理的那些 Pod。因为我们指定要代理ngx-dep这个 Deployment,所以 Kubernetes 就为我们自动填上了 ngx-dep 的标签,会选择这个 Deployment 对象部署的所有 Pod;

2)ports:分别代表外部端口、内部端口和使用的协议。

 【如何使用】

1、创建一个configmap的YAML文件cm.yml,定义一个nginx的配置片段,输出服务器的地址、主机名、请求的URL等信息。kubectl apply -f cm.yml;

apiVersion: v1
kind: ConfigMap
metadata:
name: ngx-conf data:
default.conf: |
server {
listen 80;
location / {
default_type text/plain;
return 200
'srv : $server_addr:$server_port\nhost: $hostname\nuri : $request_method $host $request_uri\ndate: $time_iso8601\n';
}
}

2、将cm注入到deployment中:创建一个deployment的YAML文件deployment.yml,在“template.volumes”里定义存储卷,再用“volumeMounts”把配置文件加载进 Nginx 容器里。kubectl apply -f deployment.yml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: ngx-dep spec:
replicas: 2
selector:
matchLabels:
app: ngx-dep template:
metadata:
labels:
app: ngx-dep
spec:
volumes:
- name: ngx-conf-vol
configMap:
name: ngx-conf containers:
- image: nginx:alpine
name: nginx
ports:
- containerPort: 80 volumeMounts:
- mountPath: /etc/nginx/conf.d
name: ngx-conf-vol

3、使用svc.yml创建service对象:创建一个svc的YAML文件svc.yml,kubectl apply后,使用get svc查看状态。可以看到,Kubernetes 为 Service 对象自动分配了一个 IP 地址“10.103.92.97”,这个地址段是独立于 Pod 地址段的。而且 Service 对象的 IP 地址还有一个特点,它是一个“虚地址”,不存在实体,只能用来转发流量。

apiVersion: v1
kind: Service
metadata:
name: ngx-svc spec:
selector:
app: ngx-dep ports:
- port: 80
targetPort: 80
protocol: TCP

4、查看service对象代理了哪些后端的pod。截图里显示 Service 对象管理了两个 endpoint,分别是10.244.1.15:80和10.244.1.16:80,与 Service、Deployment 的定义相符。进入其中一个pod,curl代理ip10.103.92.97,看到返回的信息中,Service 确实用一个静态 IP :10.103.92.97,代理了两个 Pod 的动态 IP 地址。

5、delete一个pod,ip应该会变化,之后我们重复第四步的操作

6、如果ping 10.103.92.97,是ping不通的,因为这是一个虚ip,仅仅有从来做流量转发用的,ping它是不会回reply包的,所以不会ping通的。

【一点扩展】

service这个工作原理,是不是很容易让我们想到url访问的时候,我们也是输入一个域名,然后这个域名会有很多A记录,让我们最终可以解析了这个域名,进而和这个ip进行真实的业务交互。所以service提供的这个虚ip,可不可以也是个域名呢?毕竟文字肯定要比数字好记住。这里有一个新的概念:namespace(ns)。使用kubectl get ns可以看到当前集群里有哪些ns。

其中,有一个默认的ns,叫default,如果不显式指定,API对象都会在这个default ns里。其他的ns也都有各自的用途,比如kube-system,就有apiserver,etcd等核心组件的pod。而service的域名形式就是:对象.名字空间.svc.cluster.local,很多时候我们也可以省略为:对象.名字空间,甚至简化为:对象名。

我们再次进入上面的ngx-dep pod,curl一下这个域名:ngx-svc,同样可以访问到。即,我们可以通过域名的方式,访问后端服务。(Kubernetes 也为每个 Pod 分配了域名,形式是“IP 地址. 名字空间.pod.cluster.local”,但需要把 IP 地址里的 . 改成 - 。比如地址 10.10.1.87,它对应的域名就是 10-10-1-87.default.pod。)

 【service如何对外暴露服务】

Service 对象有一个关键字段“type”,表示 Service 是哪种类型的负载均衡。前面我们看到的用法都是对集群内部 Pod 的负载均衡,所以这个字段的值就是默认的“ClusterIP”,Service 的静态 IP 地址只能在集群内访问。除了“ClusterIP”,Service 还支持其他三种类型,分别是“ExternalName”“LoadBalancer”“NodePort”。不过前两种类型一般由云服务商提供,我们的实验环境用不到,所以接下来就重点看“NodePort”这个类型。

如果我们在使用命令 kubectl expose 的时候加上参数 --type=NodePort,或者在 YAML 里添加字段 type:NodePort,那么 Service 除了会对后端的 Pod 做负载均衡之外,还会在集群里的每个节点上创建一个独立的端口,用这个端口对外提供服务,这也正是“NodePort”这个名字的由来。get svc看到“TYPE”变成了“NodePort”,而在“PORT”列里的端口信息也不一样,除了集群内部使用的“80”端口,还多出了一个“32135”端口,这就是 Kubernetes 在节点上为 Service 创建的专用映射端口。

实验一下:访问我们worker1 ip的32135端口,看看是否可以访问到ngx-dep这两个pod的服务。红框中看到,访问到的pod信息是正确的。 不过,Kubernetes 为了避免端口冲突,默认只在“30000~32767”这个范围内随机分配,只有 2000 多个可以使用,所以可能不够用。另外登录master和worker,netstat会看到,原来k8s集群里的每个节点都开放了32135端口,然后通过kube-proxy路由到最终的后端服务,如果业务量大,这无疑也增加了网络通信的成本。但 NodePort 仍然是 Kubernetes 对外提供服务的一种简单易行的方式,在其他更好的方式出现之前,我们也只能使用它。

API对象--Service(chrono《kubernetes入门实战课》笔记整理)的更多相关文章

  1. Asp.Net Web API 2(入门)第一课

    Asp.Net Web API 2(入门)第一课   前言 Http不仅仅服务于Web Pages.它也是一个创建展示服务和数据的API的强大平台.Http是简单的.灵活的.无处不在的.你能想象到几乎 ...

  2. Kubernetes的核心技术概念和API对象

    Kubernetes的核心技术概念和API对象 API对象是K8s集群中的管理操作单元.K8s集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作.例如副本集 ...

  3. Elasticsearch7.X 入门学习第四课笔记---- Search API之(Request Body Search 和DSL简介)

    原文:Elasticsearch7.X 入门学习第四课笔记---- Search API之(Request Body Search 和DSL简介) 版权声明:本文为博主原创文章,遵循CC 4.0 BY ...

  4. Elasticsearch7.X 入门学习第三课笔记----search api学习(URI Search)

    原文:Elasticsearch7.X 入门学习第三课笔记----search api学习(URI Search) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出 ...

  5. Elasticsearch7.X 入门学习第二课笔记----基本api操作和CRUD

    原文:Elasticsearch7.X 入门学习第二课笔记----基本api操作和CRUD 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链 ...

  6. 如何在Kubernetes 里添加自定义的 API 对象(一)

    环境: golang 1.15 依赖包采用go module 实例:现在往 Kubernetes 添加一个名叫 Network 的 API 资源类型.它的作用是,一旦用户创建一个 Network 对象 ...

  7. Spark入门实战系列--6.SparkSQL(下)--Spark实战应用

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .运行环境说明 1.1 硬软件环境 线程,主频2.2G,10G内存 l  虚拟软件:VMwa ...

  8. Spark入门实战系列--6.SparkSQL(上)--SparkSQL简介

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .SparkSQL的发展历程 1.1 Hive and Shark SparkSQL的前身是 ...

  9. kubernetes 入门学习

    kubernetes 学习 kubernetes 简介 Kubernetes这个名字源自希腊语,意思是"舵手",也是"管理者","治理者"等 ...

  10. 第一章 Kubernetes入门

    第一章 Kubernetes入门 kubernetes是基于容器技术的分布式架构领先方案,是一个完备的分布式系统支撑平台. kubernetes带来的好处:1)全面拥抱微服务:2)统可以随时随地整体“ ...

随机推荐

  1. Vue搭建项目的完整流程 如何搭建一个完整的vue项目 vue项目架构

    vue项目架构 技术栈:vue3.vue-router .vuex(和pinia).element plus .axios.ts.sass 1.安装vue3 脚手架+ ts vue create ad ...

  2. crypto-gmsm国密算法库

    crypto-gmsm国密算法库 一.开发背景 crypto-gmsm国密算法库是国密商密算法(SM2,SM3,SM4)工具类封装,国产密码算法(国密算法)是指国家密码局认定的国产商用密码算法,目前主 ...

  3. 【7】java之正则表达式

    一.正则标记 ​ 所有的正则可以使用的标记都在 java.util.regex.Pattern 类里定义. 1.1 单个字符 字符:表示由一位字符所组成: \\\\:表示转义字符"\\&qu ...

  4. Google Webstore Config

    1.使用Edge浏览.下载并安装 iGG谷歌访问助手 - Microsoft Edge Addons 登录https://microsoftedge.microsoft.com/addons/sear ...

  5. 7. Light (对象)

    Light Mode:模式 Realtime: 实时的.就是当前光照效果是实时的,不包含烘焙效果(即使场景曾经烘焙过) Mixed: 混合的.就是既使用烘焙数据对静态对象(Lightmap stati ...

  6. CF1764G1 题解

    题意 传送门 交互库有一个 \([1,n]\) 的排列 \(p\),你可以询问 \(l,r,k\),交互库会返回 \(\lfloor\dfrac{p_l}{k}\rfloor,\lfloor\dfra ...

  7. 隐藏来源 禁用Referrer 的方法

    原文链接: https://www.cnblogs.com/duanweishi/p/16490197.html https://blog.csdn.net/qq996150938/article/d ...

  8. Hsm状态机init()和dispatch()流程

    (LCA)共同祖先状态:首先找到s(原状态)能处理t(目标状态)的超状态,然后找到t(目标状态)到上一步超状态的退出路径p[]并保存,最后沿着退出路径进入t目标状态. QHsm_dispatch_(Q ...

  9. libuv 网络库设计概览译

    设计概览 libuv 是一种支持跨平台的网络库,最初是为了NodeJS作为某个模块实现的,主要基于事件驱动的I/O 模型设计的. 这个库不仅仅对不同的I/O polling 机制提供简单的抽象. ha ...

  10. 使用shell判断文件夹中是否包含文件

    #!/bin/bash directory="/path/to/directory" if [ $(ls -A $directory) ]; then echo "有文件 ...