Compare commits

..

2 Commits

Author SHA1 Message Date
eec739b9de Add test for isCNIResultForPID
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2021-02-21 21:13:56 +00:00
19a807c336 Use CNI cache to find container IP
This is an optimization that uses the results cache created by
CNI on the filesystem to store and fetch IP addresses for
containers in the core services and for functions. As part of
the change, the dependency on the syscall code from Weave net
has been removed, and the code should compile on MacOS again.

Updates and rebases the work in #38 by carlosedp

Tested in the original PR, further testing in the incoming
PR.

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2021-02-19 12:14:26 +00:00
16 changed files with 28 additions and 64 deletions

View File

@ -18,8 +18,8 @@ runcmd:
- mkdir -p /opt/cni/bin - mkdir -p /opt/cni/bin
- curl -sSL https://github.com/containernetworking/plugins/releases/download/v0.8.5/cni-plugins-linux-amd64-v0.8.5.tgz | tar -xz -C /opt/cni/bin - curl -sSL https://github.com/containernetworking/plugins/releases/download/v0.8.5/cni-plugins-linux-amd64-v0.8.5.tgz | tar -xz -C /opt/cni/bin
- mkdir -p /go/src/github.com/openfaas/ - mkdir -p /go/src/github.com/openfaas/
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.11.0 https://github.com/openfaas/faasd - cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.10.2 https://github.com/openfaas/faasd
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd" - curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install - cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
- systemctl status -l containerd --no-pager - systemctl status -l containerd --no-pager
- journalctl -u faasd-provider --no-pager - journalctl -u faasd-provider --no-pager

View File

@ -46,12 +46,7 @@ var rootCommand = &cobra.Command{
Use: "faasd", Use: "faasd",
Short: "Start faasd", Short: "Start faasd",
Long: ` Long: `
faasd - Serverless For Everyone Else faasd - serverless without Kubernetes
Learn how to build, secure, and monitor functions with faasd with
the eBook:
https://gumroad.com/l/serverless-for-everyone-else
`, `,
RunE: runRootCommand, RunE: runRootCommand,
SilenceUsage: true, SilenceUsage: true,

View File

@ -41,7 +41,7 @@ services:
- "127.0.0.1:9090:9090" - "127.0.0.1:9090:9090"
gateway: gateway:
image: ghcr.io/openfaas/gateway:0.20.11 image: ghcr.io/openfaas/gateway:0.20.8
environment: environment:
- basic_auth=true - basic_auth=true
- functions_provider_url=http://faasd-provider:8081/ - functions_provider_url=http://faasd-provider:8081/

View File

@ -169,7 +169,7 @@ You may find alternative package names for CentOS and other Linux distributions.
#### Install Go 1.13 (x86_64) #### Install Go 1.13 (x86_64)
```bash ```bash
curl -SLf https://golang.org/dl/go1.16.linux-amd64.tar.gz > /tmp/go.tgz curl -sSLf https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz > /tmp/go.tgz
sudo rm -rf /usr/local/go/ sudo rm -rf /usr/local/go/
sudo mkdir -p /usr/local/go/ sudo mkdir -p /usr/local/go/
sudo tar -xvf /tmp/go.tgz -C /usr/local/go/ --strip-components=1 sudo tar -xvf /tmp/go.tgz -C /usr/local/go/ --strip-components=1
@ -190,7 +190,7 @@ echo "export PATH=\$PATH:/usr/local/go/bin/" | tee -a $HOME/.bash_profile
#### Or on Raspberry Pi (armhf) #### Or on Raspberry Pi (armhf)
```bash ```bash
curl -SLsf https://golang.org/dl/go1.16.linux-armv6l.tar.gz > go.tgz curl -SLsf https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz > go.tgz
sudo rm -rf /usr/local/go/ sudo rm -rf /usr/local/go/
sudo mkdir -p /usr/local/go/ sudo mkdir -p /usr/local/go/
sudo tar -xvf go.tgz -C /usr/local/go/ --strip-components=1 sudo tar -xvf go.tgz -C /usr/local/go/ --strip-components=1
@ -233,7 +233,7 @@ export SUFFIX="-armhf"
export SUFFIX="-arm64" export SUFFIX="-arm64"
# Then download # Then download
curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd$SUFFIX" \ curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd$SUFFIX" \
-o "/tmp/faasd" \ -o "/tmp/faasd" \
&& chmod +x "/tmp/faasd" && chmod +x "/tmp/faasd"
sudo mv /tmp/faasd /usr/local/bin/ sudo mv /tmp/faasd /usr/local/bin/

View File

@ -20,8 +20,8 @@ runcmd:
- mkdir -p /var/lib/faasd/secrets/ - mkdir -p /var/lib/faasd/secrets/
- echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password - echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password
- echo admin > /var/lib/faasd/secrets/basic-auth-user - echo admin > /var/lib/faasd/secrets/basic-auth-user
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.11.0 https://github.com/openfaas/faasd - cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.10.2 https://github.com/openfaas/faasd
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd" - curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install - cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
- systemctl status -l containerd --no-pager - systemctl status -l containerd --no-pager
- journalctl -u faasd-provider --no-pager - journalctl -u faasd-provider --no-pager

View File

@ -41,8 +41,8 @@ runcmd:
- mkdir -p /var/lib/faasd/secrets/ - mkdir -p /var/lib/faasd/secrets/
- echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password - echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password
- echo admin > /var/lib/faasd/secrets/basic-auth-user - echo admin > /var/lib/faasd/secrets/basic-auth-user
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.11.0 https://github.com/openfaas/faasd - cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.10.2 https://github.com/openfaas/faasd
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd" - curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install - cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
- systemctl status -l containerd --no-pager - systemctl status -l containerd --no-pager
- journalctl -u faasd-provider --no-pager - journalctl -u faasd-provider --no-pager

2
go.mod
View File

@ -30,7 +30,7 @@ require (
github.com/opencontainers/runc v1.0.0-rc9 // indirect github.com/opencontainers/runc v1.0.0-rc9 // indirect
github.com/opencontainers/runtime-spec v1.0.2 github.com/opencontainers/runtime-spec v1.0.2
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4 github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4
github.com/openfaas/faas-provider v0.17.3 github.com/openfaas/faas-provider v0.16.2
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/procfs v0.2.0 // indirect github.com/prometheus/procfs v0.2.0 // indirect
github.com/sethvargo/go-password v0.1.3 github.com/sethvargo/go-password v0.1.3

10
go.sum
View File

@ -181,14 +181,8 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4 h1:JJjthDw7WziZQ7sC5C+M2872mIdud5R+s6Cb0cXyPuA= github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4 h1:JJjthDw7WziZQ7sC5C+M2872mIdud5R+s6Cb0cXyPuA=
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4/go.mod h1:E0m2rLup0Vvxg53BKxGgaYAGcZa3Xl+vvL7vSi5yQ14= github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4/go.mod h1:E0m2rLup0Vvxg53BKxGgaYAGcZa3Xl+vvL7vSi5yQ14=
github.com/openfaas/faas-provider v0.17.0 h1:4rT8CosKhI5xaAMqbyihEgR6KefO/ViJdF0a8THTgwM= github.com/openfaas/faas-provider v0.16.2 h1:ChpiZh1RM8zFIzvp31OPlKpTbh5Lcm7f91WCFcpW4gA=
github.com/openfaas/faas-provider v0.17.0/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98= github.com/openfaas/faas-provider v0.16.2/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
github.com/openfaas/faas-provider v0.17.1 h1:P5xTLN+/08PLLh4auIlO/PaUD/J3BUTmaC3en8N5zbs=
github.com/openfaas/faas-provider v0.17.1/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
github.com/openfaas/faas-provider v0.17.2 h1:jZ+Z83A/tyJoI1AnpyLN3o0B4K0UEsz1YJ3erASMu+s=
github.com/openfaas/faas-provider v0.17.2/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
github.com/openfaas/faas-provider v0.17.3 h1:LN76lrXUKAx27o5X8l+daKWEzsdiW2E99jMOlI1SO5Q=
github.com/openfaas/faas-provider v0.17.3/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

View File

@ -29,8 +29,8 @@ import (
const annotationLabelPrefix = "com.openfaas.annotations." const annotationLabelPrefix = "com.openfaas.annotations."
// MakeDeployHandler returns a handler to deploy a function
func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath string, alwaysPull bool) func(w http.ResponseWriter, r *http.Request) { func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath string, alwaysPull bool) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if r.Body == nil { if r.Body == nil {
@ -147,7 +147,6 @@ func deploy(ctx context.Context, req types.FunctionDeployment, client *container
containerd.WithSnapshotter(snapshotter), containerd.WithSnapshotter(snapshotter),
containerd.WithNewSnapshot(name+"-snapshot", image), containerd.WithNewSnapshot(name+"-snapshot", image),
containerd.WithNewSpec(oci.WithImageConfig(image), containerd.WithNewSpec(oci.WithImageConfig(image),
oci.WithHostname(name),
oci.WithCapabilities([]string{"CAP_NET_RAW"}), oci.WithCapabilities([]string{"CAP_NET_RAW"}),
oci.WithMounts(mounts), oci.WithMounts(mounts),
oci.WithEnv(envs), oci.WithEnv(envs),

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"log" "log"
"strings" "strings"
"time"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
@ -28,7 +27,6 @@ type Function struct {
secrets []string secrets []string
envVars map[string]string envVars map[string]string
envProcess string envProcess string
createdAt time.Time
} }
// ListFunctions returns a map of all functions with running tasks on namespace // ListFunctions returns a map of all functions with running tasks on namespace
@ -83,11 +81,6 @@ func GetFunction(client *containerd.Client, name string) (Function, error) {
return Function{}, fmt.Errorf("unable to load function spec for reading secrets: %s, error %s", name, err) return Function{}, fmt.Errorf("unable to load function spec for reading secrets: %s, error %s", name, err)
} }
info, err := c.Info(ctx)
if err != nil {
return Function{}, fmt.Errorf("can't load info for: %s, error %s", name, err)
}
envVars, envProcess := readEnvFromProcessEnv(spec.Process.Env) envVars, envProcess := readEnvFromProcessEnv(spec.Process.Env)
secrets := readSecretsFromMounts(spec.Mounts) secrets := readSecretsFromMounts(spec.Mounts)
@ -99,7 +92,6 @@ func GetFunction(client *containerd.Client, name string) (Function, error) {
fn.secrets = secrets fn.secrets = secrets
fn.envVars = envVars fn.envVars = envVars
fn.envProcess = envProcess fn.envProcess = envProcess
fn.createdAt = info.CreatedAt
replicas := 0 replicas := 0
task, err := c.Task(ctx, nil) task, err := c.Task(ctx, nil)

View File

@ -34,7 +34,6 @@ func MakeReadHandler(client *containerd.Client) func(w http.ResponseWriter, r *h
Secrets: fn.secrets, Secrets: fn.secrets,
EnvVars: fn.envVars, EnvVars: fn.envVars,
EnvProcess: fn.envProcess, EnvProcess: fn.envProcess,
CreatedAt: fn.createdAt,
}) })
} }
@ -42,5 +41,6 @@ func MakeReadHandler(client *containerd.Client) func(w http.ResponseWriter, r *h
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write(body) w.Write(body)
} }
} }

View File

@ -26,7 +26,6 @@ func MakeReplicaReaderHandler(client *containerd.Client) func(w http.ResponseWri
Secrets: f.secrets, Secrets: f.secrets,
EnvVars: f.envVars, EnvVars: f.envVars,
EnvProcess: f.envProcess, EnvProcess: f.envProcess,
CreatedAt: f.createdAt,
} }
functionBytes, _ := json.Marshal(found) functionBytes, _ := json.Marshal(found)

View File

@ -172,7 +172,6 @@ func (s *Supervisor) Start(svcs []Service) error {
containerd.WithImage(image), containerd.WithImage(image),
containerd.WithNewSnapshot(svc.Name+"-snapshot", image), containerd.WithNewSnapshot(svc.Name+"-snapshot", image),
containerd.WithNewSpec(oci.WithImageConfig(image), containerd.WithNewSpec(oci.WithImageConfig(image),
oci.WithHostname(svc.Name),
withUserOrDefault(svc.User), withUserOrDefault(svc.User),
oci.WithCapabilities(svc.Caps), oci.WithCapabilities(svc.Caps),
oci.WithMounts(mounts), oci.WithMounts(mounts),

View File

@ -36,6 +36,7 @@ import (
const ( const (
watchdogPort = "8080" watchdogPort = "8080"
defaultContentType = "text/plain" defaultContentType = "text/plain"
errMissingFunctionName = "Please provide a valid route /function/function_name."
) )
// BaseURLResolver URL resolver for proxy requests // BaseURLResolver URL resolver for proxy requests
@ -74,9 +75,8 @@ func NewHandlerFunc(config types.FaaSConfig, resolver BaseURLResolver) http.Hand
http.MethodPut, http.MethodPut,
http.MethodPatch, http.MethodPatch,
http.MethodDelete, http.MethodDelete,
http.MethodGet, http.MethodGet:
http.MethodOptions,
http.MethodHead:
proxyRequest(w, r, proxyClient, resolver) proxyRequest(w, r, proxyClient, resolver)
default: default:
@ -136,15 +136,15 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
pathVars := mux.Vars(originalReq) pathVars := mux.Vars(originalReq)
functionName := pathVars["name"] functionName := pathVars["name"]
if functionName == "" { if functionName == "" {
httputil.Errorf(w, http.StatusBadRequest, "Provide function name in the request path") httputil.Errorf(w, http.StatusBadRequest, errMissingFunctionName)
return return
} }
functionAddr, resolveErr := resolver.Resolve(functionName) functionAddr, resolveErr := resolver.Resolve(functionName)
if resolveErr != nil { if resolveErr != nil {
// TODO: Should record the 404/not found error in Prometheus. // TODO: Should record the 404/not found error in Prometheus.
log.Printf("resolver error: no endpoints for %s: %s\n", functionName, resolveErr.Error()) log.Printf("resolver error: cannot find %s: %s\n", functionName, resolveErr.Error())
httputil.Errorf(w, http.StatusServiceUnavailable, "No endpoints available for: %s.", functionName) httputil.Errorf(w, http.StatusNotFound, "Cannot find service: %s.", functionName)
return return
} }
@ -153,7 +153,6 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
httputil.Errorf(w, http.StatusInternalServerError, "Failed to resolve service: %s.", functionName) httputil.Errorf(w, http.StatusInternalServerError, "Failed to resolve service: %s.", functionName)
return return
} }
if proxyReq.Body != nil { if proxyReq.Body != nil {
defer proxyReq.Body.Close() defer proxyReq.Body.Close()
} }
@ -168,10 +167,7 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
httputil.Errorf(w, http.StatusInternalServerError, "Can't reach service for: %s.", functionName) httputil.Errorf(w, http.StatusInternalServerError, "Can't reach service for: %s.", functionName)
return return
} }
if response.Body != nil {
defer response.Body.Close() defer response.Body.Close()
}
log.Printf("%s took %f seconds\n", functionName, seconds.Seconds()) log.Printf("%s took %f seconds\n", functionName, seconds.Seconds())
@ -180,9 +176,7 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
w.Header().Set("Content-Type", getContentType(originalReq.Header, response.Header)) w.Header().Set("Content-Type", getContentType(originalReq.Header, response.Header))
w.WriteHeader(response.StatusCode) w.WriteHeader(response.StatusCode)
if response.Body != nil {
io.Copy(w, response.Body) io.Copy(w, response.Body)
}
} }
// buildProxyRequest creates a request object for the proxy request, it will ensure that // buildProxyRequest creates a request object for the proxy request, it will ensure that

View File

@ -1,7 +1,5 @@
package types package types
import "time"
// FunctionDeployment represents a request to create or update a Function. // FunctionDeployment represents a request to create or update a Function.
type FunctionDeployment struct { type FunctionDeployment struct {
@ -102,9 +100,7 @@ type FunctionStatus struct {
// mount-point. // mount-point.
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty"` ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty"`
// ================ // ** Status fields *8
// Fields for status
// ================
// InvocationCount count of invocations // InvocationCount count of invocations
InvocationCount float64 `json:"invocationCount,omitempty"` InvocationCount float64 `json:"invocationCount,omitempty"`
@ -115,8 +111,4 @@ type FunctionStatus struct {
// AvailableReplicas is the count of replicas ready to receive // AvailableReplicas is the count of replicas ready to receive
// invocations as reported by the faas-provider // invocations as reported by the faas-provider
AvailableReplicas uint64 `json:"availableReplicas,omitempty"` AvailableReplicas uint64 `json:"availableReplicas,omitempty"`
// CreatedAt is the time read back from the faas backend's
// data store for when the function or its container was created.
CreatedAt time.Time `json:"createdAt,omitempty"`
} }

2
vendor/modules.txt generated vendored
View File

@ -195,7 +195,7 @@ github.com/opencontainers/runtime-spec/specs-go
# github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4 # github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4
## explicit ## explicit
github.com/openfaas/faas/gateway/requests github.com/openfaas/faas/gateway/requests
# github.com/openfaas/faas-provider v0.17.3 # github.com/openfaas/faas-provider v0.16.2
## explicit ## explicit
github.com/openfaas/faas-provider github.com/openfaas/faas-provider
github.com/openfaas/faas-provider/auth github.com/openfaas/faas-provider/auth