自动感知,指的是客户端只用访问服务的ip,而不用关心pod在哪个节点,以及pod的ip是多少。
服务可以自动感知pod的位置及ip,核心是通过selector标签选择器找到pod
自动注册,指的是服务创建之后,会自动在k8s的kube-dns服务注册,实现域名和ip的映射,kube-dns是一个系统服务,在部署k8s的时候就有这个服务了,这个服务在kube-system系统名称空间下。其他创建的服务,来找这个dns服务,自动注册。服务域名的格式是<服务名称>.<名称空间>.svc.cluster.local
负载均衡,指的是,当一个服务后端有多个pod的时候,访问服务的请求,会自动在后端pod之间实现负载均衡,不用配置。
服务为什么能实现这些功能?
底层是lvs技术--负载均衡,比如NAT、DR
包括iptables技术--数据转发,比如SNAT、DNAT
两者都可以实现路由和负载均衡的功能,
ipbables还可以实现,修改数据包源目IP和包标记
用四表五链实现很多各种复杂的三四层路由。
都不需要管理员管理
都是kube-proxy配置和管理的
相当于你雇了个员工,他负责管理公司的防火墙和负载均衡,这个员工就叫kubeproxy
所以说,kubeproxy管理lvs负载均衡、iptables防火墙和域名注册
k8s底层,就是一个负载均衡集群
kubeproxy有自我修复机制,
即使把kube-proxy的pod全部删掉了,集群会自动重建kube-proxy的pod
而且配置的时候,是基于每一台主机的,每一台主机上面都有kubeproxy,master主机上也有
集群坏了,kubeproxy替你维护集群,kubeproxy坏了,集群又会重建kubeproxy
关于k8s内,dns服务的实现及实验
kube-dns服务在kube-system系统名称空间下
服务的自动注册测试:
当服务没有创建的时候,
服务的域名是没有被dns解析为ip的
当服务创建之后,
服务的域名被dns解析为10.245.23.28
这就验证了k8s的dns服务
对于其他服务的自动注册,自动解析功能
~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 2d22h
~]# kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.245.0.10 <none> 53/UDP,53/TCP,9153/TCP 2d22h
metrics-server ClusterIP 10.245.105.229 <none> 443/TCP 2d
~]# host
-bash: host: command not found
~]# nslookup
-bash: nslookup: command not found
~]# yum -y install bind-utils
~]# host websvc.default.svc.cluster.local 10.245.0.10
# host是DNS命令行工具, websve.de...是域名,10.245.0.10是DNS服务器
Using domain server:
Name: 10.245.0.10
Address: 10.245.0.10#53
Aliases:
Host websvc.default.svc.cluster.local not found: 3(NXDOMAIN)
~]# kubectl apply -f websvc.yaml
service/websvc created
~]# host websvc.default.svc.cluster.local 10.245.0.10
Using domain server:
Name: 10.245.0.10
Address: 10.245.0.10#53
Aliases:
websvc.default.svc.cluster.local has address 10.245.23.28
~]# cat websvc.yaml
---
kind: Service
apiVersion: v1
metadata:
name: websvc
spec:
type: ClusterIP
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 2d23h
websvc ClusterIP 10.245.23.28 <none> 80/TCP 18m
]# curl 10.245.23.28
curl: (7) Failed to connect to 10.245.23.28 port 80: Connection refused
# 这里为什么报错呢,因为服务本身不对外提供应用,只是一个代理和转发,在没有pod的时候,自然是访问不到的
~]# kubectl replace --force -f web1.yaml
pod "web1" deleted
pod/web1 replaced
~]# curl 10.245.23.28
Welcome to The Apache.
]# cat web1.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: web1
labels:
app: web
spec:
containers:
- name: apache
image: myos:httpd
# 创建pod之后,就可以访问到了。这时候不知道pod的ip,但是也不用知道pod的ip,因为访问服务,服务自动就把请求转发给pod了。pod在哪,pod的ip是多少,都无所谓,因为服务会自动感知pod的位置和ip
~]# curl 10.245.23.28
Welcome to The Apache.
~]# kubectl get pods web1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web1 1/1 Running 0 18s 10.244.21.135 node-0001 <none> <none>
~]# kubectl replace --force -f web1.yaml
pod "web1" deleted
pod/web1 replaced
~]# curl 10.245.23.28
Welcome to The Apache.
~]# kubectl get pods web1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web1 1/1 Running 0 7s 10.244.240.141 node-0004 <none> <none>
# 比如pod重建之后,从node001上跑到了node004上,ip也从21.135变成了240.141,访问服务,依然是能访问到apache服务。这就验证了服务对于pod的自动感知功能。自动感知是靠什么实现的呢?是靠标签,因为服务中制定了selector标签,而这个pod资源文件中规定了带这个标签。所以服务可以自动感知pod
~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
web1 1/1 Running 0 4m56s app=web
~]# cat websvc.yaml
---
kind: Service
apiVersion: v1
metadata:
name: websvc
spec:
type: ClusterIP
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
~]# kubectl label pods web1 app-
pod/web1 unlabeled
~]# curl 10.245.23.28
curl: (7) Failed to connect to 10.245.23.28 port 80: Connection refused
# 把pod的标签删除之后,服务就不可用了,因为服务不能通过标签找到pod
~]# kubectl label pods web1 app=web
pod/web1 labeled
~]# curl 10.245.23.28
Welcome to The Apache.
# 给pod设置标签之后,服务就又可以访问了,所以证明了,服务是靠标签找pod的
# 测试服务的自动负载均衡功能
~]# sed 's,web1,web2,' web1.yaml | kubectl apply -f -
pod/web2 created
~]# sed 's,web1,web3,' web1.yaml | kubectl apply -f -
pod/web3 created
~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web1 1/1 Running 0 11m
web2 1/1 Running 0 19s
web3 1/1 Running 0 7s
~]# curl 10.245.23.28/info.php
<pre>
Array
(
[REMOTE_ADDR] => 10.244.219.64
[REQUEST_METHOD] => GET
[HTTP_USER_AGENT] => curl/7.61.1
[REQUEST_URI] => /info.php
)
php_host: web2
1229
~]# curl 10.245.23.28/info.php
<pre>
Array
(
[REMOTE_ADDR] => 10.244.219.64
[REQUEST_METHOD] => GET
[HTTP_USER_AGENT] => curl/7.61.1
[REQUEST_URI] => /info.php
)
php_host: web1
1229
~]# curl 10.245.23.28/info.php
<pre>
Array
(
[REMOTE_ADDR] => 10.244.219.64
[REQUEST_METHOD] => GET
[HTTP_USER_AGENT] => curl/7.61.1
[REQUEST_URI] => /info.php
)
php_host: web3
1229
# 因为info.php文件中,把主机名打印出来了,所以访问三次可以看到,分别访问的是pod web1、web2、web3,证明服务是自动实现负载均衡的
host是DNS命令行工具
nslookup也是DNS命令行工具
一个是非交互式
一个是交互式