寝ても覚めてもこんぴうた

プログラム書いたり、ネットワーク設計したり、サーバ構築したり、車いじったり、ゲームしたり。そんなひとにわたしはなりたい。 投げ銭は kyash_id : chidakiyo マデ

画像認識とかでよく使う例の画像がなんだかわかったので書く

タイトルの通り。

こういうやつ。
f:id:chidakiyo:20180819034242g:plain

なんか画像使ったサンプル作りたいときに例の画像を利用したいと思ったことがあり、
その時検索したけど見つからずに諦めていたけど見つかったのでメモ。

もともとはPLAYBOYの写真だったらしく、wikipedia 曰く、

レナ(Lenna または Lena)とは、PLAYBOY誌1972年11月号に掲載された女性ヌード写真の一部。画像圧縮アルゴリズムのサンプルに、広く使用されている画像データである。

レナ (画像データ) - Wikipedia

そして、オリジナルデータはここのものが多分それ。

original image: Lena

Kubernetesのどのノードにどのコンポーネントがいるか

なんかいまいち整理できていないな。と思ったので一旦雑に書き出した。

Master

  • etcd
  • apiserver
  • scheduler
  • controller manager

Node

  • kubelet
  • container-runtime
  • kube-proxy

masterはGKE/AKSとかであればマネージドで管理されているので、
ノードを起動していなくても kubectl コマンドが通るのはそのため。

Running Kubernetes Locally via Minikube をなぞってみた

URL : https://kubernetes.io/docs/setup/minikube/

MinikubeはKubernetesの以下の機能をサポートしているそうだ

  • DNS
  • NodePorts
  • ConfigMaps と Secrets
  • Dashboards
  • コンテナランタイム、Docker、rkt、CRI-O(デフォルトはDockerかな)
  • CNI(Container Network Interface)
  • Ingress

Minikubeのインストール

適当にこの辺を見つつインストール
https://kubernetes.io/docs/setup/minikube/

クイックスタート!

Minikubeはいくつかのドライバをサポートしているようですが、virtualboxが楽な気がします。おすすめ。

以下のコマンドでminikubeを起動します

$ minikube start

どうやら minikube start を実行すると kubectl にクレデンシャルが自動的に設定されるようです。
その他のクラスタを並行して触っている場合、勝手に変わっていることがあるので注意しましょう。
私はDocker for Mac上で KubernetesのContext切り替え機能でクラスタのクレデンシャルを切り変えています。

クラスタのクレデンシャルとは、k8sクラスタに接続する鍵です

上記 start コマンドを実行するとクレデンシャルが設定されるので以下のコマンドで確認してみます。

$ kubectl get nodes

以下のようにminikube nodeが見えるはずです

NAME       STATUS    ROLES     AGE       VERSION
minikube   Ready     master    8m        v1.10.0

ちなみに、kubectlコマンドの引数は以下のように省略することも可能です

$ kubectl get no

クイックスタートのとおりに hello-minikube をデプロイしてみる

$ kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.10 --port=8080

デプロイメント hello-minikube のポートをexposeする。

$ kubectl expose deployment hello-minikube --type=NodePort

Podが起動していることを確認してみる

$ kubectl get pods

ステータスが Running になっていればOK.

デプロイしたPodに以下のコマンドでアクセスできる。

$ curl $(minikube service hello-minikube --url)

IPアドレスは動的に変更され、以下のコマンドでも取得可能のようだ。(接続するためにはポートがわからないが)

$ minikube ip

サービスを削除する

$ kubectl delete services hello-minikube

デプロイメントを削除する

$ kubectl delete deployment hello-minikube

minikubeを停止する

$ minikube stop

その他のランタイムを使うためには

CRI-O

以下のコマンドでminikubeを起動する

$ minikube start \
    --network-plugin=cni \
    --container-runtime=cri-o \
    --bootstrapper=kubeadm

拡張版として使う場合には以下のようにする

$ minikube start \
    --network-plugin=cni \
    --extra-config=kubelet.container-runtime=remote \
    --extra-config=kubelet.container-runtime-endpoint=/var/run/crio.sock \
    --extra-config=kubelet.image-service-endpoint=/var/run/crio.sock \
    --bootstrapper=kubeadm

rkt

$ minikube start \
    --network-plugin=cni \
    --container-runtime=rkt

クラスタの管理

バージョンを指定してクラスタを起動する

minikubeがサポートしているバージョンは以下のコマンドで確認できる

$ minikube get-k8s-versions

バージョンを指定してk8sクラスタを起動するには以下のコマンドのようにする

$ minikube start --kubernetes-version v1.10.0

クラスタとの対話

minikubeはコンテキストを自動で設定するが(なるほどやはり)手動で設定するには以下のコマンドを利用する

$ kubectl config use-context minikube

ダッシュボード

ダッシュボードを起動するには以下のコマンドを実行する

$ minikube dashboard

ノードポートを利用して公開しているサービスのURLを得るには以下のコマンドを利用する

$ minikube service [-n NAMESPACE] [--url] NAME

$ minikube service hello-minikube --url

例2
直接ブラウザを開く場合には --url を省略する

$ minikube service hello-minikube

Network

アクセスできるIPを取得するには minikube ip が利用できる。

ポートを取得したい場合には

$ kubectl get service hello-minikube --output='jsonpath="{.spec.ports[0].nodePort}"'

のような形で取得できる

Persistent Volumes

Minikubeでは hostPath と呼ばれるタイプのPersistentVolumesがサポートされている
これは、Minikube VM内のディレクトリにPersistentVolumeとしてマップされる。

Minikube VMはtmpfsで起動するのでほとんどのディレクトリは永続化されない(再起動で消える)
以下のディレクトリだけは永続化できる

/data
/var/lib/localcube
/var/lib/docker

dataディレクトリに永続化するためのPersistentVolume設定は以下のようになる

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 5Gi
  hostPath:
    path: /data/pv0001/

ところどころ端折ってるけどこんな感じ。

goでsliceのdeepcopyをする

タイトルのとおりなんですが、 goでsliceのディープコピーを作りたかったので。

やり方は以下。

orig := []string{"a", "b", "c", "d", "e", "f"}  // 元sliceデータ
 
fmt.Printf("%p, %v\n", orig, orig)              // 0x10438150, [a b c d e f] 
 
copy := append([]string{}, orig...)            // sliceをコピーする
 
fmt.Printf("%p, %v\n", copy, copy)           // 0x10438180, [a b c d e f] ← 異なるポインタになっている。

という感じで結構簡単にコピーできた。

参考URL : go - Concisely deep copy a slice? - Stack Overflow

Mac OSにpyenvを利用してpython3をインストールし、pythonの切り替えも便利に

pyenvを利用することで、pythonの切り替えを便利にできるので、 直接python3をインストールするのではなく、pyenvを利用していく

pyenvのインストール

brew install pyenv

コマンド自体はこんな漢字でインストール完了

pythonを切り替えるために以下の設定を .zshrc なり .bashrc なりに投入する

echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.zshrc

bashの人は最後の .zshrc.bashrc か何かに切り替えて

pyenvを利用してpythonをインストールする

インストール可能なバージョンの確認

pyenv install --list

ダーッと文字が流れますが、上の方の数字の部分がpythonのバージョン、 記事を書いた現在(2018/06/19)、3.6.5が最新なのでそれをインストールする。

python 3.6.5 のインストール

pyenv install 3.6.5

pythonのバージョンの切り替え

システム全体のpythonのバージョンを変更する場合には以下のglobalコマンドを利用します。(ほとんどの人がこっちかな)

pyenv global 3.6.5

一時的に異なるバージョンを利用したい場合には

pyenv local 3.6.5

global or local を実行したあとに設定を有効にするためにrehashを実行します。

pyenv rehash

python のバージョンを確認する

python --version

を実行し、目的のバージョンに変わっていればokです。(今回の場合には3.6.5)

おまけ

あとはpythonのバージョンを変更したい場合には、

pyenv install --list でインストールできるバージョンを確認

pyenv install x.x.x でインストール

pyenv global x.x.x でバージョン切り替え

pyenv rehash で設定変更のおまじない

という流れでok。

rehashするのがめんどくさいって人がいれば、自動化するツールもあるみたい。
個人的にはrehashぐらい自分でやろうよ。という感じなので入れてません。

ではー

AKSのクイックスタートなぞってみた(Azure)

AKSのクイックスタートなぞってみた

まず、はじめるには

クイックスタートでは Azure Cloud Shell を利用する雰囲気で書いてある。
GCPばっかり使っていたので Cloud Shell は無料かと思いきや、Azureの場合にはストレージ領域分課金されるとのこと。
がっかりしたのでmacにインストールしたコマンドで実行することにした。

Azure Clientのバージョン確認

Cloud Shellを使わなくても、Azure Clientから実行ができる。
ただし、AKSのサンプルを試すにはバージョン 2.0.27 以降である必要があるので、以下のコマンドでバージョンを確認する。

az --version
azure-cli (2.0.35)
~~ snip ~~

という感じで表示されたのでバージョン的には問題なしなのでそのまま進めよう。

Azure Clientでのログイン

Azure Clientのログインを事前に行う必要がある。
コマンドは

az login

ターミナル上にURLが表示されるのでそのURLをブラウザに貼り付けて実行し、ターミナル上に表示されたキーをブラウザに貼り付ける。
ブラウザ側の処理が完了するとターミナル側の処理が進む(json形式のレスポンスが返ってくる)のでそれを待ちましょう。

AKSプレビューの有効化

必要なサービスプロバイダーが有効になっているかのチェックを実施。

az provider register -n Microsoft.Network
az provider register -n Microsoft.Storage
az provider register -n Microsoft.Compute
az provider register -n Microsoft.ContainerService

リソースグループを作成する

リソースグループとはリソースを任意のかたまりにまとめ、ライフサイクルや権限を一括して管理するための仕組み。というもののようです。
検証用の環境としてリソースグループ単位でゴソッと用意し、要らなくなったら一気に消す、などのようなことができるっぽい。 フロントのwebサーバグループ、裏側のDBグループ、のようなものではなく、webサーバ、DBサーバ、バッチサーバという感じでアプリケーション一式の塊をグループ化するのがお作法のようだ。

とりあえず作成してみる。
2018/06/12 現在、AKSは東京リージョンに来ていないので、 centralus を使ってみることにする。

az group create --name ${RESOURCE_GROUP_NAME} --location centralus

"provisioningState": "Succeeded" のような値を含むjsonレスポンスが返ってくれば成功だろう。

AKSクラスターを作成する

タイトルの通り。コマンドを実行してAKSクラスタを作成します。
クイックスタートの例ではnode1台ですが、欲張って2台にしてみます。1台で良いという方は1にしましょう。

az aks create --resource-group ${RESOURCE_GROUP_NAME} --name ${CLUSTER_NAME} --node-count 2 --generate-ssh-keys

クラスタの作成はそこそこ時間がかかります。(20分程度??)
完了後にjsonのレスポンスが返ってくるのでそれまでのんびり待ちましょう。

クラスターへの接続

k8sクラスタへの接続には kubectl を利用します。
私はすでにインストール済みだったのでスキップしていますが、各自適当な方法でインストールしてください。

ex. Azure CLIでインストールするには

az aks install-cli

クレデンシャルの取得

kubectl用のクレデンシャルの設定を行います。

az aks get-credentials --resource-group ${RESOURCE_GROUP_NAME} --name ${CLUSTER_NAME}

ノードの一覧を取得してみる

kubectl get nodes

こんな感じの応答が返ってくる

kubectl get nodes
NAME                       STATUS    ROLES     AGE       VERSION
aks-nodepool1-38601818-0   Ready     agent     41m       v1.9.6
aks-nodepool1-38601818-1   Ready     agent     41m       v1.9.6

アプリケーションの実行

以下のようなマニフェストファイルを作成し、デプロイを行います。
pythonアプリケーションとredisインスタンスが定義されています。

azure-vote.yaml ファイル

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: azure-vote-back
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: azure-vote-back
    spec:
      containers:
      - name: azure-vote-back
        image: redis
        ports:
        - containerPort: 6379
          name: redis
---
apiVersion: v1
kind: Service
metadata:
  name: azure-vote-back
spec:
  ports:
  - port: 6379
  selector:
    app: azure-vote-back
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: azure-vote-front
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: azure-vote-front
    spec:
      containers:
      - name: azure-vote-front
        image: microsoft/azure-vote-front:v1
        ports:
        - containerPort: 80
        env:
        - name: REDIS
          value: "azure-vote-back"
---
apiVersion: v1
kind: Service
metadata:
  name: azure-vote-front
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: azure-vote-front

アプリケーションの実行

kubectl create -f azure-vote.yaml

以下のような出力がなされれば完了

deployment "azure-vote-back" created
service "azure-vote-back" created
deployment "azure-vote-front" created
service "azure-vote-front" created

アプリケーションをテストする

アプリケーションが実行されたあとに、アプリケーションフロントエンドを公開するための kubernetesサービス が作成されますが、数分かかります。
状況を監視するには以下のコマンドを利用します。

kubectl get service azure-vote-front --watch

EXTERNAL-IP が <pending> の状態ではまだ完了していません。
EXTERNAL-IPが確定したら、 ctrl+c を実行してwatchを停止します。

外部アドレスで接続し、アプリの動作を確認する

ブラウザに先程のEXTERNAL-IPを入力し、アクセスします。

→ Cats & Dogs の投票ができました。

(注:実行するとリソースグループごと消えます)クラスターを削除する

クイックスタートで実行したクラスタをリソースグループごと削除します。 (このコマンドを実行すると作成したクラスタが、最初に作成したリソースグループごと消えます)

az group delete --name ${RESOURCE_GROUP_NAME} --yes --no-wait

結構簡単に利用することができた。
一番しんどかったのはAKSクラスタを作成する az aks create コマンドを実行したときでした。(1時間近く待ちました・・・)

とはいえ、コンテナも作成してあり、yamlの記述に不安がなければ比較的かんたんに利用できそうです。

enjoy!

Mac に brew を使って Azure Client をインストールする

そんなに難しい話じゃないのでサラッとメモ

Azure Client をインストール

brew update && brew install azure-cli

az コマンドでログイン

az login

こんなかんじ

(おまけ) コマンドのアップデート

brew update && brew upgrade azure-cli

ほぼ公式ドキュメントに書いてあるけど

URL : https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-macos