# -*- mode: ruby -*- # vi: set ft=ruby : require 'yaml' # 設定ファイルの読み込み settings = YAML.load_file('config.yaml') ################################## # 共通のプロビジョニングスクリプト ################################## $configureBox = <<-SHELL # デフォルトゲートウェイ,DNSの変更 # 今回のネットワーク構成ではkubernetes用のIPアドレスを割り当てたIFからインターネット接続を行うため # そのIFにデフォルトゲートウェイとDNSサーバのアドレスを設定する。 # それ以外のネットワークIF(Vagrantで使うIFからはデフォルトゲートウェイ,DNSを削除する) # Vagrant用のIFのDHCPサーバでrouterアドレスを割り当てない設定をしていればなくても問題はない。 #(\は再度エスケープする必要がある) while read IFNAME; do echo "-----------" echo ${IFNAME} nmcli -f ipv4 con show "${IFNAME}" | grep -F ${2} > /dev/null 2>&1 if [ ${?} -eq 0 ]; then # nmcli con mod "${IFNAME}" ipv4.ignore-auto-routes no nmcli con mod "${IFNAME}" ipv4.ignore-auto-dns no nmcli con mod "${IFNAME}" ipv4.gateway ${3} nmcli con mod "${IFNAME}" ipv4.gateway ${3} nmcli con mod "${IFNAME}" ipv4.dns ${4} nmcli con down "${IFNAME}" nmcli con up "${IFNAME}" else # DHCPによる自動ルーティング設定、自動DNS設定の無効化とDNS設定の削除 nmcli con mod "${IFNAME}" ipv4.ignore-auto-routes yes nmcli con mod "${IFNAME}" ipv4.ignore-auto-dns yes nmcli con mod "${IFNAME}" ipv4.dns "" nmcli con mod "${IFNAME}" ipv4.gateway "" nmcli con down "${IFNAME}" nmcli con up "${IFNAME}" fi done < <(nmcli device show | grep -F GENERAL.CONNECTION: | grep -v "\\-\\-" | cut -d: -f2 | sed 's/^[[:blank:]]*//') # パッケージ更新 dnf update -y # スワップの無効化 swapoff -a # /etc/fstabの編集(\は再度エスケープする必要がある) sed -i '/ swap / s/^\\(.*\\)$/#\\1/g' /etc/fstab # /etc/hostsの編集 echo "${1}" >> /etc/hosts # firewalldの無効化 systemctl disable --now firewalld # SELinuxの無効化 setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config # ノードのipv6無効化 echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf # ノードのネットワーク・ブリッジを通過するパケットにiptablesを適用 cat < /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF # ノードのipv4のフォワード設定 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf # 上記sysctl関連の変更を反映 sysctl --system # コンテナランタイムのインストール dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo dnf install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.2.el7.x86_64.rpm -y dnf install docker-ce docker-ce-cli -y # Dockerデーモンの設定 mkdir -p /etc/docker cat > /etc/docker/daemon.json < /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\\$basearch 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=kubelet kubeadm kubectl EOF # kubeadm、kubelet、kubectlのインストール dnf install kubelet kubeadm kubectl --disableexcludes=kubernetes -y systemctl enable --now kubelet # kubeletがノードのIPアドレスを正しく認識するように設定 # yamlで指定したIPは追加のネットワークインタフェースに付与される # プライマリインタフェースはDHCPでIPがふられるため、ここでは選択しない。 sed -i "/KUBELET_EXTRA_ARGS=/c\KUBELET_EXTRA_ARGS=--node-ip=${2}" /etc/sysconfig/kubelet # kubeletを再起動 systemctl daemon-reload systemctl restart kubelet # sshでのパスワード認証を許可する sed -i "/^[^#]*PasswordAuthentication[[:space:]]no/c\PasswordAuthentication yes" /etc/ssh/sshd_config systemctl restart sshd SHELL ############################################ # Control Plane のプロビジョニングスクリプト ############################################ $configureMaster = <<-SHELL echo "This is Control Plane" # kubeadm initの実行 kubeadm init --apiserver-advertise-address "${1}" --pod-network-cidr "${2}" # 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 # rootユーザーがkubectlを実行できるようにする mkdir -p /root/.kube cp -i /etc/kubernetes/admin.conf /root/.kube/config # Calicoのインストール export KUBECONFIG=/etc/kubernetes/admin.conf kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml # kubectl joinコマンドを保存する kubeadm token create --print-join-command > /etc/kubeadm_join_cmd.sh chmod +x /etc/kubeadm_join_cmd.sh SHELL ########################################## # Worker node のプロビジョニングスクリプト ########################################## $configureNode = <<-SHELL echo "This is worker" dnf install -y epel-release dnf install -y sshpass while :; do sshpass -p "vagrant" scp -o StrictHostKeyChecking=no vagrant@${1}:/etc/kubeadm_join_cmd.sh . if [ ${?} -eq 0 ]; then break else echo "Wait until the control plane is ready." sleep 5 fi done sh ./kubeadm_join_cmd.sh SHELL Vagrant.configure(2) do |config| add_hosts_str = "" control_plane_ip = "" settings['nodes'].each do |node| # /etc/hostsに追加する文字列の生成 add_hosts_str << "#{node['ip']} #{node['hostname']}\n" if node['type'] == "control-plane" then # Control PlaneのIP取得 control_plane_ip = node['ip'] end end # 共有フォルダを使用しない config.vm.synced_folder '.', '/vagrant', disabled: true settings['nodes'].each do |node| config.vm.define node['hostname'] do |s| # ホスト名 s.vm.hostname = node['hostname'] # ノードのベースOSを指定 s.vm.box = settings['os'] # ネットワークを指定 # pod-network-cidrと重ならないように注意 s.vm.network "private_network", ip: node['ip'] s.vm.provider :vmware_esxi do |esxi| # 構築先のESXiの情報 esxi.esxi_hostname = settings['esxi']['hostname'] esxi.esxi_username = settings['esxi']['username'] esxi.esxi_password = settings['esxi']['password'] esxi.esxi_hostport = settings['esxi']['hostport'] esxi.esxi_virtual_network = settings['esxi']['virtualnetworks'] esxi.esxi_disk_store = settings['esxi']['diskstore'] esxi.guest_guestos = settings['os_type'] # 構築するVMの設定 esxi.guest_name = node['hostname'] esxi.guest_username = settings['guest_user'] esxi.guest_memsize = node['memory'] esxi.guest_numvcpus = node['cpus'] esxi.guest_disk_type = node['disk_type'] esxi.guest_boot_disk_size = node['disk_size'] end # 共通のプロビジョニング s.vm.provision "shell", inline: $configureBox, args: [add_hosts_str, node['ip'], settings['default-gw'], settings['dns']] if node['type'] == "control-plane" then # Contril Plane Node のプロビジョニング s.vm.provision :shell do |shell| shell.inline = $configureMaster shell.args = [control_plane_ip, settings['kubeadm']['pod-network-cidr']] end else # Worker Node のプロビジョニング s.vm.provision :shell do |shell| shell.inline = $configureNode shell.args = [control_plane_ip] end end end end end