使用Istio的Envoyfilter做kubernetes的出口http拦截

前提

以下步骤均在无法访问docker.io的集群下操作,如果集群可以连接docker.io,则不需要准备镜像包,直接在docker.io中拉取即可

场景

部署在kubernetes中的pod,在往外部请求的时,外部服务期望能知道是哪个pod调用的,以保证数据安全,在外部服务之前,用abac配置了对pod的环境限制,比方说我有两个kubernetes环境,一个是沙箱测试环境,一个是沙箱生产环境。如果abac中配置的策略为只允许在沙箱测试环境调用,当pod在调用外部http接口时,会携带上当前的kubernetes环境的唯一标识。

准备工作

  1. 安装istio需要两个镜像,pilot、proxyv2,确保当前环境的harbor中存在
  2. Istio官网
  3. Istio Github

安装包

istio-1.20.0-linux-amd64.tar.gz

镜像包

pilot.tar
proxyv2.tar

镜像准备

  1. 把镜像包加载到本地docker中
docker load -i pilot.tar
docker load -i proxyv2.tar
  1. 修改镜像tag
docker tag 4bfb4a2c6118 registry-cnp-dev.inspurcloud.cn/istio/pilot:1.20.0
docker tag df8296c1ff53 registry-cnp-dev.inspurcloud.cn/istio/proxyv2:1.20.0
  1. 推送镜像
docker push registry-cnp-dev.inspurcloud.cn/istio/pilot:1.20.0
docker push registry-cnp-dev.inspurcloud.cn/istio/proxyv2:1.20.0

安装istio

  1. 解压istio
tar -xvf istio-1.20.0-linux-amd64.tar.gz
  1. 修改istio安装的配置文件
cd istio-1.20.0/manifests/profiles/
vim demo.yaml

#### spec下增加hub和tag,hub的地址为当前环境的仓库域名 后面加上/istio
spec:
	hub: xxxxxx/istio
	tag: 1.20.0
  1. 配置环境变量
  2. 执行安装命令
istioctl install --set profile=demo -y

执行完安装命令后,再打开一个ssh窗口

  1. 查询kubernetes的deployment
kubectl get deploy -n istio-system

#### 结果
root@master01:~# kubectl get deploy -n istio-system
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
istiod   0/1     1            0           69s
  1. 修改deployment的yaml
kubectl edit deploy -n istio-system istiod


#### 在spec.template.spec下增加下面配置,指定调度到master01节点上
nodeSelector:
  kubernetes.io/hostname: master01

### 检查spec.template.spec.containers.image 是否正确,如果不正确,需要改成当前环境的仓库域名(镜像准备时推送的harbor仓库地址)
image: docker.io/istio/pilot:1.20.0 # 默认是docker.io,需要改成xxxxxxx

### 修改完毕之后,用esc ---> :wq 保存

重复执行4,查询下状态,直到istiod的READY是 1/1,证明启动成功

root@master01:~# kubectl get deploy -n istio-system
NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
istio-egressgateway    0/1     1            0           2m22s
istio-ingressgateway   0/1     1            0           2m22s
istiod                 1/1     1            1           7m28s

可以看到又出现了两个deployment,按照上述的步骤5,把istio-egressgateway和istio-ingressgateway的配置修改
注意:命令中修改哪个deployment名字,需要修改,把istiod改为要修改的deployment
例如:kubectl edit deploy -n istio-system istio-ingressgateway

直到3个deployment都启动成功,就可以进行部署EnvoyFilter了

root@master01:~# kubectl get deploy -n istio-system
NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
istio-egressgateway    1/1     1            1           9m2s
istio-ingressgateway   1/1     1            1           9m2s
istiod                 1/1     1            1           14m

部署EnvoyFilter

  1. 创建envoyfilter.yaml
vim envoyfilter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: my-envoy-filter
  namespace: ibp-test
spec:
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_OUTBOUND
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
              subFilter:
                name: "envoy.filters.http.router"
      patch:
        operation: INSERT_BEFORE
        value:
          name: add-pod-header
          typed_config:
            "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
            inlineCode: |
              function envoy_on_request(request_handle)
                local authority = request_handle:headers():get("host")
                local ip_pattern = "(%d+.%d+.%d+.%d+)"
                local ip = string.match(authority, ip_pattern)
                if ip == "xxxxx" or ip == "xxxxx" then
                  local pod_name = os.getenv("POD_NAME") or "unknown_pod"
                  request_handle:headers():add("X-POD-NAME", pod_name)
                  request_handle:headers():add("X-SPACE", "FUNCTION")
                end
              end
  1. 开启自动注入
kubectl label namespace ibp-test istio-injection=enabled
  1. 应用 EnvoyFilter 到 Kubernetes 集群
kubectl apply -f envoyfilter.yaml
  1. 验证部署
kubectl get envoyfilter -n ibp-test

注意:历史的pod需要重启才会生效!

创建http流量

在envoyfilter中,只会拦截被视为http流量的端点,所以还需要另外创建http流量,使envoyfilter拦截生效

  1. 创建envoy-filter-open-ports.yaml
apiVersion: v1
kind: Service
metadata:
  name: envoy-filter-open-ports
  namespace: ibp-test
spec:
  ports:
    - name: http-9234
      protocol: TCP
      port: 9234
      targetPort: 9234
    - name: http-9001
      protocol: TCP
      port: 9001
      targetPort: 9001
    - name: http-20040
      protocol: TCP
      port: 7082
      targetPort: 7082
  type: ClusterIP
  1. kubernetes创建service
kubectl create -f envoy-filter-open-ports.yaml

卸载

istioctl uninstall -y --purge

版本对照关系

Pasted image 20231207091038.png
Pasted image 20231212153631.png

问题汇总

Q: 启动pod的时候,还是会去docker.io中拉取镜像启动initContainer
A: deployment配置如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      annotations:
        "sidecar.istio.io/proxyImage": docker.io/istio/proxyv2:1.20.0 # 这里修改具体的镜像仓库
      labels:
        app: httpbin
        version: v1
    spec:
      serviceAccountName: httpbin
      containers:
      - image: docker.io/kong/httpbin
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80
  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在Spring Boot和Vue中使用JSESSIONID登录拦截可以通过以下步骤实现: 1. 后端配置:在Spring Boot中,可以通过配置Spring Security来实现JSESSIONID的登录拦截。在Spring Security中,可以使用`http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)`来禁用CSRF保护和使用无状态会话管理策略。然后,使用`http.authorizeRequests().anyRequest().authenticated().and().formLogin()`来配置所有请求都需要进行身份验证,并使用表单登录进行身份验证。在身份验证成功后,将用户的身份信息放入会话中。这样,每个会话都将有一个唯一的JSESSIONID,可以用于登录拦截。 2. 前端配置:在Vue中,可以使用axios拦截器来拦截所有请求,并将JSESSIONID放入请求头中。具体来说,可以在axios中使用`withCredentials: true`来启用跨域请求携带cookie。在拦截器中,可以使用`config.headers['JSESSIONID'] = cookie.get('JSESSIONID')`将JSESSIONID放入请求头中。然后,将axios实例导出,以便在整个应用程序中使用。这样,每个请求都将携带JSESSIONID,可以用于登录拦截。 3. 登录拦截:在Vue中,可以使用路由守卫来实现登录拦截。在路由守卫中,可以使用`router.beforeEach((to, from, next) => {if (to.meta.requireAuth) {// 判断该路由是否需要登录权限if (store.state.token) {// 通过vuex state获取当前的token是否存在next();} else {// 否则跳转到登录页面next({path: '/login',query: {redirect: to.fullPath}});}} else {next();}});`来判断路由是否需要登录权限,并判断用户是否已经登录。如果用户已经登录,则允许访问该路由,否则跳转到登录页面。 综上所述,在Spring Boot和Vue中使用JSESSIONID登录拦截,需要在后端和前端分别进行配置,并使用路由守卫来实现登录拦截
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值