前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ambassador网关之小试牛刀

ambassador网关之小试牛刀

作者头像
机械视角
发布2020-05-25 16:54:42
1.4K0
发布2020-05-25 16:54:42
举报
文章被收录于专栏:TensorbytesTensorbytes

Ambassador

这是一个坑…

Ambassador是一个云原生的API网关,主要用于为集群提供南-北网关,对外网流入的流量进行管理,包括限流、鉴权等。

今天这里用ambassador构建一个的鉴权服务。

安装

k8s安装:

代码语言:javascript
复制
kubectl apply -f https://www.getambassador.io/yaml/aes-crds.yaml && \
kubectl wait --for condition=established --timeout=180s crd -lproduct=aes && \
kubectl apply -f https://www.getambassador.io/yaml/aes.yaml && \
kubectl -n ambassador wait --for condition=available --timeout=180s deploy -lproduct=aes

其他安装方式参考安装手册

测试

安装好后,查看services:

代码语言:javascript
复制
$ kubectl get svc -n ambassador
NAME                  TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ambassador            LoadBalancer   10.43.227.83    <pending>     80:31082/TCP,443:32114/TCP   4h4m
ambassador-admin      ClusterIP      10.43.143.56    <none>        8877/TCP                     4h4m
ambassador-redis      ClusterIP      10.43.59.72     <none>        6379/TCP                     4h4m

由于这里没有LB,再启一个node-port:

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ambassador-nodeport
  name: ambassador-nodeport
spec:
  externalTrafficPolicy: Cluster
  ports:
  - name: "80"
    port: 80
    protocol: TCP
    targetPort: http
  - name: "443"
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    service: ambassador
  sessionAffinity: None
  type: NodePort

直接访问机器的即可看到页面:

添加一个后端应用quote:

代码语言:javascript
复制
---
apiVersion: v1
kind: Service
metadata:
  name: quote
  namespace: ambassador
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: http
  selector:
    app: quote
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: quote
  namespace: ambassador
spec:
  replicas: 1
  selector:
    matchLabels:
      app: quote
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: quote
    spec:
      containers:
      - name: backend
        image: registry.cn-shenzhen.aliyuncs.com/shikanon/ambassador-auth-demo:serverv0.1
        ports:
        - name: http
          containerPort: 8080
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: quote-backend
  namespace: ambassador
spec:
  prefix: /backend/
  service: quote

注:这里Deployment的port用name名称叫”http”,所以service可以写成targetPort: http

测试

注意:由于这里用的是Ambassador Edge Stack版本,访问必须用https的端口:

$ kubectl get svc -nambassador NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ambassador LoadBalancer 10.43.86.4 80:32487/TCP,443:31632/TCP 4h9m ambassador-admin ClusterIP 10.43.79.19 8877/TCP 4h9m ambassador-nodeport NodePort 10.43.228.37 80:30930/TCP,443:32089/TCP 7m36s ambassador-redis ClusterIP 10.43.191.197 6379/TCP 4h9m app-auth NodePort 10.43.206.119 80:30176/TCP 27m app-server ClusterIP 10.43.174.101 80/TCP 27m quote ClusterIP 10.43.55.41 80/TCP 7m2s

必须用https访问

$ curl https://10.43.86.4/backend/ –insecure

构建鉴权代码

基于golang构建一个简单的鉴权服务:

代码语言:javascript
复制
package main

import (
	"fmt"
	"net/http"
)

func indexHandler(w http.ResponseWriter, r *http.Request) {
	username := r.URL.Query().Get("username")
	passwd := r.URL.Query().Get("passwd")
	content := fmt.Sprintf("username:%v", username)
	if username == "shikanon" && passwd == "123456" {
		w.WriteHeader(200)
	} else {
		w.WriteHeader(403)
	}
	fmt.Fprintf(w, content)
}

func main() {
	http.HandleFunc("/", indexHandler)
	http.ListenAndServe(":8000", nil)
}

构建一个简单的server服务:

代码语言:javascript
复制
package main

import (
	"fmt"
	"net/http"
)

func indexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "this is server")
}

func main() {
	http.HandleFunc("/lookup", indexHandler)
	http.ListenAndServe(":8080", nil)
}

编写Dockerfile(两个服务的dockerfile类似):

代码语言:javascript
复制
FROM golang:1.14.3-alpine as build

COPY . /app
WORKDIR /app
RUN go build -o auth main.go 
RUN chmod +x ./auth

FROM alpine:latest
LABEL maintainer="hexo-shikanon-blog <shikanon@tensorbytes.com>"

COPY --from=build /app /app
EXPOSE 8000
CMD ["/app/auth"]

不想自己 build 可以直接用我上传到阿里云的镜像仓库:

  • auth: registry.cn-shenzhen.aliyuncs.com/shikanon/ambassador-auth-demo:authv0.1
  • server: registry.cn-shenzhen.aliyuncs.com/shikanon/ambassador-auth-demo:serverv0.1

使用authservice服务

构建server

基于server镜像构建响应服务:

代码语言:javascript
复制
---
apiVersion: apps/v1
kind: Deployment
metadata:
    name: app-server
    namespace: ambassador
    labels: 
        name: app-server
spec:
    replicas: 1
    selector:
        matchLabels:
            name: app-server
    template:
        metadata:
            labels: 
                name: app-server
        spec:
            containers:
              - name: app-server
                image: registry.cn-shenzhen.aliyuncs.com/shikanon/ambassador-auth-demo:serverv0.1
                imagePullPolicy: IfNotPresent
                ports:
                  - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
    name: app-server
    namespace: ambassador
spec:
    ports:
      - name: http
        port: 80
        protocol: TCP
        targetPort: 8080
    selector:
        name: app-server

构建mapping实现ambassador转发:

代码语言:javascript
复制
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
    name: auth-backend-test
    namespace: ambassador
spec:
    prefix: /test/
    host_redirect: true
    service: app-server

测试一下:

$ kubectl get svc -nambassador NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ambassador LoadBalancer 10.43.47.77 80:31290/TCP,443:31952/TCP 12h ambassador-admin ClusterIP 10.43.181.248 8877/TCP 12h ambassador-redis ClusterIP 10.43.65.217 6379/TCP 12h app-server ClusterIP 10.43.56.227 80/TCP 26m

测试效果:

代码语言:javascript
复制
$ curl -L http://10.43.47.77/test2/helloworld --insecure
* About to connect() to 10.43.47.77 port 80 (#0)
*   Trying 10.43.47.77...
* Connected to 10.43.47.77 (10.43.47.77) port 80 (#0)
> GET /test2/helloworld HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.43.47.77
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< location: https://10.43.47.77/test2/helloworld
< date: Fri, 22 May 2020 02:03:46 GMT
< server: envoy
< content-length: 0
< 
* Connection #0 to host 10.43.47.77 left intact
* Issue another request to this URL: 'https://10.43.47.77/test2/helloworld'
* Found bundle for host 10.43.47.77: 0x7fced0
* About to connect() to 10.43.47.77 port 443 (#1)
*   Trying 10.43.47.77...
* Connected to 10.43.47.77 (10.43.47.77) port 443 (#1)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: O=Ambassador Edge Stack Self-Signed
* 	start date: May 21 13:32:32 2020 GMT
* 	expire date: May 21 13:32:32 2021 GMT
* 	common name: (nil)
* 	issuer: O=Ambassador Edge Stack Self-Signed
> GET /test2/helloworld HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.43.47.77
> Accept: */*
> 
< HTTP/1.1 200 OK
< date: Fri, 22 May 2020 02:03:46 GMT
< content-length: 11
< content-type: text/plain; charset=utf-8
< x-envoy-upstream-service-time: 0
< server: envoy
< 
* Connection #1 to host 10.43.47.77 left intact
/helloworld

如果用http协议,这里必须加-L,因为ambassador会强制转成https协议,并返回301进行重定向。

构建authservice

构建好server,下面就可以构建authservice做鉴权验证和转发:

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
    name: app-auth
    namespace: ambassador
    labels:
        name: app-auth
spec:
    replicas: 1
    selector:
        matchLabels:
            name: app-auth
    template:
        metadata:
            labels: 
                name: app-auth
        spec:
            containers:
              - name: app-auth
                image: registry.cn-shenzhen.aliyuncs.com/shikanon/ambassador-auth-demo:authv0.1
                imagePullPolicy: IfNotPresent
                ports:
                  - containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
    name: app-auth
    namespace: ambassador
    annotations:
        getambassador.io/config: |
          ---
          apiVersion: getambassador.io/v2
          kind:  AuthService
          name:  authentication
          auth_service: "app-auth:3000"
          path_prefix: "/extauth"
          allowed_request_headers:
          - "x-qotm-session"
          allowed_authorization_headers:
          - "x-qotm-session"
spec:
    ports:
      - name: http
        port: 80
        protocol: TCP
        targetPort: 8000
    selector:
        name: app-auth
    type: NodePort

这里设置了对extauth的前缀做验证转发,也就是会匹配包含/extauth的url,传给验证服务,验证通过了才转到应用服务。

okay,下面开始测试。

先查看service地址:

$ kubectl get svc -nambassador NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ambassador LoadBalancer 10.43.47.77 80:31290/TCP,443:31952/TCP 12h ambassador-admin ClusterIP 10.43.181.248 8877/TCP 12h ambassador-redis ClusterIP 10.43.65.217 6379/TCP 12h app-auth NodePort 10.43.179.149 80:32711/TCP 12h app-server ClusterIP 10.43.56.227 80/TCP 26m

测试:

代码语言:javascript
复制
$ curl -Lv https://10.43.47.77/extauth/test2/helloworld --insecure

* About to connect() to 10.43.47.77 port 443 (#0)
*   Trying 10.43.47.77...
* Connected to 10.43.47.77 (10.43.47.77) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: O=Ambassador Edge Stack Self-Signed
* 	start date: May 21 13:32:32 2020 GMT
* 	expire date: May 21 13:32:32 2021 GMT
* 	common name: (nil)
* 	issuer: O=Ambassador Edge Stack Self-Signed
> GET /extauth/test2/helloworld HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.43.47.77
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< content-type: text/html; charset=utf-8
< location: /test2/helloworld
< date: Fri, 22 May 2020 02:31:35 GMT
< content-length: 52
< x-envoy-upstream-service-time: 0
< server: envoy
< 
* Ignoring the response-body
* Connection #0 to host 10.43.47.77 left intact
* Issue another request to this URL: 'https://10.43.47.77/test2/helloworld'
* Found bundle for host 10.43.47.77: 0x1c73f20
* Re-using existing connection! (#0) with host 10.43.47.77
* Connected to 10.43.47.77 (10.43.47.77) port 443 (#0)
> GET /test2/helloworld HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.43.47.77
> Accept: */*
> 
< HTTP/1.1 200 OK
< date: Fri, 22 May 2020 02:31:35 GMT
< content-length: 11
< content-type: text/plain; charset=utf-8
< x-envoy-upstream-service-time: 0
< server: envoy
< 
* Connection #0 to host 10.43.47.77 left intact

/helloworld

成功访问!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Ambassador
  • 安装
  • 测试
  • 构建鉴权代码
  • 使用authservice服务
    • 构建server
      • 构建authservice
      相关产品与服务
      容器镜像服务
      容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档