tag:crieit.net,2005:https://crieit.net/boards/worklogofcalicothehardway/feed
「Calico the hard wayの作業ログ」の投稿 - Crieit
Crieitで「Calico the hard wayの作業ログ」ボードに投稿された最近の投稿
2019-12-02T01:48:23+09:00
https://crieit.net/boards/worklogofcalicothehardway/feed
tag:crieit.net,2005:PublicArticle/Day4-Follow-up
2019-12-02T01:48:23+09:00
2019-12-02T01:48:23+09:00
https://crieit.net/boards/worklogofcalicothehardway/Day4-Follow-up
Day4: Follow up
<p>だいぶ間が空いてしまったけど、前回言っていたように、<a href="https://crieit.net/boards/worklogofcalicothehardway/Day4-Install-CNI-plugin">Day4</a>の内容の解説を行う。</p>
<p>まず前提としてCalicoはKubernetesのNetwork Pluginなので、Kubernetesと通信する必要がある。そして、KubernetesのAPIとの通信には認証が必要である。ということで、最初にやることは、認証用の鍵を作成して署名すること。</p>
<p>以下のコマンドで認証用の鍵を作成している。</p>
<pre><code class="sh">$ openssl req -newkey rsa:4096 \ # 鍵を4096bitのRSA暗号で作成する
-keyout cni.key \ # 鍵の出力先ファイル名
-nodes \ # 鍵の中身を暗号化しない
-out cni.csr \ # CSRの出力先ファイル名
-subj "/CN=calico-cni" # 証明書のサブジェクトのdistinguish nameを設定する
</code></pre>
<p>これをKubernetesのCA(認証局)に署名してもらう。</p>
<pre><code class="sh">$ sudo openssl x509 -req -in cni.csr \ # CSRが入力であり(--req)、CSRの場所は cni.csrである(--in)
-CA /etc/kubernetes/pki/ca.crt \ # KubernetesのCA証明書の場所
-CAkey /etc/kubernetes/pki/ca.key \ # KubernetesのCA鍵の場所
-CAcreateserial \ # シリアル番号がなければ番号を生成する
-out cni.crt \ # 署名された証明書の出力先ファイル名
-days 365 # 署名された証明書の有効期限
sudo chown ubuntu:ubuntu cni.crt
</code></pre>
<p>これでKubernetesにアクセスするための証明書が作成されたことになる。次に、ここで作成した証明書を使うように設定する。つまり、(Kubernetesをサーバーだと見立てた場合に)クライアント側の設定を行う。</p>
<pre><code class="sh"># KubernetesのAPIサーバーのIPアドレスを取得する
$ APISERVER=$(kubectl config view -o jsonpath='{.clusters[0].cluster.server}')
$ kubectl config set-cluster kubernetes \ # kubeconfigに"kubernetes"という名前でクラスターエントリを設定する
--certificate-authority=/etc/kubernetes/pki/ca.crt \ # CA証明書の位置。クライアント証明書を検証するために必要
--embed-certs=true \ # kubeconfigの中に証明書を埋め込むかどうか
--server=$APISERVER \ # KubernetesのAPIサーバーのIPアドレスの指定
--kubeconfig=cni.kubeconfig # 設定を保存するkubeconfigのファイルの場所
$ kubectl config set-credentials calico-cni \ # kubeconfigに"calico-cni"という名前でユーザーエントリを設定する
--client-certificate=cni.crt \ # CAに署名してもらった証明書の場所
--client-key=cni.key \ # 証明書に対応する鍵
--embed-certs=true \ # kubeconfigの中に証明書を埋め込むかどうか
--kubeconfig=cni.kubeconfig # 設定を保存するkubeconfigのファイルの場所
$ kubectl config set-context default \ # kubeconfigに"default"というコンテキストエントリを設定する
--cluster=kubernetes \ # "default"というコンテキストに対応するクラスターの名前
--user=calico-cni \ # "default"というコンテキストに対応するユーザーの名前
--kubeconfig=cni.kubeconfig # 設定を保存するkubeconfigのファイルの場所
# 設定した"default"コンテキストを指定する。読み込む設定ファイルはcni.kubeconfigとする
$ kubectl config use-context default --kubeconfig=cni.kubeconfig
</code></pre>
<p>これはCalicoが使う設定ファイルなので、Calicoノードに配布しておく必要がある。</p>
<p>ここまで見たように、1つ1つのステップがCalicoがKubernetesのAPIサーバーと通信するために必要な準備作業であることがわかる。</p>
<p>では、ここまで完了したら後はCalicoがKubernetesと協調的に動くようになるかと言うとそうでもなくて、Calicoに限らず、Kubernetesのリソース(DeploymentとかPodとか)を扱うときにはRoleを割り当てなければならない。</p>
<p>というわけで、作成するRoleが以下のようになる</p>
<pre><code class="sh">$ kubectl apply -f - <<EOF
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: calico-cni
rules:
# The CNI plugin needs to get pods, nodes, and namespaces.
- apiGroups: [""]
resources:
- pods
- nodes
- namespaces
verbs:
- get
# The CNI plugin patches pods/status.
- apiGroups: [""]
resources:
- pods/status
verbs:
- patch
# These permissions are required for Calico CNI to perform IPAM allocations.
- apiGroups: ["crd.projectcalico.org"]
resources:
- blockaffinities
- ipamblocks
- ipamhandles
verbs:
- get
- list
- create
- update
- delete
- apiGroups: ["crd.projectcalico.org"]
resources:
- ipamconfigs
- clusterinformations
- ippools
verbs:
- get
- list
EOF
</code></pre>
<p>上について細かい説明は省略するというか、追々わかってくると思うのでここでは一旦"オマジナイ"的なものとしてコピペしておくにとどめておいて良いと思う。強いて言うなら、<code>verbs</code>はHTTPのメソッド的なやつだというぐらいの認識で良いと思う。</p>
<p>あとはCalicoのバイナリをダウンロードして所定の位置に配置するだけなので割愛。Day4のフォローアップはここまでにして、次はDay5をやる。</p>
shige
tag:crieit.net,2005:PublicArticle/Day4-Install-CNI-plugin
2019-11-19T00:33:36+09:00
2019-11-19T00:33:36+09:00
https://crieit.net/boards/worklogofcalicothehardway/Day4-Install-CNI-plugin
Day4: Install CNI plugin
<p>Day3ではIP poolsを設定して、 Calicoのノード(というかPod)に割り当てるIPの設定を行った。今回はようやくCalicoをCNIとしてインストールする。</p>
<p>まず最初に、master node上でCNIが利用するSSL通信のための証明書と鍵を作成する。</p>
<pre><code class="console">$ openssl req -newkey rsa:4096 \
-keyout cni.key \
-nodes \
-out cni.csr \
-subj "/CN=calico-cni"
</code></pre>
<p>次に、Kubernetesが持っているCA(Certification Authority/認証局)を利用して、作成した証明書に署名する。</p>
<pre><code class="console">$ sudo openssl x509 -req -in cni.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial \
-out cni.crt \
-days 365
$ sudo chown user:user cni.crt
</code></pre>
<p>次に、CNI Plugin(つまりCalico)がKubernetesにアクセスするために使うkubeconfigファイルを作成する。</p>
<pre><code class="console">$ APISERVER=$(kubectl config view -o jsonpath='{.clusters[0].cluster.server}')
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=$APISERVER \
--kubeconfig=cni.kubeconfig
kubectl config set-credentials calico-cni \
--client-certificate=cni.crt \
--client-key=cni.key \
--embed-certs=true \
--kubeconfig=cni.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=calico-cni \
--kubeconfig=cni.kubeconfig
kubectl config use-context default --kubeconfig=cni.kubeconfig
</code></pre>
<p>ドキュメントによると、ここで作った<code>cni.kubeconfig</code>は各ノードにコピーしておいたほうが良いらしい。とはいえ、どこにコピーすれば良いのかわからなかったので、とりあえず各ノードの同じユーザーのホームディレクトリに置いといた。</p>
<p>次にCalicoのノードがKubernetesのリソースにアクセスするための権限を持ったRoleを作る。</p>
<pre><code class="console">kubectl apply -f - <<EOF
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: calico-cni
rules:
# The CNI plugin needs to get pods, nodes, and namespaces.
- apiGroups: [""]
resources:
- pods
- nodes
- namespaces
verbs:
- get
# The CNI plugin patches pods/status.
- apiGroups: [""]
resources:
- pods/status
verbs:
- patch
# These permissions are required for Calico CNI to perform IPAM allocations.
- apiGroups: ["crd.projectcalico.org"]
resources:
- blockaffinities
- ipamblocks
- ipamhandles
verbs:
- get
- list
- create
- update
- delete
- apiGroups: ["crd.projectcalico.org"]
resources:
- ipamconfigs
- clusterinformations
- ippools
verbs:
- get
- list
EOF
</code></pre>
<p>で、作ったRoleをCalicoのアカウント<code>calico-cni</code>にバインドする。</p>
<pre><code class="console">$ kubectl create clusterrolebinding calico-cni --clusterrole=calico-cni --user=calico-cni
</code></pre>
<p>ここまで来てようやくCalicoがインストールできる準備が整った。以下のコマンドを各ノードで、かつ<code>root</code>ユーザーで行う必要がある。</p>
<p>...なんか特にこれといった説明もなくザザッと設定ファイルを作ってコマンドを叩いただけなので、次回はここでやっていることを1つずつ解説してみたいと思う。Calicoとは直接関係ないけど、KubernetesとCalicoを理解する上では役に立つと思うので。</p>
<p>今日はここまで。</p>
shige
tag:crieit.net,2005:PublicArticle/Day3-Configure-IP-pools
2019-11-15T01:24:05+09:00
2019-11-15T01:25:07+09:00
https://crieit.net/boards/worklogofcalicothehardway/Day3-Configure-IP-pools
Day3: Configure IP pools
<p>3日目は<a target="_blank" rel="nofollow noopener" href="https://docs.projectcalico.org/v3.10/getting-started/kubernetes/hardway/configure-ip-pools">Configure IP pools</a>から。前回はcalicoctlをインストールして簡単な動作確認をしただけ。</p>
<p>Calicoには<em>workload</em>というリソースがあって、VMだったりコンテナだったり、Kubernetesの世界でいうとPodの形で配置される。それが何をするのかというと、仮想ネットワークのための仕事をする。Workloadには<em>workload endpoint</em>というものがあって、それがCalicoのネットワークの世界とCalicoの外側のネットワークをつなぐためのインターフェースとなる。</p>
<p>で、ここでタイトルにある"IP pools"の話になるんだけど、"IP pools"というのは、Calicoがworkload endpointsのために利用するIPアドレスの範囲のこと。</p>
<p>じゃあそのIPアドレスの範囲はどうやって決めるのかと言うと、Kubernetesクラスタを立ち上げるときに<code>--pod-netwrok-cidr</code>を指定したと思うんだけど、その指定した範囲のサブセットを用いる。</p>
<p>というわけで、以上を踏まえてIP poolsの設定をしてみる。以下のようにする。</p>
<pre><code class="console">$ cat > pool1.yaml <<EOF
> apiVersion: projectcalico.org/v3
> kind: IPPool
> metadata:
> name: pool1
> spec:
> cidr: 192.168.0.0/18
> ipipMode: Never
> natOutgoing: true
> disabled: false
> nodeSelector: all()
> EOF
</code></pre>
<p>ドキュメントでは触れてないけど、設定ファイルの内容がKubernetesっぽいのはDatastoreがKubernetesだからかな?etcdだとまた違う(とはいえ、これをjson形式にするとかそんな感じ?)なんだろうと思う。</p>
<p>では内容の解説。<code>apiVersion</code>や<code>kind</code>はKubernetesでさんざん見ていると思うので割愛。<code>spec</code>以下だけに絞って説明する。</p>
<pre><code>cidr: 192.168.0.0/18
</code></pre>
<p>これは見ての通り、CalicoのIP poolが利用する範囲をCIDRで指定している。KubernetesのPodには<code>192.168.0.0/16</code>を指定したので、</p>
<pre><code># https://devops.stackexchange.com/a/8486より
kubectl cluster-info dump | grep -m 1 cluster-cidr
</code></pre>
<p><code>192.168.0.0/16</code>がどういう意味かというと、ネットワーク部(fixed prefix)が<code>192.168.0.0</code>で、ネットマスクが16bitですよっていう意味。めっちゃ雑にいうと、32bitのうち、16bitはマスク部なので、残りの16bitを利用できますよっていうことになる。なので、ここでは、2^16-2(networkアドレスとbrodcastアドレスを除く) = 65536 - 2 = 65534個のIPアドレスを割り当てますよっていう設定をしている。</p>
<p>で、Calicoはこの割り当てられている範囲でIPアドレスを利用するので、サブセットとして<code>/16</code>より狭い範囲でCIDRを指定しなければならない。ということで、ここでは<code>192.168.0.0/18</code>として、これまた雑にいうと32bitのうち18bitがマスク部なので、残りの14bit、つまり2^14-2 = 16384 - 2 = 16382個のIPアドレス を使いますよっていう宣言をしていることになる。</p>
<p>次はこれ↓</p>
<pre><code>ipipMode: Never
</code></pre>
<p><code>ipipMode</code>というのは(IP in IP)[https://en.wikipedia.org/wiki/IP_in_IP]を利用するかどうかを指定する項目。IP in IPに関してはリンク先を参照してほしいのだけど、触りだけをいうと、IPパケットを別のIPパケットでカプセル化する。そうすることでVPN通信なんかを可能にしたりする。今回はそういったことは必要ないので<code>Never</code>を指定する。</p>
<pre><code>natOutgoing: true
</code></pre>
<p>これを有効(<code>true</code>)にすると、Calicoのコンテナから通信先にパケットが送られるときに、パケットがインターネット側から隠蔽されるようになる。つまりCalicoがNATしているように(ようにっていうか、まさにそうなんだろうけど)振る舞うので、本来の通信元のポート番号などがインターネット側に対して隠されるようになる。</p>
<pre><code>disabled: false
</code></pre>
<p>これが<code>true</code>だと、CalickのIPAM(<a target="_blank" rel="nofollow noopener" href="https://en.wikipedia.org/wiki/IP_address_management">IP Address management</a>)が割り当てられたIP poolsからIPアドレスを割り当てなくなる。つまり、指定したCIDRの範囲のIP poolsのIPアドレスをもつpodが作られなくなる。podはつくられなくなるんだけど、引き続き指定範囲のCIDRはCalicoのネットワークの一部として認識されている。</p>
<pre><code>nodeSelector: all()
</code></pre>
<p>CalicoのIPAMが指定されたIP poolsからアドレスを割り当てるときにノードを選択するときの振る舞いを指定する。<code>all()</code>だとIP poolで指定した範囲内のノードにすべて割り当てる。<br />
ちなみにここまで説明は全て<a target="_blank" rel="nofollow noopener" href="https://docs.projectcalico.org/v3.7/reference/calicoctl/resources/ippool">ドキュメント</a>に記載されているので詳細はそちらで。</p>
<p>つぎに2つ目のIP poolsを設定する。</p>
<pre><code class="console">$ cat > pool2.yaml <<EOF
> apiVersion: projectcalico.org/v3
> kind: IPPool
> metadata:
> name: pool2
> spec:
> cidr: 192.168.192.0/19
> ipipMode: Never
> natOutgoing: true
> disabled: true
> nodeSelector: all()
> EOF`
</code></pre>
<p>で、最後にこれらを適用する。</p>
<pre><code class="console">$ calicoctl create -f pool1.yaml
Successfully created 1 'IPPool' resource(s)
$ calicoctl create -f pool2.yaml
Successfully created 1 'IPPool' resource(s)
$ calicoctl get ippools -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR
pool1 192.168.0.0/18 true Never Never false all()
pool2 192.168.192.0/19 true Never Never true all()
</code></pre>
<p>こんな感じ。今日はここまで。</p>
shige
tag:crieit.net,2005:PublicArticle/Days2-The-Calico-datastore
2019-11-14T23:56:19+09:00
2019-11-14T23:56:19+09:00
https://crieit.net/boards/worklogofcalicothehardway/Days2-The-Calico-datastore
Days2: The Calico datastore
<p>今日は<a target="_blank" rel="nofollow noopener" href="https://docs.projectcalico.org/v3.10/getting-started/kubernetes/hardway/the-calico-datastore">The Calico datastore</a>から。前回はKubernetesのクラスタを作った。</p>
<p>これからCalicoをインストールする作業を進めていくわけだけど、そのためにはCalicoが保持するデータの場所を設定する必要がある。設定場所の選択肢はKubernetesとetcdの2つ。どちらにも長所と短所がある。ざっくり言うとこんな感じ。</p>
<ul>
<li>Kubernetesをデータストアとして使う: すでにあるKubernetesクラスタを利用するので、追加でなにかを用意する必要がない。また、Kubernetesがもっている様々な機構を利用することが出来る。</li>
<li>etcdををデータストアとして使う: Kubernetesに依存しない環境(例えばOpenStackなど)でCalicoを利用することができる。また、Kubernetesを意識する必要がないので、独自にスケールさせることが出来る。</li>
</ul>
<p>Calico the hard wayではKubernetesをデータストアとして利用する。で、じゃあKubernetesをデータストアとして利用するならどうなるかというと、KubernetesのCustom resourceとしてCalicoのリソースが管理される。全部がCustome resourceというわけではない。例えば、<a target="_blank" rel="nofollow noopener" href="https://docs.projectcalico.org/v3.10/reference/resources/workloadendpoint">workload endpoints</a>なんかはPodとして管理される。兎にも角にも、Custome resourceとして管理するためにはリソース定義が必要。ということで、以下の手順でリソース定義を適用する。</p>
<pre><code class="console">$ wget 'https://docs.projectcalico.org/v3.10/manifests/crds.yaml'
...
2019-11-14 01:01:21 (3.92 MB/s) - ‘crds.yaml’ saved [4077/4077]
$ kubectl apply -f ./crds.yaml
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
</code></pre>
<p>次にCalicoの操作を用意にするために<code>calicoctl</code>をインストールする。</p>
<pre><code class="console">$ wget https://github.com/projectcalico/calicoctl/releases/download/v3.8.0/calicoctl
$ sudo mv calicoctl /usr/local/bin/
$ chmod +x calicoctl
$ echo 'export KUBECONFIG=${HOME}/.kube/config' >> ~/.bashrc
$ echo 'export DATASTORE_TYPE=kubernetes' >> ~/.bashrc
</code></pre>
<p>軽く動作確認をする。</p>
<pre><code class="console">$ calicoctl get nodes
NAME
calicothehardway-001
calicothehardway-002
calicothehardway-003
calicothehardway-004
calicothehardway-005
# ↑と同じような出力になっているかを確認 -> OK
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
calicothehardway-001 NotReady master 24h v1.16.2
calicothehardway-002 NotReady <none> 24h v1.16.2
calicothehardway-003 NotReady <none> 23h v1.16.2
calicothehardway-004 NotReady <none> 23h v1.16.2
calicothehardway-005 NotReady <none> 23h v1.16.2
# これはからの出力になるのが期待通り。
$ calicoctl get ippools
NAME CIDR SELECTOR
</code></pre>
<p>今日はここまで。</p>
shige
tag:crieit.net,2005:PublicArticle/Day1-Standing-up-Kubernetes
2019-11-13T01:25:48+09:00
2020-03-31T13:37:14+09:00
https://crieit.net/boards/worklogofcalicothehardway/Day1-Standing-up-Kubernetes
Day1: Standing up Kubernetes
<p>初日は<a target="_blank" rel="nofollow noopener" href="https://docs.projectcalico.org/v3.10/getting-started/kubernetes/hardway/standing-up-kubernetes">Standing up Kubernetes</a>から。</p>
<p>マシンが5台必要らしいので、パパっと用意する。ドキュメントではUbuntu 18.04 LTSが指定されているが、諸事情により、CentOS7.7を使う。</p>
<p>まず必要なソフトウェアとして、dockerとkubeadmをインストールする必要がある。手順は以下のリンクを参照すれば良い。</p>
<ul>
<li>docker: <a target="_blank" rel="nofollow noopener" href="https://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker">https://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker</a>
<ul>
<li>もしかしたらdocker公式の手順でやりたくなるかもしれないが、そうするとこのあとインストールするKubernetesがサポートしていないバージョンがインストールされてしまうかもしれないので、ちゃんとKubernetesが示すインストールに従ったほうが良い。</li>
</ul></li>
<li>kubeadm: <a target="_blank" rel="nofollow noopener" href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/">https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/</a></li>
</ul>
<p>各ホストへのインストールが終わったら、適用な1台でKubernetesの初期設定を行う。</p>
<pre><code class="console">$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16
[init] Using Kubernetes version: v1.16.2
[preflight] Running pre-flight checks
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=...`
To see the stack trace of this error execute with --v=5 or higher
</code></pre>
<p>preflight checkでつまずく。</p>
<blockquote>
<p>running with swap on is not supported. Please disable swap</p>
</blockquote>
<p>とのことなので、素直にswapをoffにする。</p>
<pre><code>$ sudo /sbin/swapoff --all
</code></pre>
<p>そしてもう1度初期設定を実行する。</p>
<pre><code class="console">$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16
[init] Using Kubernetes version: v1.16.2
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[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'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Activating the kubelet service
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [calicothehardway-001 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [1.2.3.4 127.0.0.1]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [calicothehardway-001 localhost] and IPs [1.2.3.4 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [calicothehardway localhost] and IPs [1.2.3.4 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 13.003046 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.16" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node calicothehardway-001 as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node calicothehardway-001 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: 9q8nf1.********************
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 1.2.3.4:6443 --token 9q8nf1.******************** \
--discovery-token-ca-cert-hash sha256:*******************************************************
</code></pre>
<p>注: ログ出力の一部記述を編集している</p>
<p>どうやらうまくいったようだ。引き続き、ログ出力に記述されている指示に従ってKubernetes clusterを起動させる準備をする。</p>
<pre><code class="console">$ mkdir -p $HOME/.kube
$ sudo cp -iv /etc/kubernetes/admin.conf $HOME/.kube/config
‘/etc/kubernetes/admin.conf’ -> ‘/home/user/.kube/config’
$ sudo chown -v $(id -u):$(id -g) $HOME/.kube/config
changed ownership of ‘/home/user/.kube/config’ from root:root to 11000:11000
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
calicothehardway-001 NotReady master 113s v1.16.2 1.2.3.4 <none> CentOS Linux 7 (Core) 3.10.0-1062.1.2.el7.x86_64 docker://18.6.2
</code></pre>
<p>Statusが<code>NotReady</code>となっているが、これにはちゃんと理由があって、<code>kubectl get node</code>をやってみると、以下の出力内容によって説明されている。</p>
<pre><code class="console">...
Ready False Wed, 13 Nov 2019 01:10:00 +0900 Wed, 13 Nov 2019 01:01:56 +0900 KubeletNotReady runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
...
</code></pre>
<p>要はNetwork pluginを入れてないために<code>NotReady</code>ということで、まぁそうだよねっていう感じ。なので、このまま作業を継続する。残りの作業はSlaveとなるノードでswapをoffにしてクラスターに追加していけば良い。</p>
<pre><code class="console"># 各Slaveノードで以下を実行する。
$ sudo /sbin/swapoff --all
$ sudo kubeadm join ... # 残りの引数はkubeadmの画面に出てきたものをコピペ
</code></pre>
<p>最後にもう1度<code>kubectl get node</code>をやって追加したSlaveノードが全部表示されているかを確認する。</p>
<pre><code class="console">$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
calicothehardway-001 NotReady master 15m v1.16.2
calicothehardway-002 NotReady <none> 10m v1.16.2
calicothehardway-003 NotReady <none> 2m41s v1.16.2
calicothehardway-004 NotReady <none> 50s v1.16.2
calicothehardway-005 NotReady <none> 32s v1.16.2
</code></pre>
<p>問題なさそう。Day1はKubernetes準備ということなので、ここまで。</p>
shige