Kubernetes
吾八哥学k8s(十):kubernetes里Service和Ingress
在kubernetes里我们的服务通常都是有多个Pod的,那么不同的服务之间如何通信呢?如果是用Pod的IP来进行,那么当服务动态扩缩容或者Pod发版重建的时候,Pod的IP地址也是会变化的,这个时候用IP访问就变得极其复杂了。kubernetes引用了Service来解决这种问题,Service主要用于Pod之间的通信,Service可以通过Label Selector映射到一组Pod上来对外提供服务。而Ingress则是为集群中的服务提供了入口,可以提供负载均衡、SSL 终结和基于名称的虚拟托管。Ingress公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由,流量路由由 Ingress 资源上定义的规则控制。流量先到 ingress再到service最后到Pod上,下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
创建测试服务
首先我们创建一个用于测试Service的Deployment,yaml文件如下:
apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80
执行如下命令创建测试的deployment,并且等待服务器启动完成:
kubectl apply -f my-nginx.yaml kubectl rollout status deploy my-nginx
查看运行的my-nginx服务相关的信息如下:
5bug.wang:~/codes/kubernetes/test$ kubectl get pods -l run=my-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-5b56ccd65f-crslj 1/1 Running 0 2m55s 172.17.0.4 minikube <none> <none> my-nginx-5b56ccd65f-vfkgf 1/1 Running 0 2m55s 172.17.0.3 minikube <none> <none>
这个时候可以链接到上面的pod里通过Pod的IP地址进行访问,但我们今天这里要使用Service的方式来访问。
创建Service
对于service,如下知识我们得要有所了解:
service是通过label selector关联到对应的pod的
支持tcp和udp协议,默认是tcp协议
支持暴露多个端口
可以定义没有selector的Service,需手动映射Endpoints
kubernetes ServiceType支持如下几种类型:
ClusterIP 默认类型,只能在集群内部访问使用
NodePort 在集群节点上打开一个端口,此端口代理到后端的Pod,支持从集群外部访问到集群内部,格式为:NodeIP:NodePort
LoadBalancer 使用云厂商提供的负载均衡器公开服务
ExternalName 通过返回定义的CNAME别名,没有任何类型的代理(1.7+的版本支持)
下面来定义一个文件名my-nginx-svc.yaml的Service:
apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: run: my-nginx
基于上面的yaml文件创建service并查看service信息:
5bug.wang:~/codes/kubernetes/test$ kubectl apply -f my-nginx-svc.yaml service/my-nginx created 5bug.wang:~/codes/kubernetes/test$ kubectl get svc my-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-nginx ClusterIP 10.105.235.228 <none> 80/TCP 22s 5bug.wang:~/codes/kubernetes/test$ kubectl describe svc my-nginx Name: my-nginx Namespace: default Labels: run=my-nginx Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"run":"my-nginx"},"name":"my-nginx","namespace":"default"},"spe... Selector: run=my-nginx Type: ClusterIP IP: 10.105.235.228 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 172.17.0.3:80,172.17.0.4:80 Session Affinity: None Events: <none>
上面的Endpoints里就是my-nginx服务的pod IP信息,service对关联的Pod具备服务发现能力,当pod销毁的时候会自动从Endpoints移除,有新的Pod启动的时候,会自动将IP端口信息加到Endpoints里。在pod内部可以通过DNS方式进行访问service,规则为:http://{ServiceName}.{NameSpace}.svc,例如:http://my-nginx.default.svc
创建Ingress
my-nginx-ingress.yaml文件内容如下:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-nginx-ingress annotations: # use the shared ingress-nginx kubernetes.io/ingress.class: "nginx" spec: rules: - host: www.5bug.wang http: paths: - path: / backend: serviceName: my-nginx servicePort: 80
说明如下:
kubernetes.io/ingress.class: "nginx":Nginx Ingress Controller 根据该注解自动发现 Ingress
rules的定义:
host 可选,配置对应的域名
path 流量访问匹配路径
backend 描述 serviceName和servicePort
支持绑定多个域名
在使用ingress里指定的域名访问服务之前,需要先将域名解析到集群ingress节点上,否则是访问不通的。
相关文章
- 在Kubernetes里使用openkruise实现服务原地升级功能
- 吾八哥学k8s(十一):kubernetes里Pod的调度机制
- kubernetes中服务自定义Prometheus的metrics的方法
- k8s集群安装Prometheus监控以及Grafana面板的方法
- kubernetes集群证书过期的解决方法
- kubelet启动失败报failed to find cgroups of kubelet的解决方法
- 吾八哥学k8s(九):kubernetes里持久化存储
- macOs和Linux环境下kubectl命令自动补齐的方法
- 吾八哥学k8s(八):kubernetes里Secret的用法
- apps/v1版本下使用client-go实现kubernetes回滚的方法