K8S 生产实践-06-服务发现 Service
Kubernetes 中为了实现服务实例间的负载均衡和不同服务间的服务发现,创造了 Serivce 对象,同时又为从集群外部访问集群创建了 Ingress 对象。
一、服务发现
服务之间的发现、服务之间的通信是必须要考虑的问题,总结一共有三种常用的方式:
1、集群内部(集群内部该如何服务发现、服务通信)
2、集群内-》集群外
3、集群外 -》集群内
1、集群内部的访问方式:
集群内部访问,如果两个pod要相互访问,可以通过 pod ip 来访问,但这不是一个很好的方式,因为pod ip 是不稳定的,会经常变化(pod 挂了之后会重新拉取一个新的pod),这时候可以通过service 来解决该问题;
service可以对应多个pod,通过内部机制来实现负载均衡,只要service不被删掉,则IP 永远是不变的;
如果集群中布满了service,也是不够优雅的,这时候k8s提供了DNS的概念,可以通过service 的名字来访问到service,比如名字叫(SerB),这个DNS可以解析service ip(10.0.0.1),从而实现对pod的访问;
这种方案我们叫做 DNS + ClusterIP
还有一种方案,Pod C 有多个实例,Pod A 访问HeadlessService,会将pod C 的实例列表返回,客户端拿到实例列表后自己来确定访问。
2、集群内部访问集群外部的访问方式:
示例:集群内部访问集群外部的MySQL服务
3、集群外部访问集群内部的服务:
二、ingress
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。
术语
为了表达更加清晰,本指南定义了以下术语:
- 节点(Node): Kubernetes 集群中的一台工作机器,是集群的一部分。
- 集群(Cluster): 一组运行由 Kubernetes 管理的容器化应用程序的节点。 在此示例和在大多数常见的 Kubernetes 部署环境中,集群中的节点都不在公共网络中。
- 边缘路由器(Edge Router): 在集群中强制执行防火墙策略的路由器。可以是由云提供商管理的网关,也可以是物理硬件。
- 集群网络(Cluster Network): 一组逻辑的或物理的连接,根据 Kubernetes 网络模型在集群内实现通信。
- 服务(Service):Kubernetes 服务(Service), 使用标签选择器(selectors)辨认一组 Pod。 除非另有说明,否则假定服务只具有在集群网络中可路由的虚拟 IP。
Ingress 是什么?
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
Ingress是个什么鬼,网上资料很多(推荐官方),大家自行研究。简单来讲,就是一个负载均衡的玩意,其主要用来解决使用NodePort暴露Service的端口时Node IP会漂移的问题。同时,若大量使用NodePort暴露主机端口,管理会非常混乱。
好的解决方案就是让外界通过域名去访问Service,而无需关心其Node IP及Port。那为什么不直接使用Nginx?这是因为在K8S集群中,如果每加入一个服务,我们都在Nginx中添加一个配置,其实是一个重复性的体力活,只要是重复性的体力活,我们都应该通过技术将它干掉。
Ingress就可以解决上面的问题,其包含两个组件 Ingress Controller
和 Ingress
:
Ingress
将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可
Ingress Controller
将新加入的Ingress转化成Nginx的配置文件并使之生效
查看监听的端口号:
netstat -ntlp | grep 80
示例:
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-demo
spec:
selector:
matchLabels:
app: tomcat-demo
replicas: 1
template:
metadata:
labels:
app: tomcat-demo
spec:
containers:
- name: tomcat-demo
image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
ports:
- containerPort: 8080
---
#service
apiVersion: v1
kind: Service
metadata:
name: tomcat-demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: tomcat-demo
---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat-demo
spec:
rules:
- host: tomcat.mooc.com
http:
paths:
- path: /
backend:
serviceName: tomcat-demo
servicePort: 80
:set paste # 复制粘贴,样式不变
创建Pod:
[hemei@master test]$ kubectl create -f ingress-demo.yaml
deployment.apps/tomcat-demo created
service/tomcat-demo created
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/tomcat-demo created
[hemei@master test]$
查看起的Pod:
[hemei@master test]$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nfs-subdir-external-provisioner-6dcc58bb4b-8fc84 1/1 Running 11 150d 172.16.123.39 work2 <none> <none>
tomcat-demo-54cbbcffdb-2hn5h 1/1 Running 0 2m12s 172.16.123.32 work2 <none> <none>
三、实践
ingress-nginx 安装
这里采用 nginx-ingress-controller:0.30.0
[root@hombd03 ~]]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
拉取镜像:
[root@hombd03 ~]# cat mandatory.yaml | grep image
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
所有节点下载 quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
[root@hombd03 ~]# docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
创建:
[root@centos03 k8s]# kubectl apply -f mandatory.yaml
Warning: resource namespaces/ingress-nginx is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
namespace/ingress-nginx configured
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
查看pod:
[root@hombd03 ~]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-54b86f8f7b-tblw7 0/1 Running 0 24s
可以看到上边的已经安装好了,然后进行ingress service 服务暴露;
ingress service 服务暴露
1、先查看节点work(node2、node3,这里需要安装在worker节点,而非master节点上) 80和 443端口占用情况
[root@hombd04 ~]# netstat -ntlp | grep 80
tcp 0 0 0.0.0.0:8010 0.0.0.0:* LISTEN 4595/java
tcp 0 0 192.168.1.124:2380 0.0.0.0:* LISTEN 10988/etcd
tcp6 0 0 :::10252 :::* LISTEN 8031/kube-controlle
tcp6 0 0 :::45804 :::* LISTEN 20523/java
tcp6 0 0 :::10257 :::* LISTEN 8031/kube-controlle
[root@homaybd04 ~]# netstat -ntlp | grep 443
tcp6 0 0 :::6443 :::* LISTEN 7213/kube-apiserver
[root@hombd04 ~]#
如何让 pod 运行在指定的节点上?可以在yaml文件指定的节点标签,先查看node节点:
[root@hombd03 ingress-nginx]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
hombd04 Ready <none> 14d v1.20.2
hombd05 Ready <none> 14d v1.20.2
[root@hombd03 ingress-nginx]#
然后给节点打标签,这里给 hombd04
节点打标签:
[root@hombd03 ingress-nginx]# kubectl label node homaybd04 app=ingress
node/hombd04 labeled
然后修改 mandatory.yaml
文件,网络为:hostNetwork
默认的配置:
修改后的:
重新部署该文件mandatory.yaml
[root@hombd03 ingress-nginx]# kubectl apply -f mandatory.yaml
namespace/ingress-nginx unchanged
configmap/nginx-configuration unchanged
configmap/tcp-services unchanged
查看部署的节点:
[root@hombd03 ingress-nginx]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-84787756d5-zqpx2 1/1 Running 0 88s 192.168.1.124 homaybd04 <none> <none>
[root@hombd03 ingress-nginx]#
可以看到已经部署到指定的 hombd04 worker 节点上了。
然后再去 hombd04
节点看 80 和 443 端口是否存在:
[root@hombd04 ~]# netstat -nltp | grep 80
tcp 0 0 0.0.0.0:8010 0.0.0.0:* LISTEN 4595/java
tcp 0 0 192.168.1.124:2380 0.0.0.0:* LISTEN 10988/etcd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 20315/nginx: master
tcp6 0 0 :::10252 :::* LISTEN 8031/kube-controlle
tcp6 0 0 :::45804 :::* LISTEN 20523/java
tcp6 0 0 :::80 :::* LISTEN 20315/nginx: master
tcp6 0 0 :::10257 :::* LISTEN 8031/kube-controlle
[root@homaybd04 ~]# netstat -nltp | grep 443
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 20315/nginx: master
tcp6 0 0 :::6443 :::* LISTEN 7213/kube-apiserver
tcp6 0 0 :::443 :::* LISTEN 20315/nginx: master
[root@hombd04 ~]#
测试案例 ingress-demo.yaml
:
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-demo
spec:
selector:
matchLabels:
app: tomcat-demo
replicas: 1
template:
metadata:
labels:
app: tomcat-demo
spec:
containers:
- name: tomcat-demo
image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
ports:
- containerPort: 8080
---
#service
apiVersion: v1
kind: Service
metadata:
name: tomcat-demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: tomcat-demo
---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat-demo
spec:
rules:
- host: tomcat.mooc.com
http:
paths:
- path: /
backend:
serviceName: tomcat-demo
servicePort: 80
部署:
[root@homaybd03 ingress-nginx]# kubectl create -f ingress-demo.yaml
deployment.apps/tomcat-demo created
service/tomcat-demo created
如果拉取不下来,则单独拉取:
[root@homaybd03 ~]# docker pull registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
8.0.51-alpine: Pulling from liuyi01/tomcat
查看部署的 tomcat-demo
服务:
[root@homaybd03 ingress-nginx]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 1 14d 192.200.72.199 homaybd05 <none> <none>
nginx-ds-87flg 1/1 Running 1 14d 192.200.245.133 homaybd04 <none> <none>
nginx-ds-j7mqr 1/1 Running 1 14d 192.200.72.198 homaybd05 <none> <none>
tomcat-demo-54cbbcffdb-dgct2 1/1 Running 0 56s 192.200.72.202 homaybd05 <none> <none>
然后修改配置,因为我们的nginx-ingrees 部署在 homaybd04 节点,所以,需要改为该IP配置:
sudo vi /etc/hosts
# 域名配置
192.168.1.124 tomcat.mooc.com
192.168.1.124 api.mooc.com
然后在浏览器访问 http://tomcat.mooc.com/ ,可以看到已经部署成功了:
单独下载镜像
root@homaybd03 ingress-nginx]# pwd
/root/ingress-nginx
[root@homaybd03 ingress-nginx]# grep image mandatory.yaml
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
[root@homaybd03 ingress-nginx]#
然后查看该镜像是否下载到本地:
[root@homaybd03 ingress-nginx]# grep image mandatory.yaml
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
[root@homaybd03 ingress-nginx]# docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
0.30.0: Pulling from kubernetes-ingress-controller/nginx-ingress-controller
Digest: sha256:b312c91d0de688a21075078982b5e3a48b13b46eda4df743317d3059fc3ca0d9
Status: Image is up to date for quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
[root@homaybd03 ingress-nginx]#
如果镜像下载不下来,则需要再国内镜像库下载:
docker pull registry.cn-hangzhou.aliyuncs.com/liuyi01/nginx-ingress-controller:0.30.0
查看部署的服务:
[root@hombd03 ~]# kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-q8947 0/1 ImagePullBackOff 0 11d
pod/ingress-nginx-admission-patch-n8cj9 0/1 ImagePullBackOff 0 11d
pod/nginx-ingress-controller-84787756d5-zqpx2 1/1 Running 0 11d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 192.233.205.222 <pending> 80:30720/TCP,443:30714/TCP 11d
service/ingress-nginx-controller-admission ClusterIP 192.233.236.91 <none> 443/TCP 11d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-ingress-controller 1/1 1 1 11d
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-ingress-controller-54b86f8f7b 0 0 0 11d
replicaset.apps/nginx-ingress-controller-84787756d5 1 1 1 11d
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 0/1 11d 11d
job.batch/ingress-nginx-admission-patch 0/1 11d 11d
[root@hombd03 ~]#
相关文章:
k8s官网|Ingress
84-K8S 入门操作之 Pod、Controller、Service、Ingress 等核心概念
Ingress Installation Guide
K8S ingress 实践
imooc|6-6-部署ingress-nginx
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)