Go微服务架构实战目录
1. k8s架构介绍
2. 基于k8s的容器化部署
3. 基于k8s的Deployment工作负载
到现在为止我们的服务都是跑在集群内部的,为了让集群外部也能访问,那么我们需要让服务外化,但是因为minikube在mac上是网络不通的,所以我们我们直接就在minikube环境中测试(minikube ssh
进入即可)。
创建pod的service,类型是NodePort
,我们看下svc.yaml:
apiVersion: v1
kind: Service
metadata:
name: k8sdemo-svc # service的服务名称
spec:
ports:
- name: k8sdemo-svc
port: 8000 # service的端口
targetPort: 60001 # 容器服务的端口
selector:
app: k8sdemo # 关联pod
type: NodePort # 对外暴露
创建完成之后,我们可以kubectl get svc
查看是否创建成功
通过上图可以知道service是创建成功的,接下来看下架构图:
随便拿一台机器的公网IP+NodePort就可以访问了,我们这里可以在minikube中验证下:http://$(minikube ip):NodePort
docker@minikube:~$ curl -X POST http://192.168.49.2:30143/hello -d '{"name": "fromGW"}'
{"message":"Hello fromGW from 172.17.0.16:50009"}
可以看到是没有问题的。我们从图中可以看出service是pod的更高一层抽象,负责服务发现和负载均衡,当某个Pod挂掉的时候,service会发现这个问题然后把请求打到别的Pod上。同样当在创建一个带有相同标签的Pod的时候,它会自动加入到service中,然后service会把流量按照某种负载均衡算法分发到各个Pod中。
先安装ingress-nginx,我们先把ingress-nginx下载到本地,然后把镜像地址替换下,防止下载速度慢。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml
sed -i '[email protected]/ingress-nginx/controller:v1.0.0\(.*\)@cnsre/ingress-nginx-controller:v1.0.0@' deploy.yaml
sed -i '[email protected]/ingress-nginx/kube-webhook-certgen:v1.0\(.*\)$@cnsre/ingress-nginx-kube-webhook-certgen:v1.0@' deploy.yaml
通过kubectl apply -f deploy.yaml
安装。
接下来创建我们自己的ingress,这个ingress实现的功能就是路径匹配,重写以及限流,这个yam文件内容如下,ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress # ingress对象
metadata:
name: k8sdemo-ingress-prefix # 验证前缀匹配的
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: hi.k8sdemo.com # 域名
http:
paths:
- path: "/hello" # 前缀匹配
pathType: Prefix
backend:
service:
name: k8sdemo-svc
port:
number: 8000 # service的端口
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8sdemo-ingress-rewrite # 这个ingress是关于验证重写的
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2 # 重写注解
spec:
rules:
- host: hello.k8sdemo.com
http:
paths:
- pathType: Prefix
path: "/api(/|$)(.*)" # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
backend:
service:
name: k8sdemo-svc # 如果是/api/hello 去掉前缀api 用/hello访问服务 网关一般这么搞
port:
number: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8sdemo-ingress-limit-rate
annotations:
nginx.ingress.kubernetes.io/limit-rps: "1" # rps:每秒多少请求 超过之后就报错 https status: 503
spec:
ingressClassName: nginx
rules:
- host: hi.k8sdemo.com
http:
paths:
- pathType: Exact # 精确匹配
path: "/hello" # 针对这个路径限流
backend:
service:
name: k8sdemo-svc
port:
number: 8000
通过kubectl apply -f deploy.yaml
创建。可以查看下是否创建成功:
可以看到这三个ingress绑定了两个host,接下来申请域名绑定ingress的ip地址,即上图中的192.168.49.2。但因为我们是minikube本地测试,所以绑定hosts就可以了。修改/etc/hosts
:
192.168.49.2 hello.k8sdemo.com
192.168.49.2 hi.k8sdemo.com
保存之后我们就可以验证测试了。大致架构图就是:
我们再次看下ingress的svc对外暴露的端口是:可以看到是31721,接下来我们通过域名+端口来访问后端服务。
docker@minikube:~$ curl -X POST http://hi.k8sdemo.com:31721/hello -d '{"name": "fromGW"}'
{"message":"Hello fromGW from 172.17.0.16:50009"}
发现是成功的。
docker@minikube:~$ curl -X POST http://hello.k8sdemo.com:31721/api/hello -d '{"name": "fromGW"}'
{"message":"Hello fromGW from 172.17.0.16:50009"}
发现是成功的。
docker@minikube:~$ curl -X POST http://hi.k8sdemo.com:31721/hello -d '{"name": "fromGW"}'
503 Service Temporarily Unavailable
503 Service Temporarily Unavailable
nginx
当我们一秒请求的/hello
次数大于1的时候报错,nginx返回503,这样就验证了我们的ingress的限流功能。
本小节算是重点,我们要了解ingress如何暴露服务,如何重写路径以及如何限流等。路径重写很重要,比如接口地址是:http://example.gateway.com/user-center/userinfo
和http://example.gateway.com/user-center/userprofile
,网关地址是http://example.gateway.com
,路由到后端服务是userinfo
,那么在网关层为了区分我们的服务,会统一加一层user-center
,这样就可以区分不同业务了,但是user-center
不是我们想要的,我们用它只是区分业务,所以需要在ingress层做下路径重写,这样到后端的服务就没有了user-center
了。
还有基于ingress的限流功能也非常简单,大家可以尝试用起来。
参考:
https://kubernetes.github.io/ingress-nginx/
堆栈future
使很多处于迷茫阶段的coder能从这里找到光明,堆栈创世,功在当代,利在千秋