今日も爽快な打鍵音を

ITエンジニアのブログ

エンジニア向けWindowsのターミナルとシェル環境

エンジニア向けWindowsのターミナルとShell環境

エンジニアは何かとターミナルやシェルを使うことが多い。
MacLinuxをクライアントOSとして好む人も多いが、会社の方針やプロジェクトの要件等でWindowsを使わないといけないケースも多い。
文句を言っても仕方ないので、Windowsで快適に使える環境を調べた。

やりたいこと

Shellを使いたい

エンジニアはとにかくShellを使う場面が多く、かつ好んで使う。
とはいってもShellと言ってもWindowsコマンドプロンプトを指すことはない。
Linuxで使われているbashzsh等のshellだ。
残念ながらMacには標準で入っているが、Windowsには入っていない。 Shellには、find, grep, xargs, awk 等々便利なコマンドがある。
サーバーサイドと同じ操作がクライアントOSでできることは価値が高い。

使いやすいターミナルがほしい

仮にShellが使えたとしても、使いづらい状態では不満だ。
私はMacのiTerm2を愛用している。
スタイルを変更したり、標準出力から任意の文字列検索が出来たり、多くのユーザビリティ向上の機能が備わっている。
WindowsコマンドプロンプトPowerShellは標準ではなにもできない。拡張ソフトを入れることで多少マシになるが、目指すゴールには程遠い。
やはりWindowsにも使いやすいターミナルソフトが必要だ。

理想

つまりWindowsで自由に使えるbashユーザビリティに優れるターミナルが欲しいということになる。
要件をまとめると以下だ。

  • Windowsで不自由ないshellが使える。
    • bashが動く
    • package管理ができる
    • Windowsバイナリとして動作する(VMはなし)
  • 便利なターミナル
    • 標準出力検索ができる
    • コピペが楽
    • テーマ等のpluginがある
    • 画面分割・タブが使える
    • OS環境を問わないクロスプラットフォーム

Shellの比較

結論から書くとMSYS2が良い。
パッケージマネージャとしてpacmanが利用可能なことと、Windowsとの親和性が良く、扱いやすい。

Windows Subsystem for Linux

通称WSLはWindows10に組み込まれたUbuntuだ。
WSL1は少々野心的な実装をしており、Linuxカーネルを利用せずにWindows上で動作する。 一部Linuxカーネルを必要とするネットワーク系コマンド等が動作しない。
大抵の操作は可能だがサブシステムとしてubuntuがあるということを意識しないといけないのがデメリットと感じる。 WSL2ではどちらかというとLinuxカーネルを組み込み、Hyper-V使ったVMに近い構成をとっている。
このためコンテナ技術等が利用可能になる。

Git for Windows

Git for Windows
これはWindows向けのGitクライアントソフト。 gitはCUIツールであり、Windowsで動作するbashが同梱された状態で配布される。 標準状態でminttyによるターミナルが操作可能で、使い勝手は良い。
ただ、git以外のパッケージ管理ができずそのままでの利用は難しい。

MSYS2

MSYS2
Git for Windowsからgitを取り払い、パッケージマネージャとしてpacmanを導入したもの。 シンプルな構成でかつpacman経由でパッケージ導入が可能なため、使いやすい。
ArchLinuxが好みの人には非常に大きなメリットとなるだろう。

同様なものにcygwinがあるが、独自のライブラリある等で少々Windowsとの分離性が大きく、WLS同様少々サブシステムとして意識した構成となる。

ターミナルの比較

mintty

mintty
MSYS2やGit for Windowsで採用されている。 文字列の拡大機能や右クリックでのペースト機能、文字色のテーマ等が備わっている。 使いやすいが、タブや画面分割機能はなく少々物足りない。

cmder

cmder
名の知れたWindows向けターミナルソフト。 とにかく設定が豊富で細かいところまで調整可能。 Github上の開発も盛んで今後も安心して使えそう。 mini版とfull版が提供されている。 標準でgit for windowsPowerShellをサポートしており、安定した動作が期待できる。

Hyper

Hyper
最近聞くようになったのがこのHyperというターミナル。 特徴はレンダリングWebGLを使っており、Electron等のWeb系の技術で構成されている。このため、クロスプラットフォームで動作しMac, Linux, Windowsで利用可能。 またPluginやテーマも豊富だ。 すでにVersionは3で、githubのStar数も多く、OSSLicenseはMITのため、業務でも安心して使える。 MacユーザでHyperを使う人も多く、これがWindowsで使えるというのは非常にメリットだろう。

まとめ

Windowsで使えるShellとターミナルを比較した。
ShellはWindowsとの親和性とパッケージ管理が可能なMSYS2を使うことにした。
ターミナルはクロスプラットフォームでかつ機能も豊富なHyperを使うことにした。

kubesprayでkubernetesクラスタを構築

kubesprayとは

ansibleベースでkubernetesを構築するツール。ProductionReady環境を構築できるということで、使ってみる。
以前kubeadmつかったが、細かいところまでいじれないので、ansibleのフルスクラッチ構築が可能なkubesprayに移行したいというのがモチベ。

環境準備

ホスト OS 目的
kubespray Client CentOS7 kubespray(ansible) 実行用クライアント
k8s-master1 CentOS7 k8sのマスターノード
k8s-master2 CentOS7 k8sのマスターノード
k8s-master3 CentOS7 k8sのマスターノード

kubespray Client

Kubesprayを実行するホスト。ansible等が動作すれば良いため、クライアントPCで実行しても良いが、環境差異があると動かなかったりするので、手順をまとめておく。 kubespray用実行用のDockerコンテナとかあれば便利そう。

必要パッケージのインストール

sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
yum install -y python36u python36u-pip python36u-devel ansible git gcc python-netaddr libffi-devel openssl-devel
pip3.6 install pip --upgrade
pip install jinja2

kubespray

git clone  https://github.com/kubernetes-incubator/kubespray.git
cd kubespray/
pip install -r requirements.txt
 cp -r inventory/ my_inventory

kubesprayで構築するノード情報を設定(IPとかは自分の環境に合わせて) vi my_inventory/sample/inventory.ini

[all]
k8s-master1 ansible_host=192.168.0.11
k8s-master2 ansible_host=192.168.0.12
k8s-master3 ansible_host=192.168.0.13


[kube-master]
k8s-master1
k8s-master2
k8s-master3

[etcd]
k8s-master1
k8s-master2
k8s-master3

[kube-node]
k8s-master1
k8s-master2
k8s-master3

[k8s-cluster:children]
kube-master
kube-node


[all:vars]
ansible_ssh_port=22
ansible_ssh_user=root
ansible_ssh_pass=<Password>
ansible_sudo_pass=<Password>

k8s-masterノードの下処理

  • firewalld の無効
  • swapの無効
    • ansibleが無効にしてくれるっぽい
  • SElinuxの無効
    • ansibleが無効にしてくれるっぽい(permissive)

構築実行

[root@localhost kubespray]# ansible-playbook -i my_inventory/inventory.ini cluster.yml -v

...
...
PLAY RECAP ******************************************************************************************************************
k8s-master1                : ok=425  changed=69   unreachable=0    failed=0
k8s-master2                : ok=350  changed=54   unreachable=0    failed=0
k8s-master3                : ok=352  changed=55   unreachable=0    failed=0
localhost                  : ok=1    changed=0    unreachable=0    failed=0

Sunday 09 June 2019  06:26:08 -0400 (0:00:00.072)       0:05:58.662 ***********
===============================================================================
kubernetes/master : kubeadm | Init other uninitialized masters ------------------------------------------------------ 23.64s
kubernetes/master : kubeadm | Initialize first master --------------------------------------------------------------- 21.12s
download : container_download | download images for kubeadm config images ------------------------------------------- 10.61s
etcd : reload etcd -------------------------------------------------------------------------------------------------- 10.57s
etcd : wait for etcd up ---------------------------------------------------------------------------------------------- 9.25s
kubernetes-apps/ansible : Kubernetes Apps | Start Resources ---------------------------------------------------------- 6.26s
kubernetes/master : kubeadm | write out kubeadm certs ---------------------------------------------------------------- 5.53s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 3.75s
kubernetes-apps/ansible : Kubernetes Apps | Lay Down CoreDNS Template ------------------------------------------------ 3.52s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 3.52s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 3.50s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 3.43s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 3.37s
network_plugin/calico : Calico | Create calico manifests ------------------------------------------------------------- 2.84s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 2.81s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 2.74s
download : container_download | Download containers if pull is required or told to always pull (all nodes) ----------- 2.67s
policy_controller/calico : Start of Calico kube controllers ---------------------------------------------------------- 2.32s
kubernetes/node : Persist ip_vs modules ------------------------------------------------------------------------------ 2.19s
policy_controller/calico : Create calico-kube-controllers manifests -------------------------------------------------- 2.00s

躓きポイント

以下のようなエラーが出たが、原因はipv6も含めた登録するDNSが多すぎたことが原因。

Too many nameservers. You can relax this check by set docker_dns_servers_strict=false in all.yml and we will only use the first 3

roles/container-engine/docker/tasks/set_facts_dns.yml の 56 行目 のlengthを 3⇒5にして対処した。

 56   when: docker_dns_servers|length > 5 and docker_dns_servers_strict|bool

Kuberentesクラスタ 1.10 をkubeadmで構築

Kubernetes 1.10 の新機能

KubernetesはDockerのオーケストレーションツールとして使われており、Dockerコンテナの作成から、コンテナ監視管理、レプリケーション機能など多くの機能を提供している。3/26に1.10がリリースされ、新たにStorage機能やDNS機能が強化された。

Storage関連

Container Storage Interface(CSI)がBeta版に移行したらしく、CSIは新しいVolumeプラグインということ。またPersistentVolumeの更新もあり、Podで使用されているPersistentVolumeとPersistemtClaimの削除を防止する。これにより正しい順序でストレージが破棄されるようになるとのこと。

ネットワーク

CoreDNSをDNSプロバイダとして使用可能に、ただしBeta版。CoreDNSはバイナリで動作し、Configfileを記述するだけで簡単に機能する。

Kubernetesのサポートについて

1.10.x のSupportは Decenmber 2018まで。 各バージョンともに10か月間のサポートがある。1.8.x は2018/6月にサポートが終了する。

kubeadmによる Kubernetesクラスタの構築

Kubernetesをスクラッチで,1から構築する手順は公式にあるが、クラスタ間の通信のTLS対応や各コンポーネントの各種設定など、初心者にはそこそこ厳しい。Kuberetes公式Tutorialもscratchは難しいからやめとけと言わんばかりにMinikubeやkubeadmを勧めている。まずはkubeadmによる自動構築を試してみる。 今回の手順はKubernetes公式の手順を参考に躓いたポイントをまとめる。

Using kubeadm to Create a Cluster

VMの作成

多くのOSで導入可能。今回はCentOSを選択。

kubeadm Support OS

導入環境

# 推奨
OS CentOS7 CentOS or Ubuntu
CPU 4Core 2Core以上
メモリ 4GB 2GB以上

kubeadmのインストール

前提事項

Installing kubeadm

各設定をユニークに
  • Unique hostname, MAC address, and product_uuid for every node.
    • VMでKuberentesクラスタを構築するときは注意
      MAC addressの確認 ip link or ifconfig -a
      product_uuidの確認 sudo cat /sys/class/dmi/id/product_uuid
ホスト名、IPアドレスを固定化
  • ホスト名設定: hostnamectl set-hostname k8s-master
  • IP固定化: vi /etc/sysconfig/network-scripts/ifcfg-ens* 等で
SELinuxを無効
# vi /etc/selinux/config
...
SELINUX=disabled
...
Firewalldを無効

Kubernetesは多くのポートを使うので、ひとまず無効に

systemctl stop firewalld
systemctl disable firewalld
OS swapを無効
  • Swap disabled. You MUST disable swap in order for the kubelet to work properly
    • OS設定のswapが有効な場合`kubelet'の動作に影響があるため無効に

swapの無効化(CentOS7)

/etc/fstabを編集 ※ 修正ミスするとOSが立ち上がらくなることがあるので注意

...
...
/dev/mapper/cl-swap     swap                    swap    defaults        0 0
kubernetesリポジトリを追加

kubernetes用のリポジトリを追加し、kubelet', 'kubeadm', 'kubectlをインストールする。

cat <<EOF > /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
EOF

yum repolistで追加を確認。

[root@k8s-master ~]# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.tsukuba.wide.ad.jp
 * extras: ftp.tsukuba.wide.ad.jp
 * updates: ftp.tsukuba.wide.ad.jp
repo id                                                repo name                                               status
base/7/x86_64                                          CentOS-7 - Base                                         9,591
extras/7/x86_64                                        CentOS-7 - Extras                                         448
kubernetes/x86_64                                      Kubernetes                                                202
updates/7/x86_64                                       CentOS-7 - Updates                                      2,416
repolist: 12,657

kubelet kubeadm kubectlをインストールし、サービス登録。

yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet
ルーティング設定

RHEL系だと標準ではKubernetesの仮想ネットワークからルーティングされないようなので、有効にする。

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

kubeletでは同じcgoup driverを使う必要があるため、設定内容を確認する

[root@k8s-master ~]# docker info | grep -i cgroup
  WARNING: You're not using the default seccomp profile
Cgroup Driver: systemd

[root@k8s-master ~]# cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf | grep -i cgroup-driver
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=systemd"

今回はどちらもsystemdのため問題がないが、もし異なる場合は下記を実行

sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

systemctl daemon-reload
systemctl restart kubelet
kubeadm によるKuberetesの構築

kubeadmを使う準備が整った。kubeadmでkubernetesを構築する。 kubeadm init を実行するだけで、クラスタが構築されるが、さまざまなオプションが用意されている。

kubeadm init [FLAG]

FLAG 用途
--apiserver-advertise-address string k8sAPIサーバのlisten IPアドレス. stringにipアドレスを記述
--apiserver-bind-port int32 APIサーバのポートを指定。デフォルトは6443
--cert-dir string k8s用の証明書保存ディレクトリ デフォルトは/etc/kubernetes/pki
--config string kubeadm用のConfigファイルを指定
--ignore-preflight-errors strings Warning, Errorを無視してインストール
--kubernetes-version string 任意のバージョンのKubernetesをインストール デフォルトはstable-1.10
--pod-network-cidr string podのサブネットを変更。stringに任意のサブネットを記述
--service-cidr string サービスのVIPのサブネットを変更 デフォルトは10.96.0.0/12
--service-dns-domain string サービスのドメインを変更 デフォルトはcluster.local

その他オプションに CoreDNSの有効設定がある。

Auditing=true|false (ALPHA - default=false)
CoreDNS=true|false (BETA - default=false)
DynamicKubeletConfig=true|false (ALPHA - default=false)
SelfHosting=true|false (ALPHA - default=false)
StoreCertsInSecrets=true|false (ALPHA - default=false)

この中で--apiserver-advertise-address, --kubernetes-version, --service-cidr, --pod-network-cidrあたりは環境に応じて変更したほうがよさそう。Service-cidrに関してはk8s内部のIP帯と基幹ネットワークのPrivateIPが重複することもあり、k8sの対外通信自体はNAT処理が入るが、使用されるIP帯には注意が必要だろう。

kubeadmによる構築を実行
kubeadm init --apiserver-advertise-address '192.168.0.221' --kubernetes-version 1.10.2 --service-cidr '10.0.0.0/24' --pod-network-cidr '172.16.0.0/24'

kubeadm initでエラーがでたらkubeadm resetを実行し、再度kubeadm initを実行。

[root@k8s-master ~]# kubeadm init --apiserver-advertise-address '192.168.0.221' --kubernetes-version 1.10.2 --service-cidr '10.0.0.0/24' --pod-network-cidr '172.16.0.0/24'
[init] Using Kubernetes version: v1.10.2
[init] Using Authorization modes: [Node RBAC]
[preflight] Running pre-flight checks.
        [WARNING Hostname]: hostname "k8s-master" could not be reached
        [WARNING Hostname]: hostname "k8s-master" lookup k8s-master on 192.168.0.1:53: no such host
        [WARNING FileExisting-crictl]: crictl not found in system path
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
[preflight] Starting the kubelet service
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [k8s-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.0.0.1 192.168.0.221]
[certificates] Generated apiserver-kubelet-client certificate and key.
[certificates] Generated etcd/ca certificate and key.
[certificates] Generated etcd/server certificate and key.
[certificates] etcd/server serving cert is signed for DNS names [localhost] and IPs [127.0.0.1]
[certificates] Generated etcd/peer certificate and key.
[certificates] etcd/peer serving cert is signed for DNS names [k8s-master] and IPs [192.168.0.221]
[certificates] Generated etcd/healthcheck-client certificate and key.
[certificates] Generated apiserver-etcd-client certificate and key.
[certificates] Generated sa key and public key.
[certificates] Generated front-proxy-ca certificate and key.
[certificates] Generated front-proxy-client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"
[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests".
[init] This might take a minute or longer if the control plane images have to be pulled.
[apiclient] All control plane components are healthy after 18.501018 seconds
[uploadconfig]?Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[markmaster] Will mark node k8s-master as master by adding a label and a taint
[markmaster] Master k8s-master tainted and labelled with key/value: node-role.kubernetes.io/master=""
[bootstraptoken] Using token: 3ugeo9.90nstqyd48q4esa7
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: kube-dns
[addons] Applied essential addon: kube-proxy

Your Kubernetes master 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/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join 192.168.0.221:6443 --token 3ugeo9.90nstqyd48q4esa7 --discovery-token-ca-cert-hash sha256:43d8fe3e155ab1c2226bd12c5e9e72aacfe178c3a5566b874f1c4b5fc26757a4

Your Kubernetes master has initialized successfully! と表示されていれば完了。 途中にWarningメッセージが出ている。ホスト名解決ができていないのかホスト名関連のエラー。気には留めておく。

[WARNING Hostname]: hostname "k8s-master" could not be reached
[WARNING Hostname]: hostname "k8s-master" lookup k8s-master on 192.168.0.1:53: no such host
[WARNING FileExisting-crictl]: crictl not found in system path

最後の一行のkubeadm join ~~だが、これはクラスタノード(minion node)を組む際に使うもので、kubeadm導入済みの環境でコピペすればクラスタへ参加する。とても簡単。

kubectlによる接続

kubectlでは鍵による接続設定が必要。kubeadmが自動生成してくれているので、これをkubectlが読み取れる位置に変更する。

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

別の環境からkubectlを実行する場合もこのadmin.confをコピーすれば接続が完了する。

Podネットワークの構築(CNI)

k8sコンポーネントの起動確認kubectl get pods --all-namespacesをするとkube-dnsが動作せず、他のコンポーネントもループしている。

[root@k8s-master ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                                 READY     STATUS    RESTARTS   AGE
kube-system   etcd-k8s-master                      1/1       Running   0          4s
kube-system   kube-apiserver-k8s-master            1/1       Running   0          4s
kube-system   kube-controller-manager-k8s-master   1/1       Running   0          4s
kube-system   kube-dns-86f4d74b45-7vqqq            0/3       Pending   0          8m
kube-system   kube-proxy-kzpgb                     1/1       Running   0          8m
kube-system   kube-scheduler-k8s-master            1/1       Running   0          4s

これはk8sのContainer Network Interfaceが動作していないためなので、CNIをインストールを行う。

多くのサードパーティによるCNIが用意されている。

  • Calico
  • Canal
  • Flannel
  • Kube-router
  • Romana
  • Weave Net

今回はflannelを使う。 kubeadmでflannelを使う場合はオプションに--pod-network-cidr=10.244.0.0/16を指定しないと行けないらしい。

変えられそうなので調べたらkube-flannel.ymlの中に記述されており、書き換えれば良い。

wget https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml

65行目 "Network": "10.244.0.0/16",172.16.0.0/24

     63   net-conf.json: |
     64     {
     65       "Network": "10.244.0.0/16",
     66       "Backend": {
     67         "Type": "vxlan"
     68       }
     69     }

flannelをインストール

kubectl apply -f kube-flannel.yml

k8sコンポーネントの起動状況を確認 kubectl get pods --all-namespaces

[root@k8s-master ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                                 READY     STATUS    RESTARTS   AGE
kube-system   etcd-k8s-master                      1/1       Running   0          37s
kube-system   kube-apiserver-k8s-master            1/1       Running   0          37s
kube-system   kube-controller-manager-k8s-master   1/1       Running   0          37s
kube-system   kube-dns-86f4d74b45-7vqqq            3/3       Running   0          31m
kube-system   kube-flannel-ds-fpskt                1/1       Running   0          46s
kube-system   kube-proxy-kzpgb                     1/1       Running   0          31m
kube-system   kube-scheduler-k8s-master            1/1       Running   0          37s

kube-dnsが起動している。よさそう。

Podの作成

試しにPodを作成し、動作検証する。 kubeadmでは標準ではMasterノードではPodがデプロイされない設定になっているので、これを解除

[root@k8s-master ~]# kubectl taint nodes --all node-role.kubernetes.io/master-
node "k8s-master" untainted

k8sはPodとServiceをデプロイするがマニフェストファイルyamlで管理する。 テストとしてnginxをデプロイする。List記法を使い、DeploymentServiceをまとめて書いた。

nginx-test.yaml

apiVersion: v1
kind: List
items:
- apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: nginx
  spec:
    replicas: 2
    template:
      metadata:
        labels:
          run: nginx
      spec:
        containers:
        - name: nginx
          image: nginx:1.13
          ports:
          - containerPort: 80
- apiVersion: v1
  kind: Service
  metadata:
    name: nginx-nodeport
  spec:
    type: NodePort
    ports:
    - port: 80
      protocol: TCP
      targetPort: 80
    selector:
      run: nginx

Pod, Serviceをデプロイ

[root@k8s-master ~]# kubectl create -f nginx-test.yaml
deployment.extensions "nginx" created
service "nginx-nodeport" created

kubectl get allでpodとserviceを確認

[root@k8s-master ~]# kubectl get all
NAME                       READY     STATUS    RESTARTS   AGE
pod/nginx-bbc784cf-qqkbk   1/1       Running   0          1m
pod/nginx-bbc784cf-wm8n4   1/1       Running   0          1m

NAME                     TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
service/kubernetes       ClusterIP   10.0.0.1     <none>        443/TCP        43m
service/nginx-nodeport   NodePort    10.0.0.30    <none>        80:30062/TCP   1m

NAME                    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   2         2         2            2           1m

NAME                             DESIRED   CURRENT   READY     AGE
replicaset.apps/nginx-bbc784cf   2         2         2         1m

よさそう。 kubeadm initで指定したservice CIDR10.0.0.0/24になっている。 ついでにコンテナIPも見てみる。

kubectl describeで Pod,コンテナの状態を確認

[root@k8s-master ~]# kubectl describe pod/nginx-bbc784cf-qqkbk
Name:           nginx-bbc784cf-qqkbk
Namespace:      default
Node:           k8s-master/192.168.0.221
Start Time:     Sat, 28 Apr 2018 13:33:24 -0400
Labels:         pod-template-hash=66734079
                run=nginx
Annotations:    <none>
Status:         Running
IP:             172.16.0.3
Controlled By:  ReplicaSet/nginx-bbc784cf
Containers:
  nginx:
    Container ID:   docker://5be8d67afbfe477c92519e215eeccc1b13163480ce5f072ad95d3c1d2ce6f140
    Image:          nginx:1.13
    Image ID:       docker-pullable://docker.io/nginx@sha256:80e2f223b2a53cfcf3fd491521e5fb9b4004d42dfc391c76011bcdd9565643df
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sat, 28 Apr 2018 13:33:36 -0400
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-rs2wt (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-rs2wt:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-rs2wt
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason                 Age   From                 Message
  ----    ------                 ----  ----                 -------
  Normal  Scheduled              3m    default-scheduler    Successfully assigned nginx-bbc784cf-qqkbk to k8s-master
  Normal  SuccessfulMountVolume  3m    kubelet, k8s-master  MountVolume.SetUp succeeded for volume "default-token-rs2wt"
  Normal  Pulling                3m    kubelet, k8s-master  pulling image "nginx:1.13"
  Normal  Pulled                 2m    kubelet, k8s-master  Successfully pulled image "nginx:1.13"
  Normal  Created                2m    kubelet, k8s-master  Created container
  Normal  Started                2m    kubelet, k8s-master  Started container

こちらもPodのIPが172.16.0.3になっていることを確認。

サービスのバインドポートがservice/nginx-nodeport NodePort 10.0.0.30 <none> 80:30062/TCPのため、クライアント環境からk8s向けに192.168.0.221:30062でアクセス

f:id:mbook-x86:20180429024114p:plain

無事 nginx が表示された。

とりあえずkubeadmを用いてPodが立つところまでできた。

以上。