LoginSignup
29
24

More than 5 years have passed since last update.

VagrantでkubeadmでKubernetesを起動する

Last updated at Posted at 2018-12-07

今更ながらのVagrantの勉強を兼ね、vagrant upでKubernetesクラスターを簡単に起動するためのVagrantfileを作成したのでメモ。

参考資料

Vagrantfile

Masterはシングルで複数NodeのKubernetesクラスターを作成する。
注意すべき点は以下。

  • 各VMはNAT用に10.0.2.15という同じIP持っており、apiserverがそちらにバインドされてしまうため、kubeadm init--apiserver-advertise-addressなどを引数に設定
  • 同じくkubeletも10.0.2.15にバインドされてしまうため、kubeletの引数に--nodeipを指定する必要があり、そのためkubeletサービスのSystemdユニット定義から参照される/etc/default/kubelet(Ubuntu)または/etc/sysconfig/kubelet(CentOS)を修正する
  • Masterノード上で生成したkubeadm joinコマンドを、各Nodeはscpで取得して実行

(追記)以下に記載のものからKubernetesのバージョンアップへの対応などちょいちょい変更をしています。

Ubuntu

ネットワークプラグインはFlannelを使ってみる。

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

$configureBox = <<-SHELL

  # パッケージ更新
  apt-get update
  apt-get upgrade -y

  # Dockerの前提パッケージ
  apt-get install -y apt-transport-https ca-certificates curl software-properties-common
  # Dockerのレポジトリ追加
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
  add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  # Dockerのインストール
  apt-get update
  apt-get install -y docker-ce=$(apt-cache madison docker-ce | grep 17.03 | head -1 | awk '{print $3}')
  apt-mark hold docker-ce
  # vagrantユーザーをdockerグループに追加
  usermod -aG docker vagrant

  # Flannelの場合に必要
  # デフォルトが1なのでコメントアウト
  # echo net.bridge.bridge-nf-call-iptables = 1 >> /etc/sysctl.conf
  # sysctl -p

  # スワップを無効化する
  # スワップ領域がないのでコメントアウト
  # swapoff -a
  # プロビジョニングで実行する場合はバックスラッシュのエスケープが必要なことに注意
  # sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
  # sed -i '/ swap / s/^\\(.*\\)$/#\\1/g' /etc/fstab

  # Kubernetesの前提パッケージ
  # apt-get update
  # apt-get install -y apt-transport-https curl
  # Kubernetesのレポジトリ追加
  curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
  cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
  # kubeadm、kubelet、kubectlのインストール
  apt-get update
  # apt-get install -y kubelet=1.12.2-00 kubeadm=1.12.2-00 kubectl=1.12.2-00
  apt-get install -y kubelet kubeadm kubectl
  apt-mark hold kubelet kubeadm kubectl

  # プライベートネットワークのNICのIPアドレスを変数に格納
  IPADDR=$(ip a show enp0s8 | grep inet | grep -v inet6 | awk '{print $2}' | cut -f1 -d/)
  # kubeletがプライベートネットワークのNICにバインドするように設定
  sed -i "/KUBELET_EXTRA_ARGS=/c\KUBELET_EXTRA_ARGS=--node-ip=$IPADDR" /etc/default/kubelet
  # kubeletを再起動
  systemctl daemon-reload
  systemctl restart kubelet

SHELL

$configureMaster = <<-SHELL

  echo "This is master"

  # プライベートネットワークのNICのIPアドレスを変数に格納
  IPADDR=$(ip a show enp0s8 | grep inet | grep -v inet6 | awk '{print $2}' | cut -f1 -d/)
  # ホスト名を変数に格納
  HOSTNAME=$(hostname -s)

  # kubeadm initの実行
  # Flannelの場合
  kubeadm init --apiserver-advertise-address=$IPADDR --apiserver-cert-extra-sans=$IPADDR --node-name $HOSTNAME --pod-network-cidr=10.244.0.0/16
  # Calicoの場合
  # kubeadm init --apiserver-advertise-address=$IPADDR --apiserver-cert-extra-sans=$IPADDR --node-name $HOSTNAME --pod-network-cidr=192.168.0.0/16

  # vagrantユーザーがkubectlを実行できるようにする
  sudo --user=vagrant mkdir -p /home/vagrant/.kube
  cp -i /etc/kubernetes/admin.conf /home/vagrant/.kube/config
  chown $(id -u vagrant):$(id -g vagrant) /home/vagrant/.kube/config

  # Flannelのインストール
  export KUBECONFIG=/etc/kubernetes/admin.conf
  kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
  # Calicoのインストール
  # export KUBECONFIG=/etc/kubernetes/admin.conf
  # kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
  # kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml

  # kubectl joinコマンドを保存する
  kubeadm token create --print-join-command > /etc/kubeadm_join_cmd.sh
  chmod +x /etc/kubeadm_join_cmd.sh

  # sshでのパスワード認証を許可する
  sed -i "/^[^#]*PasswordAuthentication[[:space:]]no/c\PasswordAuthentication yes" /etc/ssh/sshd_config
  systemctl restart sshd

SHELL

$configureNode = <<-SHELL

  echo "This is worker"

  apt-get install -y sshpass
  sshpass -p "vagrant" scp -o StrictHostKeyChecking=no vagrant@192.168.33.11:/etc/kubeadm_join_cmd.sh .
  # sshpass -p "vagrant" scp -o StrictHostKeyChecking=no vagrant@172.16.33.11:/etc/kubeadm_join_cmd.sh .
  sh ./kubeadm_join_cmd.sh

SHELL

Vagrant.configure(2) do |config|

  (1..3).each do |i|

    if i == 1 then
      vm_name = "master"
    else
      vm_name = "node#{i-1}"
    end

    config.vm.define vm_name do |s|

      # ホスト名
      s.vm.hostname = vm_name
      # ノードのベースOSを指定
      s.vm.box = "ubuntu/xenial64"
      # ネットワークを指定
      # pod-network-cidrと重ならないように注意
      private_ip = "192.168.33.#{i+10}"
      # private_ip = "172.16.33.#{i+10}"
      s.vm.network "private_network", ip: private_ip

      # ノードのスペックを指定
      s.vm.provider "virtualbox" do |v|
        v.gui = false        
        if i == 1 then
          v.cpus = 2
          v.memory = 1024
        else
          v.cpus = 1
          v.memory = 1024
        end
      end

      # 共通のプロビジョニング
      s.vm.provision "shell", inline: $configureBox

      if i == 1 then
        # Masterのプロビジョニング
        s.vm.provision "shell", inline: $configureMaster
      else
        # Nodeのプロビジョニング
        s.vm.provision "shell", inline: $configureNode
      end

    end
  end
end

CentOS

こちらはネットワークプラグインはCalicoを使ってみる。CalicoのPodネットワーク192.168.0.0/16と重ならないようにするため、VirtualBoxのプライベートネットワークは172.16.33.0/24を使用する。

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

$configureBox = <<-SHELL

  # パッケージ更新
  yum update -y

  # Dockerの前提パッケージ
  yum install -y yum-utils device-mapper-persistent-data lvm2
  # Dockerのレポジトリ追加
  yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  # Dockerのインストール
  VERSION=$(yum list docker-ce --showduplicates | sort -r | grep 17.03 | head -1 | awk '{print $2}')
  yum install -y --setopt=obsoletes=0 docker-ce-$VERSION docker-ce-selinux-$VERSION
  systemctl enable docker && systemctl start docker
  # vagrantユーザーをdockerグループに追加
  usermod -aG docker vagrant

  # スワップを無効化する
  swapoff -a
  # プロビジョニングで実行する場合はバックスラッシュのエスケープが必要なことに注意
  # sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
  sed -i '/ swap / s/^\\(.*\\)$/#\\1/g' /etc/fstab

  # Kubernetesのレポジトリ追加
  cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF

  # SELinuxを無効化
  setenforce 0
  sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

  # kubeadm、kubelet、kubectlのインストール
  # yum install -y kubelet-1.12.2-0 kubeadm-1.12.2-0 kubectl-1.12.2-0 --disableexcludes=kubernetes
  yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
  systemctl enable kubelet && systemctl start kubelet

  cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
  sysctl --system

  # プライベートネットワークのNICのIPアドレスを変数に格納
  IPADDR=$(ip a show eth1 | grep inet | grep -v inet6 | awk '{print $2}' | cut -f1 -d/)
  # kubeletがプライベートネットワークのNICにバインドするように設定
  sed -i "/KUBELET_EXTRA_ARGS=/c\KUBELET_EXTRA_ARGS=--node-ip=$IPADDR" /etc/sysconfig/kubelet
  # kubeletを再起動
  systemctl daemon-reload
  systemctl restart kubelet

SHELL

$configureMaster = <<-SHELL

  echo "This is master"

  # プライベートネットワークのNICのIPアドレスを変数に格納
  IPADDR=$(ip a show eth1 | grep inet | grep -v inet6 | awk '{print $2}' | cut -f1 -d/)
  # ホスト名を変数に格納
  HOSTNAME=$(hostname -s)

  # kubeadm initの実行
  # Flannel
  # kubeadm init --apiserver-advertise-address=$IPADDR --apiserver-cert-extra-sans=$IPADDR --node-name $HOSTNAME --pod-network-cidr=10.244.0.0/16
  # Calico
  kubeadm init --apiserver-advertise-address=$IPADDR --apiserver-cert-extra-sans=$IPADDR --node-name $HOSTNAME --pod-network-cidr=192.168.0.0/16

  # vagrantユーザーがkubectlを実行できるようにする
  sudo --user=vagrant mkdir -p /home/vagrant/.kube
  cp -i /etc/kubernetes/admin.conf /home/vagrant/.kube/config
  chown $(id -u vagrant):$(id -g vagrant) /home/vagrant/.kube/config

  # Flannelのインストール
  # export KUBECONFIG=/etc/kubernetes/admin.conf
  # kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
  # Calicoのインストール
  export KUBECONFIG=/etc/kubernetes/admin.conf
  kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
  kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml

  # kubectl joinコマンドを保存する
  kubeadm token create --print-join-command > /etc/kubeadm_join_cmd.sh
  chmod +x /etc/kubeadm_join_cmd.sh

  # sshでのパスワード認証を許可する
  sed -i "/^[^#]*PasswordAuthentication[[:space:]]no/c\PasswordAuthentication yes" /etc/ssh/sshd_config
  systemctl restart sshd

SHELL

$configureNode = <<-SHELL

  echo "This is worker"

  yum install -y sshpass
  # sshpass -p "vagrant" scp -o StrictHostKeyChecking=no vagrant@192.168.33.11:/etc/kubeadm_join_cmd.sh .
  sshpass -p "vagrant" scp -o StrictHostKeyChecking=no vagrant@172.16.33.11:/etc/kubeadm_join_cmd.sh .
  sh ./kubeadm_join_cmd.sh

SHELL

Vagrant.configure(2) do |config|

  (1..3).each do |i|

    if i == 1 then
      vm_name = "master"
    else
      vm_name = "node#{i-1}"
    end

    config.vm.define vm_name do |s|

      # ホスト名
      s.vm.hostname = vm_name
      # ノードのベースOSを指定
      s.vm.box = "centos/7"
      # ネットワークを指定
      # pod-network-cidrと重ならないように注意
      # private_ip = "192.168.33.#{i+10}"
      private_ip = "172.16.33.#{i+10}"
      s.vm.network "private_network", ip: private_ip

      # ノードのスペックを指定
      s.vm.provider "virtualbox" do |v|
        v.gui = false        
        if i == 1 then
          v.cpus = 2
          v.memory = 1024
        else
          v.cpus = 1
          v.memory = 1024
        end
      end

      # 共通のプロビジョニング
      s.vm.provision "shell", inline: $configureBox

      if i == 1 then
        # Masterのプロビジョニング
        s.vm.provision "shell", inline: $configureMaster
      else
        # Nodeのプロビジョニング
        s.vm.provision "shell", inline: $configureNode
      end

    end
  end
end

動作確認

Ubuntu

$ vagrant up
Bringing machine 'master' up with 'virtualbox' provider...
Bringing machine 'node1' up with 'virtualbox' provider...
Bringing machine 'node2' up with 'virtualbox' provider...
==> master: Importing base box 'ubuntu/xenial64'...
==> master: Matching MAC address for NAT networking...

(省略)

    node2: Run 'kubectl get nodes' on the master to see this node join the cluster.
sotoiwa@sotonombp:~/workspace/vagrant-k8s-ubuntu
$ vagrant ssh master
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-140-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

0 packages can be updated.
0 updates are security updates.

New release '18.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.


*** System restart required ***
vagrant@master:~$ kubectl get node -o wide
NAME     STATUS   ROLES    AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master   Ready    master   3m34s   v1.13.0   192.168.33.11   <none>        Ubuntu 16.04.5 LTS   4.4.0-140-generic   docker://17.3.3
node1    Ready    <none>   2m3s    v1.13.0   192.168.33.12   <none>        Ubuntu 16.04.5 LTS   4.4.0-140-generic   docker://17.3.3
node2    Ready    <none>   37s     v1.13.0   192.168.33.13   <none>        Ubuntu 16.04.5 LTS   4.4.0-140-generic   docker://17.3.3
vagrant@master:~$ kubectl get po --all-namespaces -o wide
NAMESPACE     NAME                             READY   STATUS    RESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
kube-system   coredns-86c58d9df4-mkg9w         1/1     Running   0          3m26s   10.244.0.2      master   <none>           <none>
kube-system   coredns-86c58d9df4-rkzfp         1/1     Running   0          3m26s   10.244.0.3      master   <none>           <none>
kube-system   etcd-master                      1/1     Running   0          2m39s   192.168.33.11   master   <none>           <none>
kube-system   kube-apiserver-master            1/1     Running   0          2m41s   192.168.33.11   master   <none>           <none>
kube-system   kube-controller-manager-master   1/1     Running   0          2m24s   192.168.33.11   master   <none>           <none>
kube-system   kube-flannel-ds-amd64-27mm7      1/1     Running   0          48s     192.168.33.13   node2    <none>           <none>
kube-system   kube-flannel-ds-amd64-l8tj7      1/1     Running   0          2m14s   192.168.33.12   node1    <none>           <none>
kube-system   kube-flannel-ds-amd64-q6bhm      1/1     Running   0          3m26s   192.168.33.11   master   <none>           <none>
kube-system   kube-proxy-bqpx8                 1/1     Running   0          48s     192.168.33.13   node2    <none>           <none>
kube-system   kube-proxy-dltht                 1/1     Running   0          3m26s   192.168.33.11   master   <none>           <none>
kube-system   kube-proxy-gg6sl                 1/1     Running   0          2m14s   192.168.33.12   node1    <none>           <none>
kube-system   kube-scheduler-master            1/1     Running   0          2m48s   192.168.33.11   master   <none>           <none>
vagrant@master:~$

CentOS

$ vagrant up
Bringing machine 'master' up with 'virtualbox' provider...
Bringing machine 'node1' up with 'virtualbox' provider...
Bringing machine 'node2' up with 'virtualbox' provider...
==> master: Importing base box 'centos/7'...
==> master: Matching MAC address for NAT networking...

(省略)

    node2: Run 'kubectl get nodes' on the master to see this node join the cluster.
sotoiwa@sotonombp:~/workspace/vagrant-k8s-centos
$ vagrant ssh master
[vagrant@master ~]$ kubectl get node -o wide
NAME     STATUS   ROLES    AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION               CONTAINER-RUNTIME
master   Ready    master   10m     v1.13.0   172.16.33.11   <none>        CentOS Linux 7 (Core)   3.10.0-862.14.4.el7.x86_64   docker://17.3.3
node1    Ready    <none>   7m      v1.13.0   172.16.33.12   <none>        CentOS Linux 7 (Core)   3.10.0-862.14.4.el7.x86_64   docker://17.3.3
node2    Ready    <none>   3m51s   v1.13.0   172.16.33.13   <none>        CentOS Linux 7 (Core)   3.10.0-862.14.4.el7.x86_64   docker://17.3.3
[vagrant@master ~]$ kubectl get po --all-namespaces -o wide
NAMESPACE     NAME                             READY   STATUS    RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
kube-system   calico-node-24jkl                2/2     Running   0          7m7s    172.16.33.12   node1    <none>           <none>
kube-system   calico-node-dnjbb                2/2     Running   0          4m4s    172.16.33.13   node2    <none>           <none>
kube-system   calico-node-hhscc                2/2     Running   0          10m     172.16.33.11   master   <none>           <none>
kube-system   coredns-86c58d9df4-hlmpt         1/1     Running   0          10m     192.168.0.2    master   <none>           <none>
kube-system   coredns-86c58d9df4-phbjg         1/1     Running   0          10m     192.168.0.3    master   <none>           <none>
kube-system   etcd-master                      1/1     Running   0          9m30s   172.16.33.11   master   <none>           <none>
kube-system   kube-apiserver-master            1/1     Running   0          9m2s    172.16.33.11   master   <none>           <none>
kube-system   kube-controller-manager-master   1/1     Running   3          9m4s    172.16.33.11   master   <none>           <none>
kube-system   kube-proxy-cmc72                 1/1     Running   0          7m7s    172.16.33.12   node1    <none>           <none>
kube-system   kube-proxy-h5z7t                 1/1     Running   0          4m4s    172.16.33.13   node2    <none>           <none>
kube-system   kube-proxy-kbgm5                 1/1     Running   0          10m     172.16.33.11   master   <none>           <none>
kube-system   kube-scheduler-master            1/1     Running   3          9m30s   172.16.33.11   master   <none>           <none>
[vagrant@master ~]$
29
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
24