During the installation of official Kubernetes 1.11.0 on RPI Cluster 1, encountered a bug on the controller manager preventing the controller-manager from starting. The problem here was to be able to cross compiled the latest version of Kubernetes 1.11.1 before the code was officially released and of course rebuild the images.
First check the go setup. Fetch the code
Let’s check the go environment. See Setup GOLANG environment
$ which go
/usr/bin/go
$ go version
go version go1.10.1 linux/amd64
Clone the code
$ export GOPATH=$HOME/src
$ mkdir -p src/k8s.io
$ cd src/k8s.io
$ git clone -b release-1.11 git@github.com:kubernetes/kubernetes.git
$ cd kubernertes
To save time, I removed platforms I had not use of and only kept amd64 and arm on linux
$ cat hack/lib/golang.sh
# The server platform we are building on.
readonly KUBE_SERVER_PLATFORMS=(
linux/amd64
linux/arm
)
# The node platforms we build for
readonly KUBE_NODE_PLATFORMS=(
linux/amd64
linux/arm
)
# If we update this we should also update the set of platforms whose standard library is precompiled for in build/build-image/cross/Dockerfile
readonly KUBE_CLIENT_PLATFORMS=(
linux/amd64
linux/arm
)
# Which platforms we should compile test targets for. Not all client platforms need these tests
readonly KUBE_TEST_PLATFORMS=(
linux/amd64
linux/arm
)
Double check your Docker setup is correct
$ docker run hello-world
Clean the directory
$ ./build/make-clean.sh
Rebuild the amd64 and arm executable
$ ./build/run.sh make cross
Check the executables transfered from the docker build container to your vm by rsync
$ cd _output/dockerized/bin/linux
Check the amd64 executables
ls -lt amd64
total 2322696
-rwxr-xr-x 1 xxxxxx yyyyyy 209961168 Jul 16 01:57 e2e_node.test
-rwxr-xr-x 1 xxxxxx yyyyyy 10645252 Jul 16 01:57 ginkgo
-rwxr-xr-x 1 xxxxxx yyyyyy 160051600 Jul 16 01:57 kubemark
-rwxr-xr-x 1 xxxxxx yyyyyy 231997872 Jul 16 01:55 genman
-rwxr-xr-x 1 xxxxxx yyyyyy 54099081 Jul 16 01:55 gendocs
-rwxr-xr-x 1 xxxxxx yyyyyy 54039865 Jul 16 01:55 genyaml
-rwxr-xr-x 1 xxxxxx yyyyyy 6694536 Jul 16 01:55 linkcheck
-rwxr-xr-x 1 xxxxxx yyyyyy 5481582 Jul 16 01:55 genswaggertypedocs
-rwxr-xr-x 1 xxxxxx yyyyyy 226061456 Jul 16 01:55 genkubedocs
-rwxr-xr-x 1 xxxxxx yyyyyy 173411368 Jul 16 01:55 e2e.test
-rwxr-xr-x 1 xxxxxx yyyyyy 55241186 Jul 16 01:52 kubectl
-rwxr-xr-x 1 xxxxxx yyyyyy 51912114 Jul 16 01:52 kube-proxy
-rwxr-xr-x 1 xxxxxx yyyyyy 57246829 Jul 16 01:51 kubeadm
-rwxr-xr-x 1 xxxxxx yyyyyy 162716256 Jul 16 01:51 kubelet
-rwxr-xr-x 1 xxxxxx yyyyyy 57908740 Jul 16 01:50 kube-aggregator
-rwxr-xr-x 1 xxxxxx yyyyyy 185152632 Jul 16 01:50 kube-apiserver
-rwxr-xr-x 1 xxxxxx yyyyyy 2330265 Jul 16 01:50 mounter
-rwxr-xr-x 1 xxxxxx yyyyyy 138048783 Jul 16 01:50 cloud-controller-manager
-rwxr-xr-x 1 xxxxxx yyyyyy 153798994 Jul 16 01:50 kube-controller-manager
-rwxr-xr-x 1 xxxxxx yyyyyy 227283184 Jul 16 01:50 hyperkube
-rwxr-xr-x 1 xxxxxx yyyyyy 59296776 Jul 16 01:50 apiextensions-apiserver
-rwxr-xr-x 1 xxxxxx yyyyyy 55471235 Jul 16 01:50 kube-scheduler
-rwxr-xr-x 1 xxxxxx yyyyyy 2835466 Jul 16 01:40 go-bindata
-rwxr-xr-x 1 xxxxxx yyyyyy 13630237 Jul 16 01:40 openapi-gen
-rwxr-xr-x 1 xxxxxx yyyyyy 7699847 Jul 16 01:40 conversion-gen
-rwxr-xr-x 1 xxxxxx yyyyyy 7669238 Jul 16 01:39 defaulter-gen
-rwxr-xr-x 1 xxxxxx yyyyyy 7695690 Jul 16 01:39 deepcopy-gen
Check the RPI executables
$ ls -lt arm
total 2089216
-rwxr-xr-x 1 xxxxxx yyyyyy 191189688 Jul 16 01:58 e2e_node.test
-rwxr-xr-x 1 xxxxxx yyyyyy 9286102 Jul 16 01:58 ginkgo
-rwxr-xr-x 1 xxxxxx yyyyyy 142111524 Jul 16 01:58 kubemark
-rwxr-xr-x 1 xxxxxx yyyyyy 210989712 Jul 16 01:55 genman
-rwxr-xr-x 1 xxxxxx yyyyyy 48169969 Jul 16 01:55 gendocs
-rwxr-xr-x 1 xxxxxx yyyyyy 48102745 Jul 16 01:55 genyaml
-rwxr-xr-x 1 xxxxxx yyyyyy 5847821 Jul 16 01:55 linkcheck
-rwxr-xr-x 1 xxxxxx yyyyyy 4927730 Jul 16 01:55 genswaggertypedocs
-rwxr-xr-x 1 xxxxxx yyyyyy 205458748 Jul 16 01:55 genkubedocs
-rwxr-xr-x 1 xxxxxx yyyyyy 155653412 Jul 16 01:55 e2e.test
-rwxr-xr-x 1 xxxxxx yyyyyy 49252169 Jul 16 01:52 kubectl
-rwxr-xr-x 1 xxxxxx yyyyyy 46156229 Jul 16 01:52 kube-proxy
-rwxr-xr-x 1 xxxxxx yyyyyy 50989514 Jul 16 01:52 kubeadm
-rwxr-xr-x 1 xxxxxx yyyyyy 144291264 Jul 16 01:52 kubelet
-rwxr-xr-x 1 xxxxxx yyyyyy 52024300 Jul 16 01:50 kube-aggregator
-rwxr-xr-x 1 xxxxxx yyyyyy 168751462 Jul 16 01:50 kube-apiserver
-rwxr-xr-x 1 xxxxxx yyyyyy 2231154 Jul 16 01:50 mounter
-rwxr-xr-x 1 xxxxxx yyyyyy 122701327 Jul 16 01:50 cloud-controller-manager
-rwxr-xr-x 1 xxxxxx yyyyyy 136828051 Jul 16 01:50 kube-controller-manager
-rwxr-xr-x 1 xxxxxx yyyyyy 206769888 Jul 16 01:50 hyperkube
-rwxr-xr-x 1 xxxxxx yyyyyy 53220784 Jul 16 01:50 apiextensions-apiserver
-rwxr-xr-x 1 xxxxxx yyyyyy 49501810 Jul 16 01:50 kube-scheduler
-rwxr-xr-x 1 xxxxxx yyyyyy 2649635 Jul 16 01:40 go-bindata
-rwxr-xr-x 1 xxxxxx yyyyyy 11885551 Jul 16 01:40 openapi-gen
-rwxr-xr-x 1 xxxxxx yyyyyy 6770458 Jul 16 01:40 conversion-gen
-rwxr-xr-x 1 xxxxxx yyyyyy 6764729 Jul 16 01:39 defaulter-gen
-rwxr-xr-x 1 xxxxxx yyyyyy 6770309 Jul 16 01:39 deepcopy-gen
Transfer the binaries to RPI machine
scp -r arm rpiuser@192.168.1.94:/home/rpiuser/kubernetes_binaries
$ mkdir -p images/kube-controller-manager
$ cd images/kube-controller-manager
$ cp $HOME/kubernetes_binaries/kube-controller-manager
Create a simple Dockerfile to update the executable
$ cat Dockerfile
FROM k8s.gcr.io/kube-controller-manager-arm:v1.11.0
COPY kube-controller-manager /usr/local/bin/kube-controller-manager
Build the image
$ docker build -t jbrette/kube-controller-manager-arm:v1.11.1
Because of the brute force approach the image is twice as big since the executable (130MB) is contained in two layers of the container image
$ docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
jbrette/kube-controller-manager-arm v1.11.1 b7023eef8fdf 8 hours ago 275MB
k8s.gcr.io/kube-apiserver-arm v1.11.0 383bd2c4314e 2 weeks ago 170MB
k8s.gcr.io/kube-controller-manager-arm v1.11.0 5b25f8a97aec 2 weeks ago 138MB
k8s.gcr.io/kube-scheduler-arm v1.11.0 555ee860fa3c 2 weeks ago 50.5MB
k8s.gcr.io/kube-proxy-arm v1.11.0 d7ebe361fe95 2 weeks ago 89.1MB
k8s.gcr.io/coredns 1.1.3 7ceeb40862fb 7 weeks ago 31.3MB
k8s.gcr.io/etcd-arm 3.2.18 ae02bf7047c8 3 months ago 221MB
quay.io/coreos/flannel v0.10.0-arm c663d02f7966 5 months ago 39.9MB
k8s.gcr.io/pause-arm 3.1 e11a8cbeda86 6 months ago 374kB
k8s.gcr.io/pause 3.1 e11a8cbeda86 6 months ago 374kB
First push the controller-manager docker image to the repo
$ docker login
$ docker push jbrette/kube-controller-manager-arm:v1.11.1
Because I only rebuild one image, I can not use the kubeadm feature which allows to point to a different repo. Have to edit manually the configuration.
$ more kube-controller-manager.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
creationTimestamp: null
labels:
component: kube-controller-manager
tier: control-plane
name: kube-controller-manager
namespace: kube-system
spec:
containers:
- command:
- kube-controller-manager
- --address=127.0.0.1
- --allocate-node-cidrs=true
- --cluster-cidr=10.244.0.0/16
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
- --controllers=*,bootstrapsigner,tokencleaner
- --kubeconfig=/etc/kubernetes/controller-manager.conf
- --leader-elect=true
- --node-cidr-mask-size=24
- --root-ca-file=/etc/kubernetes/pki/ca.crt
- --service-account-private-key-file=/etc/kubernetes/pki/sa.key
- --use-service-account-credentials=true
image: jbrette/kube-controller-manager-arm:v1.11.1
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /healthz
port: 10252
scheme: HTTP
initialDelaySeconds: 15
timeoutSeconds: 15
name: kube-controller-manager
resources:
requests:
cpu: 200m
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/kubernetes/controller-manager.conf
name: kubeconfig
readOnly: true
- mountPath: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
name: flexvolume-dir
- mountPath: /usr/share/ca-certificates
name: usr-share-ca-certificates
readOnly: true
- mountPath: /usr/local/share/ca-certificates
name: usr-local-share-ca-certificates
readOnly: true
- mountPath: /etc/ca-certificates
name: etc-ca-certificates
readOnly: true
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
name: k8s-certs
- hostPath:
path: /etc/ssl/certs
type: DirectoryOrCreate
name: ca-certs
- hostPath:
path: /etc/kubernetes/controller-manager.conf
type: FileOrCreate
name: kubeconfig
- hostPath:
path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
type: DirectoryOrCreate
name: flexvolume-dir
- hostPath:
path: /usr/share/ca-certificates
type: DirectoryOrCreate
name: usr-share-ca-certificates
- hostPath:
path: /usr/local/share/ca-certificates
type: DirectoryOrCreate
name: usr-local-share-ca-certificates
- hostPath:
path: /etc/ca-certificates
type: DirectoryOrCreate
name: etc-ca-certificates
status: {}