소스코드로 쿠버네티스 직접 빌드하기
on Kubernetes
쿠버네티스 공식 레포에 기여할 때 프리뷰 형식으로 확인을 하거나, 컴포넌트 기능을 변경하여 사용하고 싶은 경우 쿠버네티스 클러스터의 핵심 파드들을 직접 빌드해야 한다.
여기를 참조하면, 시스템은 8GB 이상의 메모리와 50GB 이상의 디스크 여유 공간을 필요로 하며, gcc와 make를 활용하기 때문에 만약 없을 경우 apt-get install build-essential
을 통해 설치해놓는다.
우선 쿠버네티스 레포에 있는 소스코드들을 받아온다.
bconfiden2@h03:~$ git clone https://github.com/kubernetes/kubernetes k8s-src
Cloning into 'k8s-src'...
remote: Enumerating objects: 1369681, done.
remote: Counting objects: 100% (224/224), done.
remote: Compressing objects: 100% (157/157), done.
remote: Total 1369681 (delta 88), reused 85 (delta 65), pack-reused 1369457
Receiving objects: 100% (1369681/1369681), 875.81 MiB | 2.79 MiB/s, done.
Resolving deltas: 100% (988566/988566), done.
Updating files: 100% (23176/23176), done.
bconfiden2@h03:~$ cd k8s-src
bconfiden2@h03:~/k8s-src$ ls
api cluster docs LICENSE OWNERS README.md test
build cmd go.mod LICENSES OWNERS_ALIASES SECURITY_CONTACTS third_party
CHANGELOG code-of-conduct.md go.sum logo pkg staging vendor
CHANGELOG.md CONTRIBUTING.md hack Makefile plugin SUPPORT.md
소스코드 뿐만 아니라 깃 정보들도 전부 가져오기 때문에 시간이 오래 걸리는데, shallow나 partial clone을 활용할 수도 있다.
이후에는 사용자 의도에 맞게 코드의 일부를 변경했다고 가정하며, 지금은 간단하게 예를 들어 kubectl help 시 출력되는 문자열을 수정한다.
kubectl의 version.go 파일의 145번째 라인의 Client Version 사이에 Customized를 넣어줬다.
bconfiden2@h03:~/k8s-src$ vi staging/src/k8s.io/kubectl/pkg/cmd/version/version.go
# Line 145
fmt.Fprintf(o.Out, "Client Customized Version: %s\n", versionInfo.ClientVersion.GitVe rsion)
빌드 자체는 컨테이너 환경을 사용하기 때문에 굉장히 간단한데, 먼저 각종 패키지들을 설치해준다.
bconfiden2@h03:~/k8s-src$ sudo apt-get install -y socat conntrack
도커를 설치하는 과정에서 containerd와 ctr 역시 같이 설치되며, 이후에는 make만 수행해주면 끝!
bconfiden2@h03:~/k8s-src$ make quick-release
+++ [1017 11:38:32] Verifying Prerequisites....
+++ [1017 11:38:33] Building Docker image kube-build:build-a54a9432d7-5-v1.25.0-go1.19.2-bullseye.0
+++ [1017 11:51:27] Creating data container kube-build-data-a54a9432d7-5-v1.25.0-go1.19.2-bullseye.0
+++ [1017 11:51:48] Syncing sources to container
+++ [1017 11:51:59] Running build command...
+++ [1017 11:52:00] Building go targets for linux/amd64
k8s.io/kubernetes/cmd/kube-proxy (static)
k8s.io/kubernetes/cmd/kube-apiserver (static)
k8s.io/kubernetes/cmd/kube-controller-manager (static)
# ...
# ...
# ...
+++ [1017 12:04:40] Docker builds done
+++ [1017 12:04:40] Building tarball: server linux-amd64
+++ [1017 12:05:31] Building tarball: final
+++ [1017 12:05:33] Starting tarball: test linux-amd64
+++ [1017 12:05:33] Waiting on test tarballs
+++ [1017 12:06:22] Building tarball: test portable
시간이 약 30분 정도로 오래 걸렸다.
컨테이너에서 빌드한 결과는 호스트OS의 _output/release-stage
아래에 저장된다.
# 컨트롤 플레인과 관련된 실행파일들
bconfiden2@h03:~/k8s-src$ ls _output/release-stage/server/linux-amd64/kubernetes/server/bin
apiextensions-apiserver kube-controller-manager.docker_tag kube-proxy.docker_tag
kubeadm kube-controller-manager.tar kube-proxy.tar
kube-aggregator kubectl kube-scheduler
kube-apiserver kubectl-convert kube-scheduler.docker_tag
kube-apiserver.docker_tag kubelet kube-scheduler.tar
kube-apiserver.tar kube-log-runner mounter
kube-controller-manager kube-proxy
# 노드와 관련된 실행파일들
bconfiden2@h03:~/k8s-src$ ls _output/release-stage/node/linux-amd64/kubernetes/node/bin
kubeadm kubectl kubectl-convert kubelet kube-log-runner kube-proxy
빌드된 실행파일들을 /usr/bin
에 옮겨 사용한다.
cd _output/release-stage/server/linux-amd64/kubernetes/server/bin/
sudo cp kubeadm kubectl kubelet /usr/bin/
sudo mkdir -p /etc/kubernetes/manifests
sudo mkdir -p /etc/systemd/system/kubelet.service.d
sudo wget https://raw.githubusercontent.com/kubernetes/release/master/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf -P /etc/systemd/system/kubelet.service.d
sudo wget https://raw.githubusercontent.com/kubernetes/release/master/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service -P /etc/systemd/system
컨테이너 런타임을 containerd 로 설정해준 뒤,
bconfiden2@h03:~$ sudo vi /etc/containerd/config.toml
#disabled_plugin=["cri"] # 해당 부분 주석처리하기
bconfiden2@h03:~$ sudo systemctl restart containerd.service
containerd를 제어하기 위한 crictl 을 설치한다.
VERSION="v1.25.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
# 파일 생성 후 아래 내용 추가
bconfiden2@h03:~$ sudo vi /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
# docker images 처럼 컨테이너 이미지들 확인
bconfiden2@h03:~$ sudo crictl images
IMAGE TAG IMAGE ID SIZE
앞서 빌드되었던 컨테이너 이미지 파일들을 ctr을 사용하여 이미지를 등록해준다.
다만 빌드 시점에 따라 이미지 이름이 매번 달라지기 때문에, kube-proxy-amd64:버전버전버전
처럼 뒤에 붙는 버전은 달라질 수 있음을 주의해야 한다.
# 이미지 등록
sudo ctr -n k8s.io image import kube-proxy.tar
# 이미지 태그 변경해주기
sudo ctr -n k8s.io image tag registry.k8s.io/kube-proxy-amd64:v1.26.0-alpha.2.127_48608cfe60ed3a-dirty registry.k8s.io/kube-proxy:v1.26.0-alpha.2.127 registry.k8s.io/kube-proxy:v1.26.0-alpha.2.127
sudo ctr -n k8s.io image import kube-scheduler.tar
sudo ctr -n k8s.io image tag registry.k8s.io/kube-scheduler-amd64:v1.26.0-alpha.2.127_48608cfe60ed3a-dirty registry.k8s.io/kube-scheduler:v1.26.0-alpha.2.127 registry.k8s.io/kube-proxy:v1.26.0-alpha.2.127
sudo ctr -n k8s.io image import kube-apiserver.tar
sudo ctr -n k8s.io image tag registry.k8s.io/kube-apiserver-amd64:v1.26.0-alpha.2.127_48608cfe60ed3a-dirty registry.k8s.io/kube-apiserver:v1.26.0-alpha.2.127
registry.k8s.io/kube-apiserver:v1.26.0-alpha.2.127
sudo ctr -n k8s.io image import kube-controller-manager.tar
sudo ctr -n k8s.io image tag registry.k8s.io/kube-controller-manager-amd64:v1.26.0-alpha.2.127_48608cfe60ed3a-dirty registry.k8s.io/kube-controller-manager:v1.26.0-alpha.2.127
bconfiden2@h03:~/k8s-src/_output/release-stage/server/linux-amd64/kubernetes/server/bin$ sudo crictl images
IMAGE TAG IMAGE ID SIZE
registry.k8s.io/kube-apiserver v1.26.0-alpha.2.127 16f6e307b253d 129MB
registry.k8s.io/kube-controller-manager v1.26.0-alpha.2.127 0af0bc404f90c 116MB
registry.k8s.io/kube-proxy v1.26.0-alpha.2.127 08eef1e14c091 64.2MB
registry.k8s.io/kube-scheduler v1.26.0-alpha.2.127 712e41e1b09b3 52.9MB
최종적으로 등록한 kube-system 관련 이미지들을 사용하여 kubeadm으로 클러스터를 초기화한다.
kubeadm init 에다가, 빌드했던 쿠버네티스 버전을 명시해주면 그 이후로는 평소에 보던 kubeadm이랑 비슷한 메시지가 출력된다.
bconfiden2@h03:~/k8s-src/_output/release-stage/server/linux-amd64/kubernetes/server/bin$ sudo kubeadm init --kubernetes-version v1.26.0-alpha.2.127
[init] Using Kubernetes version: v1.26.0-alpha.2.127
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
# ...
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.30.113.22:6443 --token j7k18u.vgn00dhwx4l56cd0 \
--discovery-token-ca-cert-hash sha256:09c4c70e9521fe15e1e0eb21de693df66e152eb41fd1195663d8ac7918e408e6
수정해줬던 kubectl version 출력문도 변경되었다!
bconfiden2@h03:~$ kubectl version --short
Flag --short has been deprecated, and will be removed in the future. The --short output will become the default.
Client Customized Version: v1.26.0-alpha.2.127+48608cfe60ed3a-dirty
Kustomize Version: v4.5.7
Server Version: v1.26.0-alpha.2.127+48608cfe60ed3a-dirty