LoginSignup
15
5

More than 5 years have passed since last update.

(Proxy環境下)kubeadmでkubernetesシングルクラスタ構築

Last updated at Posted at 2019-04-08

初めに

本記事は、 kubeadm によるkubernetesのシングルクラスタ(Master1台、Worker1台)の環境構築について記載します。Proxy環境下で、sudo をつけてコマンド実行する方向けです。
シングルクラスタ環境を作るための手順は、大きく4つあります:

  1. 事前準備(Master, Worker)
  2. kubeadm による kubernetes(v1.14)環境構築(Master、 Worker)
  3. CNI(Container Network Interface)のインストール(Master)
  4. Worker nodeの登録(Worker)

今回のベースとなる環境(Master, Worker):

command
lsb_release -a
output
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:        16.04
Codename:       xenial
  • 2cores
  • 8GB RAM
  • 40GB HDD

1. 事前準備(Master, Worker)

  1. Proxyの設定

    command
    export http_proxy='http://your_proxy:password@hogehogeproxy.com'
    export https_proxy='http://your_proxy:password@hogehogeproxy.com'
    
    • /etc/apt/apt.conf.d/01proxy を用意しても良いですが、今回は 不要 です:
    /etc/apt/apt.conf.d/01proxyを用意するcommand
    echo "Acquire::http::Proxy \"http://your_proxy.pass@hogehogeproxy.com\"" | sudo tee /etc/apt/apt.conf.d/01proxy
    echo "Acquire::https::Proxy \"http://your_proxy.pass@hogehogeproxy.com\"" | sudo tee -a /etc/apt/apt.conf.d/01proxy
    
  2. dockerのインストール

    • dockerの公式ページに沿ってインストール
      • あるある: 公式ドキュメント通りにコマンド実行しても、社内Proxy環境下ではうまくいかないケースが多い
    command
    sudo -E apt remove docker docker-engine docker.io containerd runc -y
    sudo -E apt update
    sudo -E apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y
    sudo -E bash -c "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -"
    sudo -E apt-key fingerprint 0EBFCD88
    sudo -E add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo -E apt update
    sudo -E apt install docker-ce docker-ce-cli containerd.io -y
    sudo systemctl start docker
    sudo mkdir -p /etc/systemd/system/docker.service.d
    
    ...(snip)...
    Found linux image: /boot/vmlinuz-4.4.0-145-generic
    Found initrd image: /boot/initrd.img-4.4.0-145-generic
    Found linux image: /boot/vmlinuz-4.4.0-143-generic
    Found initrd image: /boot/initrd.img-4.4.0-143-generic
    Found memtest86+ image: /boot/memtest86+.elf
    Found memtest86+ image: /boot/memtest86+.bin
    done
    
  3. DockerのProxy設定

    command(Proxyの値は適宜書き換えてください)
    sudo bash -c "echo -e \"[Service]\nEnvironment=\"HTTP_PROXY=http://proxy_user:proxy_pass@your_proxy.com\"\nEnvironment=\"HTTPS_PROXY=http://proxy_user:proxy_pass@your_proxy.com\"\nEnvironment=\"NO_PROXY=localhost,127.0.0.1,192.168.122.33,192.168.0.0/16,10.96.0.0/16,10.244.0.0/16,111.111.0.0/16\"\" | tee vi /etc/systemd/system/docker.service.d/http-proxy.conf"
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    systemctl show --property=Environment docker
    
    ...(snip)...
    Environment=HTTP_PROXY=http://proxy_user:proxy_pass@your_proxy.com HTTPS_PROXY=http://proxy_user:proxy_pass@your_proxy.com NO_PROXY=localhost,127.0.0.1,192.168.122.33
    
    • NO_PROXY には、MasterのIPを指定
    • (追記)ごめんなさい以下の書き方は間違っていました。no_proxyにCIDRを指定しても効いていないとのことでした:
      • NO_PROXY=localhost,127.0.0.1,192.168.122.33,192.168.0.0/16,10.96.0.0/16,10.244.0.0/16,111.111.0.0/16
  4. kubeadm, kubelet, kubectlのインストール

    command
    sudo -E apt update; sudo -E apt install -y apt-transport-https curl
    curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo -E apt-key add -
    echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
    sudo -E apt update
    sudo -E apt install -y kubelet kubeadm kubectl
    sudo -E apt-mark hold kubelet kubeadm kubectl
    
    ...(snip)...
    Unpacking kubeadm (1.14.0-00) ...
    Setting up cri-tools (1.12.0-00) ...
    Setting up kubernetes-cni (0.7.5-00) ...
    Setting up kubelet (1.14.0-00) ...
    Setting up kubectl (1.14.0-00) ...
    Setting up kubeadm (1.14.0-00) ...
    
  5. kubeletの起動時引数に --fail-swap-on=false を追加後デーモンの再起動&kubeletが起動時に立ち上がる設定

    command
    sudo sed -i "/^\[Service\]$/a Environment=\"KUBELET_EXTRA_ARGS=--fail-swap-on=false\"" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    sudo systemctl daemon-reload; sudo systemctl stop kubelet
    sudo systemctl enable kubelet; sudo systemctl start kubelet
    
    • あるある: --fail-swap-on=false を付け忘れると kubeletが起動しないことが多い。 v1.9のときもそうでした。
  6. この時点で、screenや別ウィンドウを使って、下記のコマンドの出力結果を出して続けておく。

    • この先、コンテナが起動したかどうかの確認が楽になります。
    command
    watch -d kubectl get pods --all-namespaces -o wide
    
    この時点ではこんな出力ですが、気にせず先に進みます
    Every 2.0s: kubectl get pods --all-namespaces -o wide             Sat Apr  6 xx:xx:2019
    .
    The connection to the server localhost:8080 was refused - did you specify the right host or port?
    

2. kubernetes の構築(Masterのみ)

  1. kubeadm init を実行して kubernetes環境をデプロイ

    • 本手順書では、 Canal をインストールします
    command
    sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=swap
    
    ..(snip)...
    [preflight] This might take a minute or two, depending on the speed of your internet connection
    [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
    ...(体感3分くらい)...
    Your Kubernetes control-plane has initialized successfully!
    ...(snip)...
    
    • Your Kubernetes control-plane has initialized successfully! があれば成功です
    • 下記のようなエラーになったため、--ignore-preflight-errors=swap オプションをつけて実行しています
    • あとWARNINGも出ていますが 面倒なので今回は スルーします

      ...(snip)...
      [init] Using Kubernetes version: v1.14.0
      [preflight] Running pre-flight checks
      [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
      error execution phase preflight: [preflight] Some fatal errors occurred:
      [ERROR Swap]: running with swap on is not supported. Please disable swap
      [preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
      
  2. To start using your cluster, you need to run the following as a regular user に従って、コマンド実行

    command
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
  3. 上記コマンド実行後、 watch -d を実行していた画面に下記のような状態が出力されることを確認。

    NAMESPACE     NAME                              READY   STATUS    RESTARTS   AGE     IP                NODE      NOMINATED NODE   READINESS GATES
    kube-system   coredns-fb8b8dccf-sj9fb           0/1     Pending   0          3m14s   <none>            <none>    <none>           <none>
    kube-system   coredns-fb8b8dccf-tx8pn           0/1     Pending   0          3m14s   <none>            <none>    <none>           <none>
    kube-system   etcd-compute                      1/1     Running   0          2m27s   192.168.123.236   compute   <none>           <none>
    kube-system   kube-apiserver-compute            1/1     Running   0          2m35s   192.168.123.236   compute   <none>           <none>
    kube-system   kube-controller-manager-compute   1/1     Running   0          2m11s   192.168.123.236   compute   <none>           <none>
    kube-system   kube-proxy-8dvn6                  1/1     Running   0          3m14s   192.168.123.236   compute   <none>           <none>
    kube-system   kube-scheduler-compute            1/1     Running   0          2m15s   192.168.123.236   compute   <none>           <none>
    
    • coredns-なんちゃらPending の状態ですが、ここでは放置して次に進みます。

3. CNIのインストール(Masterのみ)

Canalの場合

  1. こちらを参考に下記のコマンドを実行

    command
    kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
    kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/canal.yaml
    
    clusterrole.rbac.authorization.k8s.io/calico created
    clusterrole.rbac.authorization.k8s.io/flannel created
    clusterrolebinding.rbac.authorization.k8s.io/canal-flannel created
    clusterrolebinding.rbac.authorization.k8s.io/canal-calico created
    configmap/canal-config created
    daemonset.extensions/canal created
    serviceaccount/canal created
    ...(snip)...
    customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
    
    • 本コマンド実行後、canal-なんたら というPodの作成が始まります。
    • coredns と上記Podを含む全てのPodが Running になることを確認しましょう
      • 体感2分30秒くらい

4. Worker nodeの登録(Workerのみ)

  1. Worker node にSSHでログイン後、sudoになります(公式ドキュメント通りに)

    command
    sudo su -
    
  2. kubeadm init の出力結果に表示された kubeadm join を実行します

    command
    kubeadm join 192.168.122.33:6443 --token miserarenaiyo --discovery-token-ca-cert-hash sha256:kottimoyapparimiserarenaiyo --ignore-preflight-errors=swap
    
    • あるある: UbuntuでSwapをオフにする設定をあとで調べようと思っていても、忘れる(揮発性)
    ...(snip)...
    This node has joined the cluster:
    * Certificate signing request was sent to apiserver and a response was received.
    * The Kubelet was informed of the new secure connection details.
    -
    Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
    
  3. Master上でノード一覧を表示して、Workerが追加されていることを確認します

    command
    kubectl get nodes
    
    NAME       STATUS     ROLES    AGE    VERSION
    k-master   Ready      master   157m   v1.14.0
    k-worker   Ready      <none>   87s    v1.14.0
    
    • STATUSReady になれば登録成功です。お疲れ様でした。

トラシュー

実際に遭遇したエラーの対処について記載します。

kubeadm init がコケる

  • kubeletの状況確認

    command
    journalctl -f -e -u kubelet.service
    
  • docker の Proxy設定状況の確認

    command
    systemctl show --property=Environment docker
    
    • ここの設定が抜けていたので、Proxy設定後、docker-daemonをリロード
  • kubeadm init を再度実行するため、作成したPodを全て削除

    command
    kubectl delete -f <curl or yaml file>
    
  • kubeadm reset 後、 $HOME ディレクトリの .kube/ を削除

    command
    sudo kubeadm reset
    rm -rf ~/.kube
    
  • 上記実行後、 kubeadm init を再度実行

    • .kube/ を消さない場合、 kubectl コマンドが実行できなくなりました(証明書関係のエラーでしたが、ログを取り忘れました...)

Worker Nodeの STATUS が一生 NotReady

Worker側の kubelet がエラーを吐いている可能性があります。私は下記の2つの現象が発生していました:

(A) Worker Node上の docker-daemonがProxy設定を認知していない
(B) CNIの設定ファイル、ディレクトリがWorkerノードに存在しない

いずれの場合においても、 まずはWorker nodeの登録解除をする必要があります。

  1. (Master) Worker nodeの登録を解除

    command
    kubectl delete node <worker-node-name>
    
  2. (Worker) joinの状態を解除する(rootで実行)

    command
    kubeadm reset
    iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
    

(A) Worker Node上の docker-daemonがProxy設定を認知していない

  1. kubelet の状態を確認

    command
    journalctl -f -e -u kubelet.service
    
    ...(snip)...
    Apr 01 19:24:56 k-worker kubelet[9131]: E0401 19:24:56.331896 9131 pod_workers.go:190] Error syncing pod
    836c281a-5465-11e9-8b12-5254007d68f0 ("canal-jwfln_kube-system(836c281a-5465-11e9-8b12-5254007d68f0)"),
    skipping: failed to "CreatePodSandbox" for "canal-jwfln_kube-system(836c281a-5465-11e9-8b12-5254007d68f0)"
    with CreatePodSandboxError: "CreatePodSandbox for pod \"canal-jwfln_kube-system(836c281a-
    5465-11e9-8b12-5254007d68f0)\" failed: rpc error: code = Unknown desc = failed pulling image
    \"k8s.gcr.io/pause:3.1\": Error response from daemon: Get https://k8s.gcr.io/v2/: dial tcp:
    lookup k8s.gcr.io on 192.168.122.1:53: no such host"
    
    • CanalのPodを作る際の docker pull にコケているように見えます
    • このエラーが出ているときは、まずはProxy設定を確認してみましょう
  2. Proxyの設定状況を確認(DockerのProxy設定 参照)

    command
    systemctl show --property=Environment docker
    
  3. Proxy定義ファイル(/etc/systemd/system/docker.service.d/http-proxy.conf)はあるのにデーモン側で設定されていない場合、デーモンの再起動忘れの可能性があるため、 docker-daemonを再起動

    command
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    • その他の見直しポイント
      • http_proxy, https_proxy にはそれぞれ、適切なproxyが設定されているか?
        • http のproxy しか存在しない状態で https 、あるいはその逆を指定していないか?
      • no_proxyに下記のアドレスはセットされているか?
        • flannel, calico, canalが使うサブネット
        • Master, Worker のIPアドレス
  4. 再度 worker側から kubeadm join コマンドを実行

(B) CNIの設定ファイル、ディレクトリがWorkerノードに存在しない

下記のようなエラーメッセージが確認できます

command
journalctl -f -e -u kubelet.service
...(snip)...
Apr 01 19:24:56 k-worker kubelet[9131]: W0401 19:24:56.395397  9131 cni.go:213] Unable to update
cni config: No networks found in /etc/cni/net.d
Apr 01 19:24:57 k-worker kubelet[9131]: E0401 19:24:57.187390  9131 kubelet.go:2170] Container runtime
network not ready: NetworkReady=false reason:NetworkPluginNotReady
message:docker: network plugin is not ready: cni config uninitialized

/etc/cni/net.d が見つからない、 NetworkPluginNotReady だよ、ということで、えいやで試してみたところ Ready になりました。ここは「えいや」ですので、この状況に陥らないことを祈ります。

  1. (Worker) kubeadm resetを実行(rootで実行)

    command
    kubeadm reset
    iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
    
  2. (Worker)下記のディレクトリ(/etc/cni/net.d/)を作成

    command
    mkdir -p /etc/cni/net.d
    
  3. (Master)同じフォルダ上(/etc/cni/net.d/)にあるファイルをWorkerへコピー(Canalの場合は以下)

    • 10-canal.conflis
    • calico-kubeconfig
  4. 10-canal.conflist は、node情報がベタ書きされているため、Worker node名に変更

      "type": "calico",
      "log_level": "info",
      "datastore_type": "kubernetes",
    -     "nodename": "k-master",
    +     "nodename": "k-worker",
      "ipam": {
    
  5. 再度 Worker側からjoinコマンドを実行

以上です。ここまで読んでくださってありがとうございました。
次は metalkubeの環境構築を目指しまっす。

15
5
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
15
5