Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add container readiness probes #664

Merged
merged 1 commit into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions cmd/cl-controlplane/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ package app

import (
"context"
"errors"
"fmt"
"net/http"
"os"
"path"
"syscall"

"github.com/bombsimon/logrusr/v4"
"github.com/sirupsen/logrus"
Expand All @@ -39,6 +42,7 @@ import (
"github.com/clusterlink-net/clusterlink/pkg/controlplane/xds"
"github.com/clusterlink-net/clusterlink/pkg/util/controller"
"github.com/clusterlink-net/clusterlink/pkg/util/grpc"
utilhttp "github.com/clusterlink-net/clusterlink/pkg/util/http"
"github.com/clusterlink-net/clusterlink/pkg/util/log"
"github.com/clusterlink-net/clusterlink/pkg/util/runnable"
"github.com/clusterlink-net/clusterlink/pkg/util/tls"
Expand Down Expand Up @@ -219,11 +223,27 @@ func (o *Options) Run() error {
return err
}

readinessListenAddress := fmt.Sprintf("0.0.0.0:%d", api.ReadinessListenPort)
httpServer := utilhttp.NewServer("controlplane-http", nil)
httpServer.Router().Get("/", func(w http.ResponseWriter, r *http.Request) {
resp, err := http.Get(fmt.Sprintf("https://127.0.0.1:%d", api.ListenPort))
if err == nil && resp.Body.Close() != nil {
logrus.Infof("Cannot close readiness response body: %v", err)
}
if errors.Is(err, syscall.ECONNREFUSED) ||
errors.Is(err, syscall.ECONNRESET) ||
!authzManager.IsReady() ||
!mgr.GetCache().WaitForCacheSync(r.Context()) {
w.WriteHeader(http.StatusServiceUnavailable)
}
})

runnableManager := runnable.NewManager()
runnableManager.Add(peerCertsWatcher)
runnableManager.Add(controller.NewManager(mgr))
runnableManager.Add(controlManager)
runnableManager.AddServer(controlplaneServerListenAddress, grpcServer)
runnableManager.AddServer(readinessListenAddress, httpServer)

return runnableManager.Run()
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/cl-dataplane/app/envoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ import (

const (
envoyPath = "/usr/local/bin/envoy"

adminPort = 1500
)

func (o *Options) runEnvoy(dataplaneID string) error {
envoyConfArgs := map[string]interface{}{
"dataplaneID": dataplaneID,

"adminPort": adminPort,

"controlplaneHost": o.ControlplaneHost,
"controlplanePort": cpapi.ListenPort,

Expand Down
2 changes: 1 addition & 1 deletion cmd/cl-dataplane/app/envoyconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ admin:
address:
socket_address:
address: 127.0.0.1
port_value: 1500
port_value: {{.adminPort}}
bootstrap_extensions:
- name: envoy.bootstrap.internal_listener
typed_config:
Expand Down
24 changes: 22 additions & 2 deletions cmd/cl-dataplane/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ package app

import (
"fmt"
"net/http"
"os"

"github.com/google/uuid"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/clusterlink-net/clusterlink/pkg/dataplane/api"
utilhttp "github.com/clusterlink-net/clusterlink/pkg/util/http"
"github.com/clusterlink-net/clusterlink/pkg/util/log"
)

Expand All @@ -36,8 +39,6 @@ const (
// KeyFile is the path to the private-key file.
KeyFile = "/etc/ssl/key/clink-dataplane.pem"

// Name is the app label of dataplane pods.
Name = "cl-dataplane"
// IngressSvcName is the ingress service name for the dataplane pods.
IngressSvcName = "clusterlink"
)
Expand Down Expand Up @@ -85,6 +86,25 @@ func (o *Options) Run() error {
dataplaneID := uuid.New().String()
logrus.Infof("Dataplane ID: %s.", dataplaneID)

readinessListenAddress := fmt.Sprintf("0.0.0.0:%d", api.ReadinessListenPort)
httpServer := utilhttp.NewServer("dataplane-readiness-http", nil)
if err := httpServer.Listen(readinessListenAddress); err != nil {
return fmt.Errorf("cannot listen for readiness: %w", err)
}
httpServer.Router().Get("/", func(w http.ResponseWriter, r *http.Request) {
resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d/ready", adminPort))
if err == nil && resp.Body.Close() != nil {
logrus.Infof("Cannot close readiness response body: %v", err)
}
if err != nil || resp.StatusCode != http.StatusOK {
w.WriteHeader(http.StatusServiceUnavailable)
}
})
go func() {
err := httpServer.Start()
logrus.Errorf("Failed to start readiness server: %v.", err)
}()

return o.runEnvoy(dataplaneID)
}

Expand Down
22 changes: 20 additions & 2 deletions cmd/cl-go-dataplane/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package app
import (
"fmt"
"net"
"net/http"
"os"
"strconv"
"time"
Expand All @@ -32,6 +33,7 @@ import (
"github.com/clusterlink-net/clusterlink/pkg/dataplane/api"
dpclient "github.com/clusterlink-net/clusterlink/pkg/dataplane/client"
dpserver "github.com/clusterlink-net/clusterlink/pkg/dataplane/server"
utilhttp "github.com/clusterlink-net/clusterlink/pkg/util/http"
"github.com/clusterlink-net/clusterlink/pkg/util/log"
"github.com/clusterlink-net/clusterlink/pkg/util/tls"
)
Expand Down Expand Up @@ -81,7 +83,7 @@ func (o *Options) runGoDataplane(dataplaneID string, parsedCertData *tls.ParsedC

controlplaneClient, err := grpc.NewClient(
controlplaneTarget,
grpc.WithTransportCredentials(credentials.NewTLS(parsedCertData.ClientConfig("cl-controlplane"))),
grpc.WithTransportCredentials(credentials.NewTLS(parsedCertData.ClientConfig(cpapi.Name))),
grpc.WithConnectParams(grpc.ConnectParams{
Backoff: backoff.Config{
BaseDelay: 100 * time.Millisecond,
Expand All @@ -101,8 +103,24 @@ func (o *Options) runGoDataplane(dataplaneID string, parsedCertData *tls.ParsedC
logrus.Errorf("Failed to start dataplane server: %v.", err)
}()

// Start xDS client, if it fails to start we keep retrying to connect to the controlplane host
xdsClient := dpclient.NewXDSClient(dataplane, controlplaneClient)

readinessListenAddress := fmt.Sprintf("0.0.0.0:%d", api.ReadinessListenPort)
httpServer := utilhttp.NewServer("go-dataplane-readiness-http", nil)
if err := httpServer.Listen(readinessListenAddress); err != nil {
return fmt.Errorf("cannot listen for readiness: %w", err)
}
httpServer.Router().Get("/", func(w http.ResponseWriter, r *http.Request) {
if !xdsClient.IsReady() || !dataplane.IsReady() {
w.WriteHeader(http.StatusServiceUnavailable)
}
})
go func() {
err := httpServer.Start()
logrus.Errorf("Failed to start readiness server: %v.", err)
}()

// Start xDS client, if it fails to start we keep retrying to connect to the controlplane host
err = xdsClient.Run()
return fmt.Errorf("xDS Client stopped: %w", err)
}
Expand Down
10 changes: 6 additions & 4 deletions pkg/bootstrap/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"path/filepath"

"github.com/clusterlink-net/clusterlink/cmd/clusterlink/config"
cpapi "github.com/clusterlink-net/clusterlink/pkg/controlplane/api"
dpapi "github.com/clusterlink-net/clusterlink/pkg/dataplane/api"
)

// Certificate represents a clusterlink certificate.
Expand Down Expand Up @@ -69,9 +71,9 @@ func CreateCACertificate() (*Certificate, error) {
func CreateControlplaneCertificate(caCert *Certificate) (*Certificate, error) {
cert, err := createCertificate(&certificateConfig{
Parent: caCert.cert,
Name: "cl-controlplane",
Name: cpapi.Name,
IsServer: true,
DNSNames: []string{"cl-controlplane"},
DNSNames: []string{cpapi.Name},
})
if err != nil {
return nil, err
Expand All @@ -84,9 +86,9 @@ func CreateControlplaneCertificate(caCert *Certificate) (*Certificate, error) {
func CreateDataplaneCertificate(caCert *Certificate) (*Certificate, error) {
cert, err := createCertificate(&certificateConfig{
Parent: caCert.cert,
Name: "cl-dataplane",
Name: dpapi.Name,
IsClient: true,
DNSNames: []string{"cl-dataplane"},
DNSNames: []string{dpapi.Name},
})
if err != nil {
return nil, err
Expand Down
Loading
Loading