k8s攻略之网络模型及services
1. Kubernetes 基本网络模型
Kubernetes 对于网络具体实现方案,没有什么限制,也没有给出特别好的参考案例。Kubernetes 对一个容器网络是否合格做出了限制,也就是 Kubernetes 的容器网络模型。可以把它归结为约法三章和四大目标。
约法三章:
任意两个 pod 之间其实是可以直接通信的,无需经过显式地使用 NAT 来接收数据和
pod 看到自己的 IP 跟别人看见它所用的IP是一样的,中间不能经过转换。
四大目标:外界流量是如何一步步到达容器内部应用app的。
外部世界和 service 之间是怎么通信的?就是有一个互联网或者是公司外部的一个用户,怎么用到 service?service 特指 K8s 里面的服务概念。
service 如何与它后端的 pod 通讯?
pod 和 pod 之间调用是怎么做到通信的?
pod 内部容器与容器之间的通信?
容器网络方案大体分为 Underlay/Overlay 两大派别:
Overlay 不一样的地方就在于它并不需要从 Host 网络的 IPM 的管理的组件去申请IP,一般来说,它只需要跟 Host 网络不冲突,这个 IP 可以自由分配的。
2. 主流网络方案简介
容器网络方案可能是 K8s 里最为百花齐放的一个领域,它有着各种各样的实现。容器网络的复杂性,其实在于它需要跟底层 Iass 层的网络做协调、需要在性能跟 IP 分配的灵活性上做一些选择,这个方案是多种多样的。具体如下:
3. Network Policy 基本概念
No resources found in default namespace.
4.service 组件需求来源
服务发现使然:pod生命周期短暂,IP频繁变动。
负载均衡要求:后端pod需要负载均衡,出口为统一VIP。
在 K8s 里面,服务发现与负载均衡就是 K8s Service。
5. services语法
实例:创建一个名字叫my-service的service,将访问这个 service 80 端口的流量负载均衡到后端 app:MyApp 这种 label 的 pod 的 9376 端口。
6.创建及查看service
[root@node-1 efk]# kubectl describe service elasticsearch
Name: elasticsearch
Namespace: default
Labels: k8s-app=elasticsearch-logging
Annotations: <none>
Selector: k8s-app=elasticsearch-logging
Type: ClusterIP
IP Families: <none>
IP: 10.68.40.132 #service vip
IPs: 10.68.40.132
Port: <unset> 9200/TCP
TargetPort: db/TCP
Endpoints: 172.20.139.114:9200 #rs ip
Session Affinity: None
Events: <none>
[root@node-1 efk]#
# type 为ClusterIP 只可以在集群内部(node,pod都可以)被访问。外部无法访问。
[root@node-1 efk]# curl 10.68.40.132:9200
{
"name" : "HQJexFJ",
"cluster_name" : "elasticsearch-logging-0",
"cluster_uuid" : "IbzfasBKTwSPa8e0yq2C0g",
"version" : {
"number" : "6.8.13",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "be13c69",
"build_date" : "2020-10-16T09:09:46.555371Z",
"build_snapshot" : false,
"lucene_version" : "7.7.3",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
[root@node-1 efk]#
7.集群内访问 Service
在集群里面,其他 pod 要怎么访问到我们所创建的这个 service 呢?有三种方式:
通过 service 的虚拟 IP 去访问
直接访问服务名,依靠 DNS 解析,就是同一个 namespace 里 pod 可以直接通过 service 的名字去访问到刚才所声明的这个 service。不同的 namespace 里面,我们可以通过 service 名字加“.”,然后加 service 所在的哪个 namespace 去访问这个 service,例如我们直接用 curl 去访问,就是 my-service:80 就可以访问到这个 service。
wget kibana.default
--2021-09-15 21:33:47-- http://kibana.default/
Resolving kibana.default... 10.68.220.10
Connecting to kibana.default|10.68.220.10|:80... connected.
HTTP request sent, awaiting response... 404 Not Found
2021-09-15 21:33:47 ERROR 404: Not Found.
# 进入某一个pod中,输入env找到对应的环境变量。进行访问。
# wget $ELASTICSEARCH_SERVICE_HOST:$ELASTICSEARCH_SERVICE_PORT
8.集群外暴露service
暴露公网的两种方式:
# node节点30071 端口暴漏在公网
# 所有的node节点30071 均可以访问。
# kubectl get service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
elasticsearch NodePort 10.68.40.132 <none> 9200:30071/TCP 10d k8s-app=elasticsearch-logging
kibana ClusterIP 10.68.220.10 <none> 5601/TCP 10d app=kibana
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 130d <none>
LoadBalancer:在 NodePort 上面又做了一层转换,刚才所说的 NodePort 其实是集群里面每个节点上面一个端口,LoadBalancer 是在所有的节点前又挂一个负载均衡。比如在阿里云上挂一个 SLB,这个负载均衡会提供一个统一的入口,并把所有它接触到的流量负载均衡到每一个集群节点的 node pod 上面去。然后 node pod 再转化成 ClusterIP,去访问到实际的 pod 上面。
# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch ClusterIP 10.68.40.132 <none> 9200/TCP 10d
kibana ClusterIP 10.68.220.10 <none> 5601/TCP 10d
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 130d
# 修改为LoadBalancer 被外部访问,可以看到EXTERNAL-IP 出现。
# kubectl get service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
elasticsearch LoadBalancer 10.68.40.132 <pending> 9200:30071/TCP 10d k8s-app=elasticsearch-logging
kibana ClusterIP 10.68.220.10 <none> 5601/TCP 10d app=kibana
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 130d <none>
用EXTERNAL-IP进程访问测试:
9.k8s服务发现架构