フラミナル

考え方や調べたことを書き殴ります。IT技術系記事多め

kubernetesをkubeadmでVagrant上のCentOS7にインストールする

kubernetesの環境をサクッと用意したいので手順を示しておきます。

仮想マシンの準備

以下のようなVagrantfileを用意します。今回はmaster1台とworker node1台の構成でいきます。

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

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.define "master"
  config.vm.define "node1"

  config.vm.define "master" do |machine|
    machine.vm.hostname = "master"
    machine.vm.network "private_network", ip: "192.168.10.1", virtualbox__intnet: "intnet"
  end

  config.vm.define "node1" do |machine|
    machine.vm.hostname = "node1"
    machine.vm.network "private_network", ip: "192.168.10.2", virtualbox__intnet: "intnet"
  end
  
  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "4096"
    vb.cpus = 2
  end
  config.vm.provision "shell", inline: <<-SHELL
    yum update
    yum -y install git vim wget net-tools
    echo "192.168.10.1 master" >> /etc/hosts
    echo "192.168.10.2 node1" >> /etc/hosts
  SHELL
end

このような最終構成を目指します。

f:id:lirlia:20200412095137p:plain

ファイルを配置したらvagrant upと叩いてください。正常に終われば以下のコマンドでサーバにSSHできるようになります。

$ vagrant ssh master
$ vagrant ssh node1

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
EOF

# Set SELinux in permissive mode (effectively disabling it)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

systemctl enable --now kubelet

このコマンドではkubeadmkubeletkubectlをインストールしています。

  • kubeadm ー k8sクラスターを起動するコマンド
  • kubelet ー k8sクラスター内のすべてのマシンで実行されるコンポーネント。 Podやコンテナの起動などを行う。
  • kubectl ー クラスターにアクセスするためのCLI

f:id:lirlia:20200412095137p:plain

その後、以下の問題がありますのでカーネルパラメータを設定します。

RHEL / CentOS 7の一部のユーザーは、iptablesがバイパスされるためにトラフィックが正しくルーティングされない問題を報告しています。

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

そしてmodprobe br_netfilterコマンドを叩いておきます。


Dockerをインストールする

今回はとりあえずコンテナランタイムとしてDockerを使います。

yum -y install docker
systemctl enable docker; systemctl start docker

kubeadmでk8sクラスタを構築する

これに従いながらやっていきます。

ここからのコマンドはmasterに対して行います。また使用するContainer Network Interfaceは Calicoです。

swapoff -a
kubeadm init  --pod-network-cidr 192.168.20.0/24 --apiserver-advertise-address=192.168.10.1 --control-plane-endpoint=192.168.10.1

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bashrc 

ついでにswapを無効化するようにしましょう。

vim /lib/systemd/system/kubelet.service

ExecStart=/usr/bin/kubelet
↓
ExecStart=swapoff -a && /usr/bin/kubelet

コマンドを叩くとすでにk8sクラスタが存在していることがわかります。

# kubectl get nodes
NAME     STATUS     ROLES    AGE     VERSION
master   NotReady   master   4m51s   v1.18.1

calico(CNI)のインストール

calicoのpodをmaster上で動作させます。

wget https://docs.projectcalico.org/v3.8/manifests/calico.yaml

以下のように書き換えます。

            - name: CALICO_IPV4POOL_CIDR
-             value: "192.168.0.0/16"
+            value: "192.168.20.0/24"

適用します。

kubectl apply -f calico.yaml

# kubectl get pods -A
NAMESPACE     NAME                                       READY   STATUS              RESTARTS   AGE
kube-system   calico-kube-controllers-77c5fc8d7f-pw6v6   0/1     ContainerCreating   0          45s
kube-system   calico-node-n6gdq                          0/1     PodInitializing     0          45s
kube-system   coredns-66bff467f8-g6g92                   0/1     ContainerCreating   0          8m43s
kube-system   coredns-66bff467f8-wcvgw                   0/1     ContainerCreating   0          8m43s
kube-system   etcd-master                                1/1     Running             0          8m55s
kube-system   kube-apiserver-master                      1/1     Running             0          8m55s
kube-system   kube-controller-manager-master             1/1     Running             0          8m55s
kube-system   kube-proxy-kxccw                           1/1     Running             0          8m45s
kube-system   kube-scheduler-master                      1/1     Running             0          8m55s

k8sクラスタへの参加

そしてこのコマンドが成功するとこのようなコマンドが出力されます。

kubeadm join 192.168.10.1:6443 --token np5hdd.y6o94strreezcdhh \
    --discovery-token-ca-cert-hash sha256:70957a439608b6457c71c675e78f4db7a9c34cb47a21101782b29f9a363d6270

ハッシュ値などはかわるのでそれを使ってください。これはnodeをk8sクラスタに参加させるコマンドです。

swapoff -a
systemctl enable kubelet.service ; systemctl start kubelet.service
kubeadm join 192.168.10.1:6443 --token np5hdd.y6o94strreezcdhh \
    --discovery-token-ca-cert-hash sha256:70957a439608b6457c71c675e78f4db7a9c34cb47a21101782b29f9a363d6270

ついでにswapを無効化するようにしましょう。

vim /lib/systemd/system/kubelet.service

ExecStart=/usr/bin/kubelet
↓
ExecStart=swapoff -a && /usr/bin/kubelet

ここまできたらmaster上でkubectlを叩くとnodeが表示されるようになります。

[root@master vagrant]# kubectl get nodes
NAME     STATUS   ROLES    AGE     VERSION
master   Ready    master   5h24m   v1.18.1
node1    Ready    <none>   5h22m   v1.18.1

kube-proxyのnodeport-addressの設定を192.168.10.0/24にする

kubectl -n kube-system edit cm kube-proxy

    mode: ""
    nodePortAddresses: null を↓にする
    nodePortAddresses: ["192.168.10.0/24"]
    oomScoreAdj: null
kubectl get pods -A |grep proxy ででてきたpodを
kubectl delete pod --namespace=kube-system [pod name] で削除します

サンプルserviceとpodを起動してみる

このコマンドまずはmanifestの雛形を作ります。

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
  
---
  
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: 80

kubectl applyで作成します。

kubectl apply -f nginx.yaml 
kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        7h2m
nginx        NodePort    10.104.9.71   <none>        80:30405/TCP   39m

するとこのようにnginxが起動していることがわかりますね。curlでアクセスしてみましょう。

$ curl 192.168.10.1:30405
  
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

はい! アクセスできました。 ここまでやった方お疲れ様でした。