I am building the following ridiculously simple go
program
package main
import (
"context"
"flag"
"fmt"
"log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
)
const namespace = "default"
func main() {
home := homedir.HomeDir()
defaultKubeConfigPath := fmt.Sprintf("%s/%s", home, ".kube/config")
kubeconfig := flag.String("kubeconfig", defaultKubeConfigPath, "location to kubeconfig file")
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal(err)
}
pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}
for i := range pods.Items {
fmt.Printf("%s\n", pods.Items[i].Name)
}
deployments, err := clientset.AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}
for i := range deployments.Items {
fmt.Printf("%s\n", deployments.Items[i].Name)
}
}
using the following Dockerfile
FROM golang:1.19.2-alpine3.15 as builder
COPY src /src
WORKDIR /src
RUN go build -race -ldflags "-s -w" -a -o client-go
FROM scratch
COPY --from=builder client-go /client-go
ENTRYPOINT [ "./client-go" ]
The build fails as folows:
#8 21.92 # runtime/cgo
#8 21.92 cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in $PATH
Where exactly is gcc
needed since I am not using any cgo
extensions?
Is there an a priori way of identifying when gcc
for cgo
is needed?
CodePudding user response:
You need to set CGO_ENABLED=0
and not enable the race detector.
The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling. You can control this by setting the CGO_ENABLED environment variable when running the go tool: set it to 1 to enable the use of cgo, and to 0 to disable it. The go tool will set the build constraint "cgo" if cgo is enabled. The special import "C" implies the "cgo" build constraint, as though the file also said "// build cgo". Therefore, if cgo is disabled, files that import "C" will not be built by the go tool.
See also Why is CGO_ENABLED=1 default?
With CGO_ENABLED=0
and the race flag set, you'll get an error:
#8 0.857 go: -race requires cgo; enable cgo by setting CGO_ENABLED=1
So to get this to compile without gcc you'll want to use:
RUN CGO_ENABLED=0 go build -ldflags "-s -w" -a -o client-go