eyecatch
Tue, Apr 17, 2018

Kubernetes 1.10をスクラッチから全手動で構築

CentOS 7のVMでKubernetes1.10のクラスタをスクラッチから全手動で作った。 参考にしたのは主に以下。 https://nixaid.com/deploying-kubernetes-cluster-from-scratch/ https://kubernetes.io/docs/getting-started-guides/scratch/ https://ulam.io/blog/kubernetes-scratch/ https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/creating-a-linux-master (adsbygoogle = window.adsbygoogle || []).push({}); 構成 マシン: Windows 10 Homeのラップトップの上のVMware PlayerのVM CPU: 2コア メモリ: 4GB NIF: NATのを一つ OS: Oracle Linux 7.4 Minimalインストール IPアドレス: 192.168.171.200、静的割り当て ホスト名: k8s-master (hostsで解決) Kubernetes: バージョン1.10.0 単一ノード 全コンポーネント(kubelet、kube-proxy、kube-apiserver、kube-controller-manager、kube-scheduler、etcd)をsystemdで起動 (i.e. 非コンテナ) コンポーネント間通信とkubectlの通信をTLSで暗号化 コンポーネント間通信とkubectlの通信の認証はx509クライアント証明書 TLS bootstrappingはbootstrap token使用。 etcd 3.1.12 flannel 0.10.0 CoreDNS 1.1.1 kubeletの動作条件にあるので、swapをoffにする。 Oracle Linuxにログインして、/etc/fstabのswapの行を削除して、以下のコマンドを実行。 # swapoff -a SELinuxはちゃんと設定すればKubernetes動かせるはずだけど、面倒なのでとりあえず無効にする。 /etc/selinux/configを編集して、SELINUXをpermissiveにして、以下のコマンドを実行。 # setenforce 0 ファイアウォールもちゃんと設定すればいいんだけど面倒なのでとりあえず無効にする。 # systemctl stop firewalld # systemctl disable firewalld これで準備完了。 クラスタ構築手順 おおむね、k8sコンポーネント間の通信の暗号化に使う鍵と証明書の生成、各コンポーネント用kubeconfigの生成、etcdのデプロイ、k8sコンポーネントのデプロイ、fannelデプロイ、CoreDNSデプロイ、という流れ。 ついでに最後にWeave Scopeをデプロイしてみる。 Bridge netfilterとIP forwardingを設定 まず、Bridge netfilterモジュールをロードする。 # modprobe br_netfilter # cat > /etc/sysconfig/modules/br_netfilter.modules << EOF #!/bin/sh /sbin/modprobe br_netfilter > /dev/null 2>&1 EOF # chmod 755 /etc/sysconfig/modules/br_netfilter.modules Bridge netfilterとIP forwardingを有効化する。 # cat > /etc/sysctl.d/kubernetes.conf << EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # sysctl -p /etc/sysctl.d/kubernetes.conf 設定確認。 # lsmod |grep br_netfilter # sysctl -a | grep -E "net.bridge.bridge-nf-call-|net.ipv4.ip_forward" x509証明書生成 opensslの設定作成 # mkdir -p /etc/kubernetes/pki # cd /etc/kubernetes/pki # K8S_SERVICE_IP=10.0.0.1 # MASTER_IP=192.168.171.200 # cat > openssl.cnf << EOF [ req ] distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_ca ] basicConstraints = critical, CA:TRUE keyUsage = critical, digitalSignature, keyEncipherment, keyCertSign [ v3_req_server ] basicConstraints = CA:FALSE keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ v3_req_client ] basicConstraints = CA:FALSE keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [ v3_req_apiserver ] basicConstraints = CA:FALSE keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names_cluster [ v3_req_etcd ] basicConstraints = CA:FALSE keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alt_names_etcd [ alt_names_cluster ] DNS.1 = kubernetes DNS.2 = kubernetes.default DNS.3 = kubernetes.default.svc DNS.4 = kubernetes.default.svc.cluster.local DNS.5 = k8s-controller IP.1 = ${MASTER_IP} IP.2 = ${K8S_SERVICE_IP} [ alt_names_etcd ] DNS.1 = k8s-controller IP.1 = ${MASTER_IP} EOF Kubernetes CA証明書生成 以降で生成する証明書に署名するための証明書。 # cd /etc/kubernetes/pki # CA_DAYS=5475 # openssl ecparam -name secp521r1 -genkey -noout -out ca.key # chmod 0600 ca.key # openssl req -x509 -new -sha256 -nodes -key ca.key -days $CA_DAYS -out ca.crt -subj "/CN=kubernetes-ca" -extensions v3_ca -config ./openssl.cnf kube-apiserver証明書生成 kube-apiserverのAPIをHTTPSにするためのサーバ証明書。 # cd /etc/kubernetes/pki # APISERVER_DAYS=5475 # openssl ecparam -name secp521r1 -genkey -noout -out kube-apiserver.key # chmod 0600 kube-apiserver.key # openssl req -new -sha256 -key kube-apiserver.key -subj "/CN=kube-apiserver" | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -out kube-apiserver.crt -days $APISERVER_DAYS -extensions v3_req_apiserver -extfile ./openssl.cnf kube-apiserver-kubelet証明書生成 kube-apiserverがkubeletのAPIにアクセスするときのクライアント証明書。 # cd /etc/kubernetes/pki # APISERVER_KUBELET_CLIENT_DAYS=5475 # openssl ecparam -name secp521r1 -genkey -noout -out apiserver-kubelet-client.key # chmod 0600 apiserver-kubelet-client.key # openssl req -new -key apiserver-kubelet-client.key -subj "/CN=kube-apiserver-kubelet-client/O=system:masters" | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -out apiserver-kubelet-client.crt -days $APISERVER_KUBELET_CLIENT_DAYS -extensions v3_req_client -extfile ./openssl.cnf adminクライアント証明書生成 kubectlとkubeletがkube-apiserverのAPIにアクセスするときのクライアント証明書。 本当はkubeletは別に作ったほうがよさそう。 # cd /etc/kubernetes/pki # ADMIN_DAYS=5475 # openssl ecparam -name secp521r1 -genkey -noout -out admin.key # chmod 0600 admin.key # openssl req -new -key admin.key -subj "/CN=kubernetes-admin/O=system:masters" | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -out admin.crt -days $ADMIN_DAYS -extensions v3_req_client -extfile ./openssl.cnf Service Accountキーとkube-controller-managerのクライアント証明書生成 Service Accountトークンにkube-controller-managerが署名するときに使うキーを生成する。 そのキーを使ってkube-controller-managerのクライアント証明書も生成する。 kube-apiserverがトークンの署名を確認するとき(?)に使う公開鍵も生成する。 # cd /etc/kubernetes/pki # CONTROLLER_MANAGER_DAYS=5475 # openssl ecparam -name secp521r1 -genkey -noout -out sa.key # openssl ec -in sa.key -outform PEM -pubout -out sa.pub # chmod 0600 sa.key # openssl req -new -sha256 -key sa.key -subj "/CN=system:kube-controller-manager" | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -out sa.crt -days $CONTROLLER_MANAGER_DAYS -extensions v3_req_client -extfile ./openssl.cnf kube-schedulerクライアント証明書生成 kube-schedulerがkube-apiserverにリクエストするときに使うクライアント証明書。 多分。 # cd /etc/kubernetes/pki # SCHEDULER_DAYS=5475 # openssl ecparam -name secp521r1 -genkey -noout -out kube-scheduler.key # chmod 0600 kube-scheduler.key # openssl req -new -sha256 -key kube-scheduler.key -subj "/CN=system:kube-scheduler" | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -out kube-scheduler.crt -days $SCHEDULER_DAYS -extensions v3_req_client -extfile ./openssl.cnf front proxy CA証明書生成 front proxyのクライアント証明書に署名するのにつかう証明書。 front proxyってなんだ?
eyecatch
Sun, Apr 1, 2018

Skaffoldを触ってみた

Skaffoldを試してみた話。 (adsbygoogle = window.adsbygoogle || []).push({}); Skaffoldとは Googleが開発している、Kubernetesアプリケーションを快適に開発するためのツール。 アプリケーションのソースを監視し、変更が入ると、自動的にコンテナイメージをビルドしてKubernetesクラスタにデプロイしてくれる。 2018/3/16に発表された新しいツールで、触った感じではまだこれからといった感じだった。 Goで書かれていて、Linux、OS X、Windows用のバイナリが提供されている。 似たツールにはMicrosoftのDraftがある。 また、Gitのコミットを自動デプロイしてくれるものに、Gitkube、Jenkins X (エックス)がある。 Windows版を試す 自PCがWindowsなのでWindows版を試す。 会社で使ってるのもWindowsだし。 Skaffoldを使うには、Skaffoldの実行バイナリ、Kubernetesクラスタ、そのクラスタをコンテクストに設定したkubectl、Dockerが必要。 まずWindows版Skaffoldをインストールする。 GitHubのリリースページからWindowsバイナリをダウンロードして、skaffold.exeにリネームしてPATHの通ったところに置くだけ。 Skaffoldのバージョンは0.3.0。 Kubernetesクラスタは、Windows 10 Home上にminikube 0.22.2で作ったKubernetes 1.7.0のクラスタ。 minikubeは以前インストールしたものを使う。 minikubeを起動。 > minikube start --kubernetes-version v1.7.0 kubectlもminikubeと一緒にインストール済み。 Dockerについては、デーモンはminikube上のを使えばいいとして、クライアント(Docker Client)はskaffoldコマンドから実行するのでWindows上にないとだめはなず。 WindowsでDockerと言えば今ならDocker for Windowsだけど、これはWindows 10 Proじゃないと使えなかったはずなので、Docker Toolboxでクライアントをいれた。 このクライアントはデフォルトではローカルのデーモンを見てるので、minikubeのデーモンを見させる。 そのための設定はminikubeのコマンドで分かるようになっている。 > minikube docker-env SET DOCKER_TLS_VERIFY=1 SET DOCKER_HOST=tcp://192.168.99.100:2376 SET DOCKER_CERT_PATH=C:\Users\kaitoy\.minikube\certs SET DOCKER_API_VERSION=1.23 REM Run this command to configure your shell: REM @FOR /f "tokens=*" %i IN ('minikube docker-env') DO @%i これに従って以下のコマンドを実行するとクライアントの設定完了。 > @FOR /f "tokens=*" %i IN ('minikube docker-env') DO @%i これで準備完了。 SkaffoldのGetting Startedをやってみる。 Skaffoldのリポジトリをcloneして、コマンドプロンプト開いて、examples/getting-startedにcdして、以下のコマンドを実行。 > skaffold dev エラーで終わった。 [31mERRO[0047] run: running skaffold steps: starting watch on file C:\Users\kaitoy\Desktop\skaffold\examples\getting-started\Dockerfile: adding watch for C:\Users\kaitoy\Desktop\skaffold\examples\getting-started\Dockerfile: The parameter is incorrect.
eyecatch
Sun, Mar 25, 2018

機械学習のHello World: MNISTの分類モデルをKerasで作ってみた

機械学習のHello WorldとしてよくやられるMNISTの分類モデルをKeras on TensorFlowで作ってみた話。 (adsbygoogle = window.adsbygoogle || []).push({}); MNISTとは 手書き数字画像のラベル付きデータセット。 6万個の訓練データと1万個のテストデータからなる。 CC BY-SA 3.0で配布されているっぽい。 一つの画像は28×28ピクセルの白黒画像で、0から9のアラビア数字が書かれている。 画像とラベルがそれぞれ独特な形式でアーカイブされていて、画像一つ、ラベル一つ取り出すのも一苦労する。 Kerasとは Pythonのニューラルネットワークライブラリ。 バックエンドとしてTensorFlowかCNTKかTheanoを使う。 今回はTensorFlowを使った。 やったこと KerasのMNISTのAPIとかコードサンプルとかがあけどこれらはスルー。 MNISTのサイトにあるデータセットをダウンロードしてきて、サイトに書いてあるデータ形式の説明を見ながらサンプルを取り出すコードを書いた。 で、KerasでVGGっぽいCNNを書いて、学習させてモデルをダンプして、ダンプしたモデルをロードしてテストデータで評価するコードを書いた。 コードはGitHubに。 ネットワークアーキテクチャ 入力画像のサイズに合わせてVGGを小さくした感じのCNNを作った。 VGGは2014年に発表されたアーキテクチャで、各層に同じフィルタを使い、フィルタ数を線形増加させるシンプルな構造でありながら、性能がよく、今でもよく使われるっぽい。 VGGを図にすると以下の構造。 実際はバッチ正規化とかDropoutもやるのかも。 プーリング層は数えないで16層なので、VGG-16とも呼ばれる。 パラメータ数は1億3800万個くらいで、結構深めなアーキテクチャ。 VGG-16は244×244×3の画像を入力して1000クラスに分類するのに対し、MNISTは28×28×1を入れて10クラスに分類するので、以下のような7層版を作った。 これでパラメータ数は27万個くらい。 訓練データのサンプル数が6万個なので、パラメータ数が大分多い感じではある。 コードは以下。 inputs: Tensor = Input(shape=(IMAGE_NUM_ROWS, IMAGE_NUM_COLS, 1)) x: Tensor = Conv2D(filters=8, kernel_size=(2, 2), padding='same', activation='relu')(inputs) x = Conv2D(filters=8, kernel_size=(2, 2), padding='same', activation='relu')(x) x = MaxPooling2D(pool_size=(2, 2))(x) x = Conv2D(filters=16, kernel_size=(2, 2), padding='same', activation='relu')(x) x = Conv2D(filters=16, kernel_size=(2, 2), padding='same', activation='relu')(x) x = Conv2D(filters=16, kernel_size=(2, 2), padding='same', activation='relu')(x) x = MaxPooling2D(pool_size=(2, 2))(x) x = Flatten()(x) x = Dense(units=256, activation='relu')(x) x = Dense(units=256, activation='relu')(x) predictions: Tensor = Dense(NUM_CLASSES, activation='softmax')(x) model: Model = Model(inputs=inputs, outputs=predictions) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) 訓練・評価 上記モデルを6万個のサンプルでバッチサイズ512で一周(1エポック)学習させると、Intel Core i5-6300HQプロセッサー、メモリ16GBのノートPCで28秒前後かかる。 とりあえず3エポック学習させてみる。 (ml-mnist) C:\workspace\ml-mnist>python bin\ml_mnist.py train Using TensorFlow backend.
eyecatch
Sun, Mar 4, 2018

オープンデータメモ

機械学習の勉強に使えそうなオープンデータのメモ。 (adsbygoogle = window.adsbygoogle || []).push({}); テキスト WordNet: 英語の語彙データベース。名詞、動詞、形容詞、副詞ごとに階層的にグルーピングされたDBが提供されている。ライセンスはWordNet Licenseで、著作権表示さえしておけば、目的の制限なく、使用、複製、改変、再配布を無料でできる。 日本語ワードネット: 日本語版WordNet。ライセンスはJapanese WordNetライセンスで、著作権表示さえしておけば、目的の制限なく、使用、複製、改変、再配布を無料でできる。 画像 ImageNet: WordNetの名詞の階層構造に従ってラベル付けされた1400万個以上の画像データ。バウンディングボックスも付いてる。画像はFlickrとかに上がっているもので、そこから自分で無料でダウンロードできる。非商用(研究か教育)目的ならImageNetのサイトから画像をダウンロードできる。 Open Images: 900万個の画像に数千クラスのラベルとバウンディングボックスを付けたデータ。ライセンスはCreative Commons BY 4.0。 MNIST: 手書き数字のラベル付きデータセット。訓練データとテストデータ合わせて7万個。機械学習のHello Worldに使われる。 動画 YouTube-8M: 800万個のYouTube動画を4800クラスでラベル付けしたデータ。ライセンスはCreative Commons BY 4.0。 YouTube-Bounding Boxes: 24万個のYouTube動画に23クラスのラベルと560万個のバウンディングボックスを付けたデータ。ライセンスはCreative Commons BY 4.0。 Atomic Visual Actions(AVA): 5.76万個のYouTube動画を、80種の動作についてラベル付けしたデータ。ライセンスはCreative Commons BY 4.0。 音声 Speech Commands Datase: 6.5万個の1秒音声データで、30種の言葉を数千人が発音してる。ライセンスはCreative Commons BY 4.0。 AudioSet: 200万個の10秒音声データで、527クラスでラベル付けされてる。ライセンスはCreative Commons BY 4.0。 データカタログサイト DATA GO JP: 日本政府が公開してる公共データ集。 UCI Machine Learning Repository: 現時点で426のデータセットが配布されている。有名なアヤメのデータセットのソースはここ。 単語ベクトル HR領域の単語ベクトル: 約9.95億個の日本語のHR系の単語からWord2Vecで学習した単語ベクトル。ベクトル長は100か200。