Kubernetes中使用ClusterDNS进行服务发现
在k8s集群中,服务是运行在Pod中的,Pod的发现和副本间负载均衡是我们面临的问题。我们使用Service解决了负载均衡的问题,但是集群环境中,service经常伴随着ip的变动而变动,得益于kubedns插件,使其可以直接通过域名(service name)进行访问。
1.常见使用场景
在常见集群中经常会出现服务之间彼此通过http或者tcp、RPC的形式进行访问,在kubernetes集群中,pod和pod、service之间的网络是互通的,但是service的ip地址是存储在etcd中,如果创建完成之后,一直使用apply,那么ip不会变化,如果不小心执行了kubectl delete -f yaml,那么service的ip将发生变化,如果此ip被很多服务使用,将会带来灾难性的修改,这时我们可以借助kube-dns解决问题。
2.kubernetes网络模型
一个完整的Kubernetes集群应该包含三层网络,首先第一层是mater和node节点之间的网络,这个网络需要在部署kubernetes集群之前配置完成,第二层网络是pod的网络通过kubenet或者cni插件实现,用于pod之间或者内部的通信,集群中的所有pod均处在同一个网络平面空间内,可以直接通信,第三层网络是Service资源的网络,是一个虚拟网络,用于为Kubernetes集群配置IP地址,但此地址并不配置于任何主机或者容器的网络接口之上,而是通过kubeproxy配置为iptables规则,将发往该地址的所有流量调度至后端的pod之上。
Kubernetes网络中常见四种通信方式
1 同一个pod的内部通信;
2 各个pod彼此通信;
3 pod和service的通信;
4 集群外部流向service的通信。
看到上面这些你就不难理解为什么在yaml中存在port,targetPort,nodePort?
containerPort:一个信息性数据,他只是为集群提供一个可以快速了解相关pod可以访问端口的途径,而且显式指定容器端口,无论你是否指定都不影响其他节点上的客户端pod对其进行访问。
port:服务提供端口,用于kubernetes集群内部服务访问。
targetPort:pod目标端口,如果不设置使用默认port端口,port和nodePort的数据通过这个端口进入到Pod内部,Pod里面的containers的端口映射到这个端口,提供服务。
nodePort:外部用户访问端口
3.kubernetes中如何发现服务
通过如下yaml创建两个nginx服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.hub.com/ops/openresty:1.15
ports:
- containerPort: 80
通过进入服务内部进行访问nginx服务
kubectl exec nginx-deployment-74fd67c98d-26j9r -it /bin/bash
[root@nginx-deployment-74fd67c98d-26j9r /]# curl 10.244.1.49:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to OpenResty!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to OpenResty!</h1>
<p>If you see this page, the OpenResty web platform is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="https://openresty.org/">openresty.org</a>.<br/>
Commercial support is available at
<a href="https://openresty.com/">openresty.com</a>.</p>
<p><em>Thank you for flying OpenResty.</em></p>
</body>
</html>
看到这里可能有人要说,这简直没法用,每次创建pod ip都要改变,总不能每次手动修改ip地址访问吧?如此访问,我怎么才能做负载均衡?
如何通过service解决问题负载问题
创建如下service,通过selector选择nginx服务
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30007
- name: https
port: 443
targetPort: 443
nodePort: 30003
selector:
app: nginx
查看服务对应服务ip,并访问服务。
root@k8s-m opt]# kubectl get svc nginx-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.99.251.122 <none> 80:30007/TCP,443:30003/TCP 29h
[root@k8s-master opt]#
[root@nginx-deployment-745fd7c98d-2xj9r /]# curl 10.99.251.122:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to OpenResty!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to OpenResty!</h1>
<p>If you see this page, the OpenResty web platform is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="https://openresty.org/">openresty.org</a>.<br/>
Commercial support is available at
<a href="https://openresty.com/">openresty.com</a>.</p>
<p><em>Thank you for flying OpenResty.</em></p>
</body>
</html>
通过如上service的方式已经实现了负载均衡,但是我们在服务没有创建之前仍然是不知道服务对外提供服务IP是什么?当然我们可以在service的yaml中内置ClusterIP,但是即使如此,还可能会出现ip占用的问题。
kube-dns是如何解决如上问题的?
在创建pod资源时,kubelet会将其所属名称空间中的所有service对象以环境变量的形式注入其中。如下所示:
[root@nginx-deployment-745fd7c98d-2xj9r /]# printenv|grep NGINX
NGINX_SERVICE_PORT_443_TCP=tcp://10.99.251.123:443
NGINX_SERVICE_PORT_80_TCP_PORT=80
NGINX_SERVICE_PORT_443_TCP_PORT=443
NGINX_SERVICE_PORT_80_TCP_PROTO=tcp
NGINX_SERVICE_PORT_443_TCP_PROTO=tcp
NGINX_SERVICE_SERVICE_HOST=10.99.251.123
NGINX_SERVICE_SERVICE_PORT_HTTP=80
NGINX_SERVICE_PORT=tcp://10.99.251.123:80
NGINX_SERVICE_PORT_80_TCP=tcp://10.99.251.123:80
NGINX_SERVICE_SERVICE_PORT_HTTPS=443
NGINX_SERVICE_SERVICE_PORT=80
NGINX_SERVICE_PORT_80_TCP_ADDR=10.99.251.123
NGINX_SERVICE_PORT_443_TCP_ADDR=10.99.251.123
所以我们可以直接通过如下形式进行访问(当然如果存在集群内服务调用的话,我们就可以直接配置成域名的形式):
[root@nginx-deployment-745fd7c98d-2xj9r /]# curl nginx-service:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to OpenResty!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to OpenResty!</h1>
域名格式
具体为:<service_name>.<namespace>.svc.<cluster_domain>和<service_name>.<namespace>.<cluster_domain>,当然后面cluster_domain取决于本地/etc/resolv.conf是否配置,如上我的示例就没有使用命名空间也没有配置集群域名,那么我直接service名称就可以直接访问。
Kubernetes中使用ClusterDNS进行服务发现的更多相关文章
- kubernetes 简介:kube-dns 和服务发现
服务发现 kubernetes 提供了 service 的概念可以通过 VIP 访问 pod 提供的服务,但是在使用的时候还有一个问题:怎么知道某个应用的 VIP?比如我们有两个应用,一个 app,一 ...
- Kubernetes如何使用kube-dns实现服务发现
大纲: • Kubernetes中如何发现服务 • 如何发现Pod提供的服务 • 如何使用Service发现服务 • 如何使用kube-dns发现服务 ...
- kubernetes进阶(三)服务发现-coredns
服务发现,说白了就是服务(应用)之间相互定位的过程. 服务发现需要解决的问题: 1.服务动态性强--容器在k8s中ip变化或迁移 2.更新发布频繁--版本迭代快 3.支持自动伸缩--大促或流量高峰 我 ...
- Kubernetes 服务发现
目录 什么是服务发现? 环境变量 DNS 服务 Linux 中 DNS 查询原理 Kubernetes 中 DNS 查询原理 调试 DNS 服务 存根域及上游 DNS 什么是服务发现? 服务发现就是一 ...
- Istio技术与实践02:源码解析之Istio on Kubernetes 统一服务发现
前言 文章Istio技术与实践01: 源码解析之Pilot多云平台服务发现机制结合Pilot的代码实现介绍了Istio的抽象服务模型和基于该模型的数据结构定义,了解到Istio上只是定义的服务发现的接 ...
- prometheus k8s服务发现
Prometheus的服务发现在解决什么问题? 被监控的目标(target)是整个监控体系中重要组成部分,传统监控系统zabbix通过 网络发现的机制自动创建主机到zabbix-server,进而快速 ...
- k8s之服务发现
一.概述 k8s中支持两种服务发现方法: 环境变量和DNS 二.环境变量 当Pod被创建的时候,k8s将为Pod设置每一个Service的相关环境变量,这些环境变量包括两种类型: k8s Servic ...
- nginx动态配置及服务发现那些事
Reference: http://xiaorui.cc/2016/10/16/nginx%E5%8A%A8%E6%80%81%E9%85%8D%E7%BD%AE%E5%8F%8A%E6%9C%8D% ...
- SpringCloud学习(3)——Eureka服务注册中心及服务发现
Eureka概述: Eureka是Netflix的一个子模块, 也是核心模块之一.Eureka是一个基于REST的服务, 用于定位服务, 以实现云端中间层服务发现和故障转移.服务注册与发现对于微服务框 ...
随机推荐
- 如何准备论文线上Presentation视频录制教程(Summary of Video Recording)
0:前言 由于国外的疫情严重,目前大多数学术会议都是线上举办,因此往往需要制作presentation的视频录制.由于各种软件横飞,有的需要会员并且不熟悉操作,特别浪费时间.因此,我将这次的操作和遇到 ...
- jdk8 hashmap 链表resize 源码分析
重点看这部分代码 for (int j = 0; j < oldCap; ++j) { Node<K,V> e; if ((e = oldTab[j]) != null) { old ...
- 边缘计算 KubeEdge+EdgeMash
简介 KubeEdge是面向边缘计算场景.专为边云协同设计的业界首个云原生边缘计算框架,在 Kubernetes 原生的容器编排调度能力之上实现了边云之间的应用协同.资源协同.数据协同和设备协同等能力 ...
- String类型函数传递问题
String类型函数传递问题 问题 以前没有注意过的一个问题, 最近在使用String类型作为函数入参的时候, 发现函数内对于String类型的改变并不会影响到外层调用对象本身; 结论 (先说结论) ...
- 02 MySQL_数据库相关的SQL
数据库相关的SQL 1. 查看所有数据库 show databases; 2. 创建数据库 格式:create database 数据库名称: 示例: create database db1; 3. ...
- Solution -「线段树」题目集合
T1 无聊的数列 来自:Link flag 帖先从水题入手. 首先分析题目,它是以等差数列为原型进行的修改.等差数列一大性质就是其差分数列的值除第一项以外均相等. 于是不难想到使用差分数列进行维护. ...
- Running Median_via牛客网
题目 链接:https://ac.nowcoder.com/acm/contest/28886/1002 来源:牛客网 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 65536K, ...
- iOS中 Tagged Pointer 技术
前言: 从64位开始,iOS引入了Tagged Pointer技术,用于优化NSNumber.NSDate.NSString等小对象的存储. Tagged Pointer主要为了解决两个问题: 内 ...
- @DS("slave") 多数据源兼容事务问题解决方案
SpringBoot项目中用到多数据源,在方法上又必须加事务处理,此时可以对使用了@DS的方法或类添加@Transactional并添加事务隔离级别 举例: 1.这是一个方法,方法内需要实现多数据源查 ...
- 转:windows下定时执行备份数据库
上一篇写了linux下定时任务,这一篇转发一个windows下定时备份数据库. 第一种:新建批处理文件 backup.dat,里面输入以下 net stop mysql xcopy "C:\ ...