はじめに
444エンジニアの久保田です。 当社サービスのTechFULのバックエンドにGKEを使っています。GKEはGoogleさんがよろしくやってくれているのでk8sをよく知らなくても使い始められてしまいます。とてもありがたいのですが、ちょっとした試験するにいちいちクラウドにデプロイとかしたくないので、ローカルにk8sの試験環境を作ることにしました。ローカルでk8sを構築する簡易な手段としてminikubeやmicrok8sがあります。
わたしは普段Ubuntuを使っているので、今回はubuntu20.04でminikubeを構築します。
VirtualBoxのインストール
minikubeは仮想マシンとして HyperVisor やVirtualBox のほか、Dockerなどのコンテナでもインストールできます。今回は私が使い慣れたVirtualBoxで構築してみます。
sudo apt-get install virtualbox
minikubeのインストール
以下のサイトのまま
https://minikube.sigs.k8s.io/docs/start/
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb sudo dpkg -i minikube_latest_amd64.deb
kubectlのインストール
k8sのCLIであるkubectlもインストールしておきます。
sudo snap install kubectl --classic
minikubeクラスタの構築
k8sクラスタをローカル環境で立ち上げます。クラスタと言いつつ1台構成です。今回はVirtualBoxで構築するので以下のコマンドになります。ちなみに他の端末からもアクセス可能としたい場合は --apiserver-ips=192.168.100.100 とかHOST側OSのIPアドレスを指定しておきます。
minikube start --driver=virtualbox --apiserver-ips=10.252.61.218
ちなみにminikubeのクラスタのメモリ割当のデフォルト値は2GByte、CPU割当のデフォルト値は2コアですこちらを変更する場合は以下のように指定します。
minikube start --memory='16g' --cpus=12
しばらくするとクラスタが立ち上がります。minikubeは同時にkubectlの接続情報も初期化してくれます。以下のコマンドを実行してクラスタのノードの状態を見てみましょう。
$ kubectl describe nodes Name: minikube Roles: control-plane,master Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/arch=amd64 kubernetes.io/hostname=minikube kubernetes.io/os=linux minikube.k8s.io/commit=15cede53bdc5fe242228853e737333b09d4336b5 minikube.k8s.io/name=minikube minikube.k8s.io/updated_at=2021_05_07T18_18_42_0700 minikube.k8s.io/version=v1.19.0 node-role.kubernetes.io/control-plane= node-role.kubernetes.io/master= Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock node.alpha.kubernetes.io/ttl: 0 volumes.kubernetes.io/controller-managed-attach-detach: true CreationTimestamp: Fri, 07 May 2021 18:18:39 +0900 Taints: <none> Unschedulable: false Lease: HolderIdentity: minikube AcquireTime: <unset> RenewTime: Fri, 07 May 2021 20:09:39 +0900 Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- MemoryPressure False Fri, 07 May 2021 20:05:24 +0900 Fri, 07 May 2021 18:18:37 +0900 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Fri, 07 May 2021 20:05:24 +0900 Fri, 07 May 2021 18:18:37 +0900 KubeletHasNoDiskPressure kubelet has no disk pressure PIDPressure False Fri, 07 May 2021 20:05:24 +0900 Fri, 07 May 2021 18:18:37 +0900 KubeletHasSufficientPID kubelet has sufficient PID available Ready True Fri, 07 May 2021 20:05:24 +0900 Fri, 07 May 2021 18:18:49 +0900 KubeletReady kubelet is posting ready status Addresses: InternalIP: 192.168.99.103 Hostname: minikube Capacity: cpu: 12 ephemeral-storage: 17784752Ki hugepages-2Mi: 0 memory: 16417908Ki pods: 110 Allocatable: cpu: 12 ephemeral-storage: 17784752Ki hugepages-2Mi: 0 memory: 16417908Ki pods: 110 System Info: Machine ID: b18e74ec97a54e7592a95e07c40b494f System UUID: d5a90dc1-7493-bc4a-93dd-2fb45ada331f Boot ID: fbbd978a-66a6-449d-832e-033158d37314 Kernel Version: 4.19.171 OS Image: Buildroot 2020.02.10 Operating System: linux Architecture: amd64 Container Runtime Version: docker://20.10.4 Kubelet Version: v1.20.2 Kube-Proxy Version: v1.20.2 PodCIDR: 10.244.0.0/24 PodCIDRs: 10.244.0.0/24 Non-terminated Pods: (7 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age --------- ---- ------------ ---------- --------------- ------------- --- kube-system coredns-74ff55c5b-9d4pm 100m (0%) 0 (0%) 70Mi (0%) 170Mi (1%) 110m kube-system etcd-minikube 100m (0%) 0 (0%) 100Mi (0%) 0 (0%) 110m kube-system kube-apiserver-minikube 250m (2%) 0 (0%) 0 (0%) 0 (0%) 110m kube-system kube-controller-manager-minikube 200m (1%) 0 (0%) 0 (0%) 0 (0%) 110m kube-system kube-proxy-5h742 0 (0%) 0 (0%) 0 (0%) 0 (0%) 110m kube-system kube-scheduler-minikube 100m (0%) 0 (0%) 0 (0%) 0 (0%) 110m kube-system storage-provisioner 0 (0%) 0 (0%) 0 (0%) 0 (0%) 111m Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 750m (6%) 0 (0%) memory 170Mi (1%) 170Mi (1%) ephemeral-storage 100Mi (0%) 0 (0%) hugepages-2Mi 0 (0%) 0 (0%) Events: <none>
立ち上がっていますね。
名前空間の作成
kubectl create namespace test
GCR用のシークレット作成
ここからは本題です。このままではパブリックなdocker-registryからしかイメージを取得できません。実際GKEでサービス運用している場合は、GCR(Google Container Registry)のプライベートレジストリにイメージを配置していることが多いと思います。プライベートレジストリからイメージを取得するにはGCPの認証を通らなければなりません。そのためにはGCPのIAMでサービスアカウントを作成し、GCRへのアクセス権限を与え、そのサービスアカウントの認証情報をk8sの docker-registryシークレットとして登録します。
kubectl --namespace=compiler create secret docker-registry gcr-json-key \ --docker-server=https://gcr.io \ --docker-username=_json_key \ --docker-password="$(cat /home/hogehoge/key.json)" \ --docker-email=hogehoge@triple-four.com
gcr-json-key
はシークレット名です。任意の文字列を指定してください。--docker-server=https://gcr.io
はプライベートレジストリのURLです。---docker-username=_json_key
は_json_key
固定です。--docker-password=
は`先程作ったGCPのサービスアカウントの秘密鍵です。GoogleCloudConsoleから取得します。--docker-email=hogehoge@triple-four.com
は有効なメールアドレスを指定してください。
サービスアカウントの作成
次にk8sのサービスアカウントを作成します。これはk8sの世界のサービスアカウントです。上で作ったGCPのサービスアカウントとは別物と考えてください。
kubectl apply -f service_account.yml
k8sサービスアカウントに GCR用のシークレットを紐付ける
kubectl --namespace=compiler patch serviceaccount compile-publisher -p '{"imagePullSecrets": [{"name": "staging-gcr-json-key"}]}'
おわりに
これでubuntu20.04のローカルkubernatesでプライベートGCRのイメージを利用する環境が構築できました。