github.phpd.cn/cilium/cilium@v1.6.12/pkg/proxy/envoyproxy.go (about)

     1  // Copyright 2016-2018 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package proxy
    16  
    17  import (
    18  	"fmt"
    19  	"sync"
    20  
    21  	"github.com/cilium/cilium/pkg/completion"
    22  	"github.com/cilium/cilium/pkg/envoy"
    23  	"github.com/cilium/cilium/pkg/option"
    24  	"github.com/cilium/cilium/pkg/policy"
    25  	"github.com/cilium/cilium/pkg/revert"
    26  )
    27  
    28  // the global Envoy instance
    29  var envoyProxy *envoy.Envoy
    30  
    31  // envoyRedirect implements the RedirectImplementation interface for an l7 proxy.
    32  type envoyRedirect struct {
    33  	listenerName string
    34  	xdsServer    *envoy.XDSServer
    35  }
    36  
    37  var envoyOnce sync.Once
    38  
    39  // createEnvoyRedirect creates a redirect with corresponding proxy
    40  // configuration. This will launch a proxy instance.
    41  func createEnvoyRedirect(r *Redirect, stateDir string, xdsServer *envoy.XDSServer, mayUseOriginalSourceAddr bool, wg *completion.WaitGroup) (RedirectImplementation, error) {
    42  	envoyOnce.Do(func() {
    43  		// Start Envoy on first invocation
    44  		envoyProxy = envoy.StartEnvoy(stateDir, option.Config.EnvoyLogPath, 0)
    45  	})
    46  
    47  	l := r.listener
    48  	if envoyProxy != nil {
    49  		redir := &envoyRedirect{
    50  			listenerName: fmt.Sprintf("%s:%d", l.name, l.proxyPort),
    51  			xdsServer:    xdsServer,
    52  		}
    53  		// Only use original source address for egress
    54  		if l.ingress {
    55  			mayUseOriginalSourceAddr = false
    56  		}
    57  		xdsServer.AddListener(redir.listenerName, l.parserType, l.proxyPort, l.ingress,
    58  			mayUseOriginalSourceAddr, wg)
    59  
    60  		return redir, nil
    61  	}
    62  
    63  	return nil, fmt.Errorf("%s: Envoy proxy process failed to start, cannot add redirect", l.name)
    64  }
    65  
    66  // UpdateRules is a no-op for envoy, as redirect data is synchronized via the
    67  // xDS cache.
    68  func (k *envoyRedirect) UpdateRules(wg *completion.WaitGroup, l4 *policy.L4Filter) (revert.RevertFunc, error) {
    69  	return func() error { return nil }, nil
    70  }
    71  
    72  // Close the redirect.
    73  func (r *envoyRedirect) Close(wg *completion.WaitGroup) (revert.FinalizeFunc, revert.RevertFunc) {
    74  	if envoyProxy == nil {
    75  		return nil, nil
    76  	}
    77  
    78  	revertFunc := r.xdsServer.RemoveListener(r.listenerName, wg)
    79  
    80  	return nil, func() error {
    81  		// Don't wait for an ACK for the reverted xDS updates.
    82  		// This is best-effort.
    83  		revertFunc(completion.NewCompletion(nil, nil))
    84  		return nil
    85  	}
    86  }