访问部署在kubernetes集群中服务,有两种类型:
- 集群内部实现访问
- 集群外部实现访问
但是不管是集群内部还是外部访问都是要经过kube-proxy的
集群内部实现访问
ClusterIP
Clusterip是集群内部的私有ip,在集群内部访问服务非常方便,也是kuberentes集群默认的方式,直接通过service的Clusterip访问,也可以直接通过ServiceName访问。集群外部则是无法访问的。
示例
创建nginx服务,提供web服务
nginx-ds.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
创建一个pod作为client
alpine.yaml
apiVersion: v1
kind: Pod
metadata:
name: alpine
spec:
containers:
- name: alpine
image: alpine
command:
- sh
- -c
- while true; do sleep 1; done
应用并测试访问
kubectl create -f nginx-ds.yaml
kubectl create -f alpine.yaml
> kubectl get svc | grep nginx
nginx-svc ClusterIP 10.254.105.39 80/TCP 11m
> kubectl exec -it alpine ping nginx-svc
PING nginx-svc (10.254.105.39): 56 data bytes
64 bytes from 10.254.105.39: seq=0 ttl=64 time=0.073 ms
64 bytes from 10.254.105.39: seq=1 ttl=64 time=0.083 ms
64 bytes from 10.254.105.39: seq=2 ttl=64 time=0.091 ms
64 bytes from 10.254.105.39: seq=3 ttl=64 time=0.088 ms
> kubectl exec -it alpine ping 10.254.105.39
PING 10.254.105.39 (10.254.105.39): 56 data bytes
64 bytes from 10.254.105.39: seq=0 ttl=64 time=0.137 ms
64 bytes from 10.254.105.39: seq=1 ttl=64 time=0.106 ms
64 bytes from 10.254.105.39: seq=2 ttl=64 time=0.083 ms
使用curl访问测试
> kubectl exec -it alpine sh # 默认没有安装curl
/ # apk update && apk upgrade
/ # apk add curl
kubectl exec -it alpine curl http://10.254.105.39
kubectl exec -it alpine curl http://nginx-svc # 都可以访问到nginx默认页面
集群外部方式访问
NodePort
NodePort在kubenretes里是一个早期广泛应用的服务暴露方式。Kubernetes中的service默认情况下都是使用的ClusterIP
这种类型,这样的service会产生一个ClusterIP,这个IP只能在集群内部访问,要想让外部能够直接访问service,需要将service type修改为 nodePort。将service监听端口映射到node节点。
示例
nginx-ds.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30004
protocol: TCP
selector:
name: nginx
创建
kubectl create -f nginx-ds.yaml
访问测试
在集群之外,可以通过任何一个node节点的ip+nodeport
都可以访问集群中服务
> curl http://192.168.16.238:30004
> curl http://192.168.16.239:30004
....
> curl http://192.168.16.243:30004
> curl http://192.168.16.244:30004
LoadBalancer
LoadBlancer Service 是 kubernetes 深度结合云平台的一个组件;当使用 LoadBlancer Service 暴露服务时,实际上是通过向底层云平台申请创建一个负载均衡器来向外暴露服务;目前 LoadBlancer Service 支持的云平台已经相对完善,比如国外的 GCE、DigitalOcean,国内的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度结合了云平台,所以只能在一些云平台上来使用
Ingress
官方文档
Ingress是自kubernetes1.1版本后引入的资源类型。必须要部署Ingress controller才能创建Ingress资源,Ingress controller是以一种插件的形式提供。
使用 Ingress 时一般会有三个组件:
- 反向代理负载均衡器
- Ingress Controller
- Ingress
组件介绍
反向代理负载均衡器
反向代理负载均衡器很简单,类似nginx,haproxy;在集群中反向代理负载均衡器可以自由部署,可以使用 Replication Controller、Deployment、DaemonSet 等等,推荐DaemonSet 的方式部署
Ingress Controller
Ingress Controller 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用
Ingress
Ingress 简单理解就是个规则定义;比如说某个域名对应某个 service,即当某个域名的请求进来时转发给某个 service;这个规则将与 Ingress Controller 结合,然后 Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡
这种方式不需再经过kube-proxy的转发,比LoadBalancer方式更高效。
Traefik使用
Traefik是一款开源的反向代理与负载均衡工具。它最大的优点是能够与常见的微服务系统直接整合,可以实现自动化动态配置。目前支持Docker、Swarm、Mesos/Marathon、 Mesos、Kubernetes、Consul、Etcd、Zookeeper、BoltDB、Rest API等等后端模型。
部署Traefik
创建RBAC授权
获取traefik-rbac.yaml文件并应用,用于service account验证:
wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml #不用修改直接应用就行
> kubectl create -f traefik-rbac.yaml
DaemonSet方式部署Traefik
以 Daemon Set 的方式在每个 node 上启动一个 traefik,并使用 hostPort 的方式让其监听每个 node 的 80 端口
获取yaml文件
wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml
> kubectl get pod,svc -n kube-system | grep traefik
> kubectl get pod,svc -n kube-system | grep traefik
pod/traefik-ingress-controller-7fkp7 1/1 Running 0 10m
pod/traefik-ingress-controller-mqnm9 1/1 Running 0 10m
pod/traefik-ingress-controller-tdg77 1/1 Running 0 10m
service/traefik-ingress-service ClusterIP 10.254.179.212 80/TCP,8080/TCP 22s
Taefik-UI
traefik 本身还提供了一套 UI 供我们使用,其同样以 Ingress 方式暴露
获取yaml文件
wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
> kubectl create -f ui.yaml
- host: traefik-ui.k8s # 可以绑定node节点ip做对应hosts解析
访问web-ui
hosts
192.168.16.238 traefik-ui.k8s
访问
http://traefik-ui.k8s/dashboard/
Ingress
创建nginx服务的暴露规则
nginx-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-traefik
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: nginx.svc
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
kubectl create -f nginx-ingress.yaml
访问测试
hosts
192.168.16.238 nginx.svc
http://nginx.svc
k8s-dahboard的暴露
k8s-dashboard-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dashboard-k8s-traefik
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: dashboard.k8s
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 80 # dashboard使用https则需要改成443
应用并测试
> kubectl create -f k8s-dashboard-ingress.yaml
访问web-ui
hosts
192.168.16.238 dashboard.k8s
http://dashboard.k8s/#!/login
使用token登录
实现Ingress很多service mesh也是可以解决的