[type:feat]:init ingress controller sofa (#5253)

* [type:feat]:init ingress controller grpc

* [type:feat]:init ingress controller grpc
diff --git a/.github/workflows/integrated-test-k8s-ingress.yml b/.github/workflows/integrated-test-k8s-ingress.yml
index 2839b2a..e8766fc 100644
--- a/.github/workflows/integrated-test-k8s-ingress.yml
+++ b/.github/workflows/integrated-test-k8s-ingress.yml
@@ -34,6 +34,7 @@
           - shenyu-integrated-test-k8s-ingress-websocket
           - shenyu-integrated-test-k8s-ingress-brpc
           - shenyu-integrated-test-k8s-ingress-grpc
+          - shenyu-integrated-test-k8s-ingress-sofa
     runs-on: ubuntu-latest
     if: github.repository == 'apache/shenyu'
     steps:
diff --git a/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/ingress.yml b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/ingress.yml
new file mode 100644
index 0000000..d26dc07
--- /dev/null
+++ b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/ingress.yml
@@ -0,0 +1,87 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+apiVersion: v1
+kind: Service
+metadata:
+  name: sofa-find-id
+  namespace: shenyu-ingress
+  annotations:
+    kubernetes.io/ingress.class: shenyu
+    shenyu.apache.org/plugin-sofa-enabled: 'true'
+    shenyu.apache.org/plugin-sofa-app-name: sofa
+    shenyu.apache.org/plugin-context-path-path: /sofa
+    shenyu.apache.org/plugin-sofa-path: /sofa/findById
+    shenyu.apache.org/plugin-sofa-rpc-type: sofa
+    shenyu.apache.org/plugin-sofa-service-name: org.apache.shenyu.examples.sofa.api.service.SofaSingleParamService
+    shenyu.apache.org/plugin-sofa-method-name: findById
+    shenyu.apache.org/plugin-sofa-params-type: java.lang.String
+    shenyu.apache.org/plugin-sofa-rpc-expand: |
+      {"loadbalance":"hash","retries":3,"timeout":-1}
+spec:
+  selector:
+    app: shenyu-examples-sofa
+  ports:
+    - port: 8888
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: sofa-find-all
+  namespace: shenyu-ingress
+  annotations:
+    kubernetes.io/ingress.class: shenyu
+    shenyu.apache.org/plugin-sofa-enabled: 'true'
+    shenyu.apache.org/plugin-context-path-path: /sofa
+    shenyu.apache.org/plugin-sofa-app-name: sofa
+    shenyu.apache.org/plugin-sofa-path: /sofa/findAll
+    shenyu.apache.org/plugin-sofa-rpc-type: sofa
+    shenyu.apache.org/plugin-sofa-service-name: org.apache.shenyu.examples.sofa.api.service.SofaSingleParamService
+    shenyu.apache.org/plugin-sofa-method-name: findAll
+    shenyu.apache.org/plugin-sofa-rpc-expand: |
+      {"loadbalance":"hash","retries":3,"timeout":-1}
+spec:
+  selector:
+    app: shenyu-examples-sofa
+  ports:
+    - port: 8888
+
+---
+
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  namespace: shenyu-ingress
+  labels:
+    shenyu.apache.org/metadata-labels-1: sofa-find-id
+    shenyu.apache.org/metadata-labels-2: sofa-find-all
+  annotations:
+    kubernetes.io/ingress.class: shenyu
+    shenyu.apache.org/plugin-sofa-enabled: 'true'
+    shenyu.apache.org/zookeeper-register-address: shenyu-zk:2181
+  name: demo-ingress
+spec:
+  rules:
+    - http:
+        paths:
+          - backend:
+              service:
+                name: shenyu-examples-sofa
+                port:
+                  number: 8888
+            path: /sofa/
+            pathType: Prefix
diff --git a/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/shenyu-examples-sofa.yml b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/shenyu-examples-sofa.yml
new file mode 100644
index 0000000..5bc7ee0
--- /dev/null
+++ b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/shenyu-examples-sofa.yml
@@ -0,0 +1,84 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: shenyu-examples-sofa-deployment
+  namespace: shenyu-ingress
+  labels:
+    app: shenyu-examples-sofa
+    all: shenyu-examples-sofa
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: shenyu-examples-sofa
+      all: shenyu-examples-sofa
+  strategy: {}
+  template:
+    metadata:
+      labels:
+        app: shenyu-examples-sofa
+        all: shenyu-examples-sofa
+    spec:
+      containers:
+        - image: shenyu-examples-sofa
+          name: shenyu-examples-sofa
+          livenessProbe:
+            exec:
+              command:
+                - wget -q -O - http://localhost:8081/actuator/health | grep UP || exit 1
+            initialDelaySeconds: 10
+            failureThreshold: 3
+            timeoutSeconds: 2
+          env:
+            - name: shenyu.register.serverLists
+              value: http://shenyu-admin:9095
+            - name: com.alipay.sofa.rpc.registry-address
+              value: zookeeper://shenyu-zk:2181
+          ports:
+            - containerPort: 28011
+            - containerPort: 8888
+          imagePullPolicy: IfNotPresent
+      restartPolicy: Always
+status: {}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: shenyu-examples-sofa-service
+  namespace: shenyu-ingress
+  labels:
+    app: shenyu-examples-sofa
+    all: shenyu-examples-sofa
+spec:
+  selector:
+    app: shenyu-examples-sofa
+    all: shenyu-examples-sofa
+  type: NodePort
+  ports:
+    - name: "8888"
+      port: 8888
+      targetPort: 8888
+      nodePort: 31111
+    - name: "28011"
+      port: 28011
+      targetPort: 28011
+      nodePort: 31112
+status:
+  loadBalancer: {}
diff --git a/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/shenyu-zookeeper.yml b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/shenyu-zookeeper.yml
new file mode 100644
index 0000000..8f4f193
--- /dev/null
+++ b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/shenyu-zookeeper.yml
@@ -0,0 +1,87 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: shenyu-ingress
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  namespace: shenyu-ingress
+  labels:
+    app: shenyu-zk
+    all: shenyu-examples-sofa
+  name: shenyu-zk
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: shenyu-zk
+      all: shenyu-examples-sofa
+  strategy: {}
+  template:
+    metadata:
+      namespace: shenyu-ingress
+      labels:
+        app: shenyu-zk
+        all: shenyu-examples-sofa
+    spec:
+      containers:
+        - image: zookeeper:latest
+          name: shenyu-zk
+          resources: {}
+          ports:
+            - containerPort: 2181
+              name: client
+            - containerPort: 2888
+              name: server
+            - containerPort: 3888
+              name: leader-election
+            - containerPort: 8080
+              name: website
+      restartPolicy: Always
+status: {}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: shenyu-zk
+  namespace: shenyu-ingress
+  labels:
+    app: shenyu-zk
+    all: shenyu-examples-sofa
+spec:
+  type: NodePort
+  selector:
+    app: shenyu-zk
+    all: shenyu-examples-sofa
+  ports:
+    - name: "client"
+      port: 2181
+      targetPort: 2181
+    - name: "server"
+      port: 2888
+      targetPort: 2888
+    - name: "election"
+      port: 3888
+      targetPort: 3888
+    - name: "website"
+      port: 8080
+      targetPort: 8080
diff --git a/shenyu-integrated-test/pom.xml b/shenyu-integrated-test/pom.xml
index 81b29a3..dd767cf 100644
--- a/shenyu-integrated-test/pom.xml
+++ b/shenyu-integrated-test/pom.xml
@@ -53,6 +53,7 @@
         <module>shenyu-integrated-test-k8s-ingress-websocket</module>
         <module>shenyu-integrated-test-k8s-ingress-brpc</module>
         <module>shenyu-integrated-test-k8s-ingress-grpc</module>
+        <module>shenyu-integrated-test-k8s-ingress-sofa</module>
     </modules>
 
     <properties>
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/Dockerfile b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/Dockerfile
new file mode 100644
index 0000000..db79bc5
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/Dockerfile
@@ -0,0 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM openjdk:8-jre-alpine
+
+ENV APP_NAME shenyu-integrated-test-k8s-ingress-sofa
+ENV LOCAL_PATH /opt/${APP_NAME}
+
+RUN mkdir -p ${LOCAL_PATH}
+
+ADD target/${APP_NAME}.jar ${LOCAL_PATH}
+
+WORKDIR ${LOCAL_PATH}
+EXPOSE 9195
+
+CMD java -jar ${APP_NAME}.jar
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/deploy/deploy-shenyu.yaml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/deploy/deploy-shenyu.yaml
new file mode 100644
index 0000000..a38325b
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/deploy/deploy-shenyu.yaml
@@ -0,0 +1,103 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+automountServiceAccountToken: true
+kind: ServiceAccount
+metadata:
+  name: shenyu-ingress-controller
+  namespace: shenyu-ingress
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: shenyu-ingress-controller
+  namespace: shenyu-ingress
+  labels:
+    app: shenyu-ingress-controller
+    all: shenyu-ingress-controller
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: shenyu-ingress-controller
+  template:
+    metadata:
+      labels:
+        app: shenyu-ingress-controller
+    spec:
+      containers:
+      - name: shenyu-ingress-controller
+        image: apache/shenyu-integrated-test-k8s-ingress-sofa:latest
+        ports:
+        - containerPort: 9195
+        imagePullPolicy: IfNotPresent
+      serviceAccountName: shenyu-ingress-controller
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: shenyu-ingress-controller
+  namespace: shenyu-ingress
+spec:
+  selector:
+    app: shenyu-ingress-controller
+  type: NodePort
+  ports:
+    - port: 9195
+      targetPort: 9195
+      nodePort: 30095
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: shenyu-ingress-controller
+  namespace: shenyu-ingress
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - namespaces
+  - services
+  - endpoints
+  - secrets
+  - pods
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - networking.k8s.io
+  resources:
+  - ingresses
+  verbs:
+  - get
+  - list
+  - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: shenyu-ingress-controller
+  namespace: shenyu-ingress
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: shenyu-ingress-controller
+subjects:
+- kind: ServiceAccount
+  name: shenyu-ingress-controller
+  namespace: shenyu-ingress
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/deploy/kind-config.yaml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/deploy/kind-config.yaml
new file mode 100644
index 0000000..18b7da9
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/deploy/kind-config.yaml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kind: Cluster
+apiVersion: kind.x-k8s.io/v1alpha4
+nodes:
+  - role: control-plane
+    kubeadmConfigPatches:
+      - |
+        kind: InitConfiguration
+        nodeRegistration:
+          kubeletExtraArgs:
+            node-labels: "ingress-ready=true"
+    extraPortMappings:
+      - containerPort: 80
+        hostPort: 80
+        protocol: TCP
+      - containerPort: 443
+        hostPort: 443
+        protocol: TCP
+      - containerPort: 30095
+        hostPort: 30095
+        protocol: TCP
\ No newline at end of file
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/pom.xml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/pom.xml
new file mode 100644
index 0000000..6c2052b
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.shenyu</groupId>
+        <artifactId>shenyu-integrated-test</artifactId>
+        <version>2.6.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>shenyu-integrated-test-k8s-ingress-sofa</artifactId>
+    <name>shenyu-integrated-test-k8s-ingress-sofa</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.alipay.sofa</groupId>
+            <artifactId>sofa-rpc-all</artifactId>
+            <version>5.7.6</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>net.jcip</groupId>
+                    <artifactId>jcip-annotations</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>io.grpc</groupId>
+                    <artifactId>grpc-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-client</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-framework</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-recipes</artifactId>
+            <version>4.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-sofa</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-plugin-jwt</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-integrated-test-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- shenyu kubernetes controller begin -->
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spring-boot-starter-k8s</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- shenyu kubernetes controller end -->
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>it</id>
+            <properties>
+                <docker.buildArg.APP_NAME>shenyu-integrated-test-k8s-ingress-sofa</docker.buildArg.APP_NAME>
+                <docker.image.tag.repo>apache/shenyu-integrated-test-k8s-ingress-sofa</docker.image.tag.repo>
+                <docker.image.tag.tagName>latest</docker.image.tag.tagName>
+            </properties>
+            <build>
+                <finalName>shenyu-integrated-test-k8s-ingress-sofa</finalName>
+                <plugins>
+                    <plugin>
+                        <groupId>org.springframework.boot</groupId>
+                        <artifactId>spring-boot-maven-plugin</artifactId>
+                        <version>${spring-boot.version}</version>
+                        <executions>
+                            <execution>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>repackage</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <mainClass>org.apache.shenyu.integrated.test.k8s.ingress.sofa.SofaIngressControllerIntegratedBootstrap
+                            </mainClass>
+                            <executable>true</executable>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>io.fabric8</groupId>
+                        <artifactId>docker-maven-plugin</artifactId>
+                        <version>${docker-maven-plugin.version}</version>
+                        <configuration>
+                            <images>
+                                <image>
+                                    <name>apache/shenyu-integrated-test-k8s-ingress-sofa</name>
+                                    <build>
+                                        <contextDir>${project.basedir}</contextDir>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>start</id>
+                                <goals>
+                                    <goal>build</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <skipTests>false</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/build_k8s_cluster.sh b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/build_k8s_cluster.sh
new file mode 100644
index 0000000..4d5cecc
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/build_k8s_cluster.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+kind load docker-image "shenyu-examples-sofa:latest"
+kind load docker-image "apache/shenyu-integrated-test-k8s-ingress-sofa:latest"
+kubectl apply -f ./shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s//shenyu-zookeeper.yml
+kubectl wait --for=condition=Ready pod -l app=shenyu-zk -n shenyu-ingress
+kubectl apply -f ./shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/shenyu-examples-sofa.yml
+kubectl apply -f ./shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/deploy/deploy-shenyu.yaml
+kubectl apply -f ./shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/k8s/ingress.yml
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/healthcheck.sh b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/healthcheck.sh
new file mode 100644
index 0000000..22a7603
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/healthcheck.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PRGDIR=`dirname "$0"`
+for service in `grep -v -E "^$|^#" ${PRGDIR}/services.list`
+do
+    for loop in `seq 1 30`
+    do
+        status=`curl -o /dev/null -s -w %{http_code} $service`
+        echo -e "curl $service response $status"
+
+        if [ $status -eq 200  ]; then
+            break
+        fi
+
+        sleep 2
+    done
+done
+
+sleep 3
+echo -e "\n-------------------"
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/services.list b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/services.list
new file mode 100644
index 0000000..ef0e742
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/script/services.list
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+http://localhost:30095/actuator/health
+http://localhost:31184/actuator/health
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/SofaIngressControllerIntegratedBootstrap.java b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/SofaIngressControllerIntegratedBootstrap.java
new file mode 100644
index 0000000..d6513ab
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/SofaIngressControllerIntegratedBootstrap.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.integrated.test.k8s.ingress.sofa;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The type sofa integrated bootstrap.
+ */
+@SpringBootApplication
+public class SofaIngressControllerIntegratedBootstrap {
+    /**
+     * main method of app.
+     *
+     * @param args args
+     */
+    public static void main(final String[] args) {
+        SpringApplication.run(SofaIngressControllerIntegratedBootstrap.class);
+    }
+}
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/dto/SofaTestData.java b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/dto/SofaTestData.java
new file mode 100644
index 0000000..3956aa6
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/dto/SofaTestData.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.integrated.test.k8s.ingress.sofa.dto;
+
+public class SofaTestData {
+
+    private String id;
+
+    private String name;
+
+    /**
+     * get id.
+     *
+     * @return id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * get name.
+     *
+     * @return name
+     */
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return "SofaTest{"
+                + "id='" + id + '\''
+                + ", name='" + name + '\''
+                + '}';
+    }
+}
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/resources/application-local.yml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/resources/application-local.yml
new file mode 100644
index 0000000..643c441
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/resources/application-local.yml
@@ -0,0 +1,55 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+server:
+  port: 9195
+  address: 0.0.0.0
+
+spring:
+  main:
+    allow-bean-definition-overriding: true
+  application:
+    name: shenyu-bootstrap
+
+management:
+  health:
+    defaults:
+      enabled: false
+
+shenyu:
+  switchConfig:
+    local: true
+  cross:
+    enabled: true
+  exclude:
+    enabled: true
+    paths:
+      - /favicon.ico
+      - /actuator/health
+  local:
+    enabled: true
+    sha512Key: "BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413"
+  sharedPool:
+    enable: true
+
+logging:
+  level:
+    root: info
+    org.springframework.boot: info
+    org.apache.ibatis: info
+    org.apache.shenyu.bonuspoint: info
+    org.apache.shenyu.lottery: info
+    org.apache.shenyu: info
+
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/resources/application.yml b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/resources/application.yml
new file mode 100644
index 0000000..393ad24
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/main/resources/application.yml
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+spring:
+  profiles:
+    active: local
diff --git a/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/SofaPluginShareThreadPoolTest.java b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/SofaPluginShareThreadPoolTest.java
new file mode 100644
index 0000000..a8bc54f
--- /dev/null
+++ b/shenyu-integrated-test/shenyu-integrated-test-k8s-ingress-sofa/src/test/java/org/apache/shenyu/integrated/test/k8s/ingress/sofa/SofaPluginShareThreadPoolTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.integrated.test.k8s.ingress.sofa;
+
+import com.google.gson.reflect.TypeToken;
+import org.apache.shenyu.integrated.test.k8s.ingress.sofa.dto.SofaTestData;
+import org.apache.shenyu.integratedtest.common.AbstractPluginDataInit;
+import org.apache.shenyu.integratedtest.common.helper.HttpHelper;
+import org.hamcrest.core.Is;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class SofaPluginShareThreadPoolTest extends AbstractPluginDataInit {
+
+    private static final HttpHelper HTTP_HELPER = HttpHelper.INSTANCE;
+
+    @BeforeAll
+    public static void setup() {
+        HTTP_HELPER.setGatewayEndpoint("http://localhost:30095");
+    }
+
+    @Test
+    public void testHelloWorld() throws IOException {
+        SofaTestData response = HttpHelper.INSTANCE.getFromGateway("/sofa/findById?id=1001", new TypeToken<SofaTestData>() { }.getType());
+        assertThat(response.getName(), Is.is("hello world shenyu Sofa, findById"));
+        assertThat(response.getId(), Is.is("1001"));
+    }
+}
diff --git a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java
index e20cfa5..1f8ef13 100644
--- a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java
+++ b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/common/IngressConstants.java
@@ -218,4 +218,37 @@
 
     //The configuration key to specify the Grpc parameter type for the plugin, in string
     public static final String PLUGIN_GRPC_PARAMETER_TYPE = "shenyu.apache.org/plugin-grpc-parameter-type";
+
+    //The configuration key to specify the Sofa application name for the plugin, in string
+    public static final String PLUGIN_SOFA_APP_NAME = "shenyu.apache.org/plugin-sofa-app-name";
+
+    //The configuration key to specify the Sofa service name for the plugin, in string
+    public static final String PLUGIN_SOFA_SERVICE_NAME = "shenyu.apache.org/plugin-sofa-service-name";
+
+    //The configuration key to specify the Sofa method name for the plugin, in string
+    public static final String PLUGIN_SOFA_METHOD_NAME = "shenyu.apache.org/plugin-sofa-method-name";
+
+    //The configuration key to specify the Sofa params type for the plugin, in string
+    public static final String PLUGIN_SOFA_PARAMS_TYPE = "shenyu.apache.org/plugin-sofa-params-type";
+
+    //The configuration key to specify the Sofa rpc type for the plugin, in string
+    public static final String PLUGIN_SOFA_RPC_TYPE = "shenyu.apache.org/plugin-sofa-rpc-type";
+
+    //The configuration key to specify the Sofa context path for the plugin, in string
+    public static final String PLUGIN_SOFA_CONTEXT_PATH = "shenyu.apache.org/plugin-sofa-context-path";
+
+    //The configuration key to specify the Sofa path for the plugin, in string
+    public static final String PLUGIN_SOFA_PATH = "shenyu.apache.org/plugin-sofa-path";
+
+    //The configuration key to specify the Sofa enabled for the plugin, in string
+    public static final String PLUGIN_SOFA_ENABLED = "shenyu.apache.org/plugin-sofa-enabled";
+
+    //The configuration key to specify the Sofa rpc expand for the plugin, in string
+    public static final String PLUGIN_SOFA_RPC_EXPAND = "shenyu.apache.org/plugin-sofa-rpc-expand";
+
+    //The configuration key to specify the Sofa parameter type for the plugin, in string
+    public static final String PLUGIN_SOFA_PARAMETER_TYPE = "shenyu.apache.org/plugin-sofa-parameter-type";
+
+    //The configuration key to specify the Sofa parameter type for the plugin, in string
+    public static final String PLUGIN_SOFA_RPC_EXT = "shenyu.apache.org/plugin-sofa-rpc-ext";
 }
diff --git a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
index 6d9f2b1..99c1c42 100644
--- a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
+++ b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/IngressParser.java
@@ -71,8 +71,9 @@
         boolean webSocketEnabled = getBooleanAnnotation(ingress, IngressConstants.PLUGIN_WEB_SOCKET_ENABLED);
         boolean brpcEnabled = getBooleanAnnotation(ingress, IngressConstants.PLUGIN_BRPC_ENABLED);
         boolean grpcEnabled = getBooleanAnnotation(ingress, IngressConstants.PLUGIN_GRPC_ENABLED);
+        boolean sofaEnabled = getBooleanAnnotation(ingress, IngressConstants.PLUGIN_SOFA_ENABLED);
 
-        if (!dubboEnabled || !motanEnabled) {
+        if (!dubboEnabled || !motanEnabled || !sofaEnabled) {
             contextPathParse(ingress, shenyuMemoryConfigList, coreV1Api);
         }
         if (dubboEnabled) {
@@ -93,6 +94,9 @@
         } else if (grpcEnabled) {
             GrpcParser grpcParser = new GrpcParser(serviceLister, endpointsLister);
             shenyuMemoryConfigList.add(grpcParser.parse(ingress, coreV1Api));
+        } else if (sofaEnabled) {
+            SofaParser sofaParser = new SofaParser(serviceLister, endpointsLister);
+            shenyuMemoryConfigList.add(sofaParser.parse(ingress, coreV1Api));
         } else {
             DivideIngressParser divideIngressParser = new DivideIngressParser(serviceLister, endpointsLister);
             shenyuMemoryConfigList.add(divideIngressParser.parse(ingress, coreV1Api));
diff --git a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/SofaParser.java b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/SofaParser.java
new file mode 100644
index 0000000..c8ff4a2
--- /dev/null
+++ b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/parser/SofaParser.java
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.k8s.parser;
+
+import io.kubernetes.client.informer.cache.Lister;
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+import io.kubernetes.client.openapi.models.V1Endpoints;
+import io.kubernetes.client.openapi.models.V1HTTPIngressPath;
+import io.kubernetes.client.openapi.models.V1Ingress;
+import io.kubernetes.client.openapi.models.V1IngressBackend;
+import io.kubernetes.client.openapi.models.V1IngressRule;
+import io.kubernetes.client.openapi.models.V1IngressServiceBackend;
+import io.kubernetes.client.openapi.models.V1IngressTLS;
+import io.kubernetes.client.openapi.models.V1Secret;
+import io.kubernetes.client.openapi.models.V1Service;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.shenyu.common.config.ssl.SslCrtAndKeyStream;
+import org.apache.shenyu.common.dto.ConditionData;
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.common.dto.convert.rule.impl.SofaRuleHandle;
+import org.apache.shenyu.common.enums.LoadBalanceEnum;
+import org.apache.shenyu.common.enums.MatchModeEnum;
+import org.apache.shenyu.common.enums.OperatorEnum;
+import org.apache.shenyu.common.enums.ParamTypeEnum;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.common.enums.SelectorTypeEnum;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.k8s.common.IngressConfiguration;
+import org.apache.shenyu.k8s.common.IngressConstants;
+import org.apache.shenyu.k8s.common.ShenyuMemoryConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Parser of Ingress Sofa Annotations.
+ */
+public class SofaParser implements K8sResourceParser<V1Ingress> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SofaParser.class);
+
+    private final Lister<V1Service> serviceLister;
+
+    private final Lister<V1Endpoints> endpointsLister;
+
+    /**
+     * SofaIngressParser Constructor.
+     *
+     * @param serviceInformer   serviceInformer
+     * @param endpointsInformer endpointsInformer
+     */
+    public SofaParser(final Lister<V1Service> serviceInformer, final Lister<V1Endpoints> endpointsInformer) {
+        this.serviceLister = serviceInformer;
+        this.endpointsLister = endpointsInformer;
+    }
+
+    /**
+     * Parse ingress to ShenyuMemoryConfig.
+     *
+     * @param ingress   ingress resource
+     * @param coreV1Api coreV1Api
+     * @return ShenyuMemoryConfig
+     */
+    @Override
+    public ShenyuMemoryConfig parse(final V1Ingress ingress, final CoreV1Api coreV1Api) {
+        ShenyuMemoryConfig res = new ShenyuMemoryConfig();
+
+        if (Objects.nonNull(ingress.getSpec())) {
+            // Parse the sofa backend
+            V1IngressBackend sofaBackend = ingress.getSpec().getDefaultBackend();
+            List<V1IngressRule> rules = ingress.getSpec().getRules();
+            List<V1IngressTLS> tlsList = ingress.getSpec().getTls();
+
+            String namespace = Objects.requireNonNull(ingress.getMetadata()).getNamespace();
+
+            if (Objects.isNull(rules) || CollectionUtils.isEmpty(rules)) {
+                // if rules is null, sofaBackend become global default
+                if (Objects.nonNull(sofaBackend) && Objects.nonNull(sofaBackend.getService())) {
+                    IngressConfiguration defaultRouteConfig = getSofaRouteConfig(ingress.getMetadata().getAnnotations());
+                    res.setGlobalDefaultBackend(Pair.of(Pair.of(namespace + "/" + ingress.getMetadata().getName(), sofaBackend.getService().getName()),
+                            defaultRouteConfig));
+                }
+            } else {
+                // if rules is not null, sofaBackend is default in this ingress
+                List<IngressConfiguration> routeList = new ArrayList<>(rules.size());
+                for (V1IngressRule ingressRule : rules) {
+                    List<IngressConfiguration> routes = parseIngressRule(ingressRule,
+                            Objects.requireNonNull(ingress.getMetadata()).getNamespace(), ingress.getMetadata().getAnnotations(), ingress.getMetadata().getLabels());
+                    routeList.addAll(routes);
+                }
+                res.setRouteConfigList(routeList);
+            }
+
+            // Parse tls
+            if (Objects.nonNull(tlsList) && CollectionUtils.isNotEmpty(tlsList)) {
+                List<SslCrtAndKeyStream> sslList = new ArrayList<>();
+                for (V1IngressTLS tls : tlsList) {
+                    if (Objects.nonNull(tls.getSecretName()) && Objects.nonNull(tls.getHosts()) && CollectionUtils.isNotEmpty(tls.getHosts())) {
+                        try {
+                            V1Secret secret = coreV1Api.readNamespacedSecret(tls.getSecretName(), namespace, "ture");
+                            if (secret.getData() != null) {
+                                InputStream keyCertChainInputStream = new ByteArrayInputStream(secret.getData().get("tls.crt"));
+                                InputStream keyInputStream = new ByteArrayInputStream(secret.getData().get("tls.key"));
+                                tls.getHosts().forEach(host ->
+                                        sslList.add(new SslCrtAndKeyStream(host, keyCertChainInputStream, keyInputStream))
+                                );
+                            }
+                        } catch (ApiException e) {
+                            LOG.error("parse tls failed ", e);
+                        }
+                    }
+                }
+                res.setTlsConfigList(sslList);
+            }
+        }
+        return res;
+    }
+
+    private String parsePort(final V1IngressServiceBackend service) {
+        if (Objects.nonNull(service.getPort())) {
+            if (service.getPort().getNumber() != null && service.getPort().getNumber() > 0) {
+                return String.valueOf(service.getPort().getNumber());
+            } else if (service.getPort().getName() != null && !"".equals(service.getPort().getName().trim())) {
+                return service.getPort().getName().trim();
+            }
+        }
+        return null;
+    }
+
+    private List<IngressConfiguration> parseIngressRule(final V1IngressRule ingressRule,
+                                                        final String namespace,
+                                                        final Map<String, String> annotations,
+                                                        final Map<String, String> labels) {
+        List<IngressConfiguration> res = new ArrayList<>();
+        ConditionData hostCondition = Objects.nonNull(ingressRule.getHost()) ? createHostCondition(ingressRule.getHost()) : null;
+        if (Objects.nonNull(ingressRule.getHttp())) {
+            List<V1HTTPIngressPath> paths = ingressRule.getHttp().getPaths();
+            if (Objects.nonNull(paths)) {
+                for (V1HTTPIngressPath path : paths) {
+                    if (path.getPath() == null) {
+                        continue;
+                    }
+                    OperatorEnum operator = getOperator(path.getPathType());
+                    ConditionData pathCondition = createPathCondition(path.getPath(), operator);
+                    List<ConditionData> conditionList = new ArrayList<>(2);
+                    if (Objects.nonNull(hostCondition)) {
+                        conditionList.add(hostCondition);
+                    }
+                    conditionList.add(pathCondition);
+
+                    SelectorData selectorData = createSelectorData(path.getPath(), conditionList);
+                    List<RuleData> ruleDataList = new ArrayList<>();
+                    List<MetaData> metaDataList = new ArrayList<>();
+                    for (String label : labels.keySet()) {
+                        Map<String, String> metadataAnnotations = serviceLister.namespace(namespace).get(labels.get(label)).getMetadata().getAnnotations();
+                        SofaRuleHandle ruleHandle = createSofaRuleHandle(annotations);
+                        List<ConditionData> ruleConditionList = getRuleConditionList(metadataAnnotations);
+                        RuleData ruleData = createRuleData(metadataAnnotations, ruleHandle, ruleConditionList);
+                        MetaData metaData = parseMetaData(metadataAnnotations);
+                        ruleDataList.add(ruleData);
+                        metaDataList.add(metaData);
+                    }
+                    res.add(new IngressConfiguration(selectorData, ruleDataList, metaDataList));
+                }
+            }
+        }
+        return res;
+    }
+
+    private List<ConditionData> getRuleConditionList(final Map<String, String> annotations) {
+        final List<ConditionData> ruleConditionList = new ArrayList<>();
+        ConditionData ruleCondition = new ConditionData();
+        ruleCondition.setOperator(OperatorEnum.EQ.getAlias());
+        ruleCondition.setParamType(ParamTypeEnum.URI.getName());
+        ruleCondition.setParamValue(annotations.get(IngressConstants.PLUGIN_SOFA_PATH));
+        ruleConditionList.add(ruleCondition);
+        return ruleConditionList;
+    }
+
+    private ConditionData createHostCondition(final String host) {
+        ConditionData hostCondition = new ConditionData();
+        hostCondition.setParamType(ParamTypeEnum.DOMAIN.getName());
+        hostCondition.setOperator(OperatorEnum.EQ.getAlias());
+        hostCondition.setParamValue(host);
+        return hostCondition;
+    }
+
+    private OperatorEnum getOperator(final String pathType) {
+        if ("ImplementationSpecific".equals(pathType)) {
+            return OperatorEnum.MATCH;
+        } else if ("Prefix".equals(pathType)) {
+            return OperatorEnum.STARTS_WITH;
+        } else if ("Exact".equals(pathType)) {
+            return OperatorEnum.EQ;
+        } else {
+            LOG.info("Invalid path type, set it with match operator");
+            return OperatorEnum.MATCH;
+        }
+    }
+
+    private ConditionData createPathCondition(final String path, final OperatorEnum operator) {
+        ConditionData pathCondition = new ConditionData();
+        pathCondition.setOperator(operator.getAlias());
+        pathCondition.setParamType(ParamTypeEnum.URI.getName());
+        pathCondition.setParamValue(path);
+        return pathCondition;
+    }
+
+    private SofaRuleHandle createSofaRuleHandle(final Map<String, String> annotations) {
+        SofaRuleHandle sofaRuleHandle = new SofaRuleHandle();
+        if (Objects.nonNull(annotations)) {
+            sofaRuleHandle.setLoadBalance(annotations.getOrDefault(IngressConstants.LOADBALANCER_ANNOTATION_KEY, LoadBalanceEnum.RANDOM.getName()));
+            sofaRuleHandle.setTimeout(Long.parseLong(annotations.getOrDefault(IngressConstants.TIMEOUT_ANNOTATION_KEY, "3000")));
+            sofaRuleHandle.setRetries(Integer.parseInt(annotations.getOrDefault(IngressConstants.RETRY_ANNOTATION_KEY, "3")));
+        }
+        return sofaRuleHandle;
+    }
+
+    private SelectorData createSelectorData(final String path, final List<ConditionData> conditionList) {
+        return SelectorData.builder()
+                .pluginId(String.valueOf(PluginEnum.SOFA.getCode()))
+                .pluginName(PluginEnum.SOFA.getName())
+                .name(path)
+                .matchMode(MatchModeEnum.AND.getCode())
+                .type(SelectorTypeEnum.CUSTOM_FLOW.getCode())
+                .enabled(true)
+                .logged(false)
+                .continued(true)
+                .conditionList(conditionList)
+                .build();
+    }
+
+    private RuleData createRuleData(final Map<String, String> metadataAnnotations, final SofaRuleHandle ruleHandle, final List<ConditionData> ruleConditionList) {
+        return RuleData.builder()
+                .name(metadataAnnotations.get(IngressConstants.PLUGIN_SOFA_PATH))
+                .pluginName(PluginEnum.SOFA.getName())
+                .matchMode(MatchModeEnum.AND.getCode())
+                .conditionDataList(ruleConditionList)
+                .handle(GsonUtils.getInstance().toJson(ruleHandle))
+                .loged(true)
+                .enabled(true)
+                .build();
+    }
+
+    private MetaData parseMetaData(final Map<String, String> annotations) {
+        return MetaData.builder()
+                .appName(annotations.get(IngressConstants.PLUGIN_SOFA_APP_NAME))
+                .path(annotations.get(IngressConstants.PLUGIN_SOFA_PATH))
+                .rpcType(annotations.get(IngressConstants.PLUGIN_SOFA_RPC_TYPE))
+                .rpcExt(annotations.get(IngressConstants.PLUGIN_SOFA_RPC_EXPAND))
+                .serviceName(annotations.get(IngressConstants.PLUGIN_SOFA_SERVICE_NAME))
+                .methodName(annotations.get(IngressConstants.PLUGIN_SOFA_METHOD_NAME))
+                .parameterTypes(annotations.get(IngressConstants.PLUGIN_SOFA_PARAMS_TYPE))
+                .enabled(true)
+                .build();
+    }
+
+    private IngressConfiguration getSofaRouteConfig(final Map<String, String> annotations) {
+        final ConditionData conditionData = new ConditionData();
+        conditionData.setParamName("sofa");
+        conditionData.setParamType(ParamTypeEnum.URI.getName());
+        conditionData.setOperator(OperatorEnum.PATH_PATTERN.getAlias());
+        conditionData.setParamValue("/**");
+
+        final SelectorData selectorData = SelectorData.builder()
+                .name("sofa-selector")
+                .sort(Integer.MAX_VALUE)
+                .conditionList(Collections.singletonList(conditionData))
+                .enabled(true)
+                .id(IngressConstants.ID)
+                .pluginName(PluginEnum.SOFA.getName())
+                .pluginId(String.valueOf(PluginEnum.SOFA.getCode()))
+                .logged(false)
+                .continued(true)
+                .matchMode(MatchModeEnum.AND.getCode())
+                .type(SelectorTypeEnum.FULL_FLOW.getCode()).build();
+
+        final RuleData ruleData = RuleData.builder()
+                .selectorId(IngressConstants.ID)
+                .pluginName(PluginEnum.SOFA.getName())
+                .name("sofa-rule")
+                .matchMode(MatchModeEnum.AND.getCode())
+                .conditionDataList(Collections.singletonList(conditionData))
+                .loged(false)
+                .enabled(true)
+                .sort(Integer.MAX_VALUE).build();
+
+        MetaData metaData = new MetaData();
+        if (Objects.nonNull(annotations)) {
+            metaData.setAppName(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_APP_NAME, "sofa"));
+            metaData.setMethodName(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_METHOD_NAME, "methodName"));
+            metaData.setPath(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_PATH, "/sofa/findAll"));
+            metaData.setRpcType(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_RPC_TYPE, RpcTypeEnum.SOFA.getName()));
+            metaData.setServiceName(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_SERVICE_NAME, "findAll"));
+            metaData.setContextPath(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_CONTEXT_PATH, "/sofa"));
+            metaData.setRpcExt(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_RPC_EXT, "{\"loadbalance\":\"hash\",\"retries\":3,\"timeout\":-1}"));
+            metaData.setParameterTypes(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_PARAMETER_TYPE, ""));
+            metaData.setEnabled(Boolean.parseBoolean(annotations.getOrDefault(IngressConstants.PLUGIN_SOFA_ENABLED, "true")));
+        }
+        return new IngressConfiguration(selectorData, Arrays.asList(ruleData), Arrays.asList(metaData));
+    }
+}
diff --git a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java
index bf6beb8..f1629a8 100644
--- a/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java
+++ b/shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java
@@ -129,21 +129,7 @@
         final V1Ingress v1Ingress = this.ingressLister.namespace(request.getNamespace()).get(request.getName());
         final V1Ingress oldIngress = IngressCache.getInstance().get(request.getNamespace(), request.getName());
         Map<String, String> annotations = v1Ingress.getMetadata().getAnnotations();
-        if (Objects.equals(annotations.get(IngressConstants.PLUGIN_DUBBO_ENABLED), "true")) {
-            String zookeeperUrl = getZookeeperUrl(annotations, request);
-            enablePlugin(shenyuCacheRepository, PluginEnum.DUBBO, zookeeperUrl);
-        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_MOTAN_ENABLED), "true")) {
-            String zookeeperUrl = getZookeeperUrl(annotations, request);
-            enablePlugin(shenyuCacheRepository, PluginEnum.MOTAN, zookeeperUrl);
-        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_SPRING_CLOUD_ENABLED), "true")) {
-            enablePlugin(shenyuCacheRepository, PluginEnum.SPRING_CLOUD, null);
-        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_WEB_SOCKET_ENABLED), "true")) {
-            enablePlugin(shenyuCacheRepository, PluginEnum.WEB_SOCKET, null);
-        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_BRPC_ENABLED), "true")) {
-            enablePlugin(shenyuCacheRepository, PluginEnum.BRPC, null);
-        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_GRPC_ENABLED), "true")) {
-            enablePlugin(shenyuCacheRepository, PluginEnum.GRPC, null);
-        }
+        enablePluginsBasedOnAnnotations(annotations, request);
         if (Objects.isNull(v1Ingress)) {
             if (Objects.nonNull(oldIngress)) {
                 // Delete ingress binding selectors
@@ -203,6 +189,27 @@
         return new Result(false);
     }
 
+    private void enablePluginsBasedOnAnnotations(final Map<String, String> annotations, final Request request) {
+        if (Objects.equals(annotations.get(IngressConstants.PLUGIN_DUBBO_ENABLED), "true")) {
+            String zookeeperUrl = getZookeeperUrl(annotations, request);
+            enablePlugin(shenyuCacheRepository, PluginEnum.DUBBO, zookeeperUrl);
+        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_MOTAN_ENABLED), "true")) {
+            String zookeeperUrl = getZookeeperUrl(annotations, request);
+            enablePlugin(shenyuCacheRepository, PluginEnum.MOTAN, zookeeperUrl);
+        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_SPRING_CLOUD_ENABLED), "true")) {
+            enablePlugin(shenyuCacheRepository, PluginEnum.SPRING_CLOUD, null);
+        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_WEB_SOCKET_ENABLED), "true")) {
+            enablePlugin(shenyuCacheRepository, PluginEnum.WEB_SOCKET, null);
+        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_BRPC_ENABLED), "true")) {
+            enablePlugin(shenyuCacheRepository, PluginEnum.BRPC, null);
+        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_GRPC_ENABLED), "true")) {
+            enablePlugin(shenyuCacheRepository, PluginEnum.GRPC, null);
+        } else if (Objects.equals(annotations.get(IngressConstants.PLUGIN_SOFA_ENABLED), "true")) {
+            String zookeeperUrl = getZookeeperUrl(annotations, request);
+            enablePlugin(shenyuCacheRepository, PluginEnum.SOFA, zookeeperUrl);
+        }
+    }
+
     private void doDeleteConfigByIngress(final Request request, final V1Ingress oldIngress) {
         List<String> selectorList = new ArrayList<>();
         if (Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_DUBBO_ENABLED), "true")) {
@@ -219,6 +226,9 @@
             selectorList = deleteSelectorByIngressName(request.getNamespace(), request.getName(), PluginEnum.BRPC.getName(), "");
         } else if (Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_GRPC_ENABLED), "true")) {
             selectorList = deleteSelectorByIngressName(request.getNamespace(), request.getName(), PluginEnum.GRPC.getName(), "");
+        } else if (Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_SOFA_ENABLED), "true")) {
+            selectorList = deleteSelectorByIngressName(request.getNamespace(), request.getName(), PluginEnum.SOFA.getName(),
+                    oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_SOFA_CONTEXT_PATH));
         } else {
             selectorList = deleteSelectorByIngressName(request.getNamespace(), request.getName(), PluginEnum.DIVIDE.getName(), "");
         }
@@ -235,6 +245,8 @@
                 IngressSelectorCache.getInstance().remove(request.getNamespace(), request.getName(), PluginEnum.BRPC.getName());
             } else if (Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_GRPC_ENABLED), "true")) {
                 IngressSelectorCache.getInstance().remove(request.getNamespace(), request.getName(), PluginEnum.GRPC.getName());
+            } else if (Objects.equals(oldIngress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_SOFA_ENABLED), "true")) {
+                IngressSelectorCache.getInstance().remove(request.getNamespace(), request.getName(), PluginEnum.SOFA.getName());
             } else {
                 IngressSelectorCache.getInstance().remove(request.getNamespace(), request.getName(), PluginEnum.DIVIDE.getName());
             }
@@ -283,6 +295,8 @@
                 return "{\"registerProtocol\":\"zk\",\"registerAddress\":\"" + zookeeperUrl + "\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0,\"threadpool\":\"shared\"}";
             case WEB_SOCKET:
                 return "{multiSelectorHandle: 1}";
+            case SOFA:
+                return "{\"protocol\":\"zookeeper\",\"register\":\"" + zookeeperUrl + "\",\"threadpool\":\"shared\"}";
             case GRPC:
                 return "{\"multiSelectorHandle\":\"1\",\"multiRuleHandle\":\"0\",\"threadpool\":\"shared\"}";
             default:
@@ -562,6 +576,7 @@
         String pluginWebSocketEnabled = ingress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_WEB_SOCKET_ENABLED);
         String pluginBrpcEnabled = ingress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_BRPC_ENABLED);
         String pluginGrpcEnabled = ingress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_GRPC_ENABLED);
+        String pluginSofaEnabled = ingress.getMetadata().getAnnotations().get(IngressConstants.PLUGIN_SOFA_ENABLED);
         if ((Boolean.TRUE.toString()).equals(pluginDubboEnabled)) {
             pluginName = PluginEnum.DUBBO.getName();
         } else if ((Boolean.TRUE.toString()).equals(pluginMotanEnabled)) {
@@ -574,6 +589,8 @@
             pluginName = PluginEnum.BRPC.getName();
         } else if ((Boolean.TRUE.toString()).equals(pluginGrpcEnabled)) {
             pluginName = PluginEnum.GRPC.getName();
+        } else if ((Boolean.TRUE.toString()).equals(pluginSofaEnabled)) {
+            pluginName = PluginEnum.SOFA.getName();
         } else {
             pluginName = PluginEnum.DIVIDE.getName();
         }