後編を進める前に前編を確認してください。
Jujuによるアプリケーションのデプロイを実行する前に、JujuとCloud、Model、Charms、Bundleについて理解する必要があります。 詳細はJujuやMAASの公式ドキュメントをご確認いただくとして、次のような資料をアップロードしていますので参考にしてください。
www.slideshare.net
JujuとMAAS Cloudについて
JujuでMAAS Cloudを使ってアプリケーションをデプロイするには、事前に以下のような設定が必要です。公式ドキュメントを参考に設定してください。
- https://docs.jujucharms.com/2.4/en/clouds-maas
- https://docs.jujucharms.com/2.4/en/controllers-creating
Juju CharmもしくはBundleはJuju Charms Storeに公開されています。
今回はここからKubernetes + Calicoの構成のBundleを利用してセットアップします。
Juju Charms Storeに公開されているサンプルを用いることでJujuでKubernetesをデプロイできますが、正直、Kubernetesで永続ストレージを使いたいので、手頃に使えるNFSをBundleに追加して「kubernetes calico + NFS」な環境を自動でセットアップするBundleにしてみます。
NFSのJuju Charmはこちらを使います。
Bundle YAMLについて
Bundle YAMLについて少々解説します。
machinesにJujuでアプリケーションをデプロイするためのマシンを定義します。 machinesの下の数字はJuju Machineの番号です。0から始めます。この番号をservicesの展開先として後ほどtoの項に記述します。
seriesはOSをコードネームで示しています。Ubuntu 18.04のコードネームはBionic Beaverなので、ここではbionicを指定しています。
constraintsはマシンを識別するための項目です。今回はJuju+MAASの構成なので、amd64アーキテクチャーのサーバーでかつMAAS tagとして設定したtagを列挙します。指定できるconstraintsは"Cloud"によって異なります。詳細は次のドキュメントを確認してください。
上記を考慮した上で、Juju Charms Siteで公開されているKubernetes Calicoをベースに追加、加筆してみたものが次のYAMLです。
3台のマシンにデプロイするのでJuju Machinesに3台のノードを定義し、servicesの展開先としてJuju Machinesで定義したマシンを各種割り当てています。
# Kubernetes Calico 273 base
description: 3-machine Kubernetes cluster, appropriate for PoC. Includes a 2 Kubernetes worker nodes.
machines:
'0':
series: bionic
constraints: "arch=amd64 tags=vm1"
'1':
series: bionic
constraints: "arch=amd64 tags=vm2"
'2':
series: bionic
constraints: "arch=amd64 tags=vm3"
series: bionic
services:
calico:
annotations:
gui-x: '450'
gui-y: '750'
charm: cs:~containers/calico-526
options:
docker-opts: '--bip=10.0.0.1/16'
easyrsa:
annotations:
gui-x: '450'
gui-y: '550'
charm: cs:~containers/easyrsa-195
num_units: 1
to:
- 0
etcd:
annotations:
gui-x: '800'
gui-y: '550'
charm: cs:~containers/etcd-338
num_units: 1
options:
channel: 3.2/stable
to:
- 0
kubeapi-load-balancer:
annotations:
gui-x: '450'
gui-y: '250'
charm: cs:~containers/kubeapi-load-balancer-525
expose: true
num_units: 1
options:
proxy_read_timeout: 6000
to:
- 0
kubernetes-master:
annotations:
gui-x: '800'
gui-y: '850'
charm: cs:~containers/kubernetes-master-542
num_units: 1
options:
channel: 1.13/stable
enable-nvidia-plugin: auto
allow-privileged: "true"
to:
- 0
kubernetes-worker:
annotations:
gui-x: '100'
gui-y: '850'
charm: cs:~containers/kubernetes-worker-398
expose: true
num_units: 2
options:
channel: 1.13/stable
docker_runtime: auto
docker-opts: '--bip=10.0.0.1/16'
to:
- 1
- 2
nfs:
charm: 'cs:nfs-7'
num_units: 1
series: bionic
annotations:
gui-x: '104'
gui-y: '544'
to:
- 0
relations:
- - kubernetes-master:kube-api-endpoint
- kubeapi-load-balancer:apiserver
- - kubernetes-master:loadbalancer
- kubeapi-load-balancer:loadbalancer
- - kubernetes-master:kube-control
- kubernetes-worker:kube-control
- - kubernetes-master:certificates
- easyrsa:client
- - etcd:certificates
- easyrsa:client
- - kubernetes-master:etcd
- etcd:db
- - kubernetes-worker:certificates
- easyrsa:client
- - kubernetes-worker:kube-api-endpoint
- kubeapi-load-balancer:website
- - kubeapi-load-balancer:certificates
- easyrsa:client
- - calico:etcd
- etcd:db
- - calico:cni
- kubernetes-master:cni
- - calico:cni
- kubernetes-worker:cni
- - nfs:nfs
- kubernetes-worker:nfs
もし、CNIとしてCalicoではなくFlannelを使いたい場合は上記のYAMLのCalicoの部分を次のように変更してください。 relationsの変更もお忘れなく。
flannel:
annotations:
gui-x: '450'
gui-y: '750'
charm: cs:~containers/flannel-351
...
- - flannel:etcd
- etcd:db
- - flannel:cni
- kubernetes-master:cni
- - flannel:cni
- kubernetes-worker:cni
必要な情報や環境は揃いましたので早速デプロイしましょう。「juju add-model k8s」などのようにコマンドを実行してModelを作り、そのモデルにアプリケーションを登録します。 この後の流れについては以前の投稿をご覧いただき、デプロイを行なってください。
- https://tech.virtualtech.jp/entry/2018/06/15/115735
- https://tech.virtualtech.jp/entry/2018/06/15/162143
Kubernetesを早速使ってみる
次の流れでJujuを使ってデプロイした Kubernetesを、早速使ってみましょう。
1. クレデンシャルファイルをコピーしてくる
% mkdir ~/.kube && touch ~/.kube/config % juju scp kubernetes-master/0:config ~/.kube/config
2. クライアントにkubectlをインストールする
Ubuntuクライアントの場合
% sudo snap install kubectl --channel=stable --classic
macOSの場合(Homebrewが必要)
% brew install kubectl
3. 確認
クレデンシャルとkubectlコマンドの導入がうまくいったことを確認してみます。 次のような感じで出力されれば、Kubernetes Masterノード、Workerノードともに正常に動いていることが確認できます。
% kubectl get po --namespace=kube-system NAME READY STATUS RESTARTS AGE calico-policy-controller-5974f46875-6h8tp 1/1 Running 0 110m heapster-v1.6.0-beta.1-58774bcb4d-fgwf8 4/4 Running 0 107m kube-dns-8f7866879-rfx5p 3/3 Running 1 112m kubernetes-dashboard-654cfb4879-5sc9m 1/1 Running 2 112m metrics-server-v0.3.1-54b884db75-46dbh 2/2 Running 0 109m monitoring-influxdb-grafana-v4-5866497777-g2xnq 2/2 Running 0 112m % kubectl get no NAME STATUS ROLES AGE VERSION vm2 Ready <none> 112m v1.13.1 vm3 Ready <none> 112m v1.13.1
4. Kubernetes YAMLを用意する
今回はKubernetes 1.13をデプロイしたため、次のようなYAMLを用意すればNFSボリュームをPodに割り当てることができます。Kubernetes 1.10以降はいきなりPVCから要求してもうまくいくようになったようです。
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginxapp3-claim
spec:
storageClassName: default
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginxapp3
spec:
replicas: 2
template:
metadata:
labels:
app: nginxapp3
spec:
containers:
- name: nginxapp3
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html/"
name: nginxapp3
volumes:
- name: nginxapp3
persistentVolumeClaim:
claimName: nginxapp3-claim
---
apiVersion: v1
kind: Service
metadata:
name: nginxapp3-nodeport
labels:
app: nginxapp3
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: nginxapp3
5. Kubernetesでアプリケーションをデプロイする
デプロイ
% kubectl apply -f nfs-storage-default.yml persistentvolumeclaim/nginxapp3-claim created deployment.extensions/nginxapp3 created service/nginxapp3-nodeport created
状況の確認
% kubectl get -f nfs-storage-default.yml NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/nginxapp3-claim Bound pvc-23b2a893-130d-11e9-88fb-525400dd100b 1Gi RWX default 73s NAME READY UP-TO-DATE AVAILABLE AGE deployment.extensions/nginxapp3 2/2 2 2 73s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginxapp3-nodeport NodePort 10.152.183.65 <none> 80:31061/TCP 73s
アプリケーションへのアクセス
1. Podにログインしてみる
replicas: 2を指定していたため、2つPodが稼働中であることが確認できます。一方のPodにアクセスしてみます。
% kubectl get po|grep nginxapp3
nginxapp3-75dcf8dbdb-7gz8z 1/1 Running 0 41m
nginxapp3-75dcf8dbdb-svr8s 1/1 Running 0 41m
% kubectl exec -it nginxapp3-75dcf8dbdb-7gz8z -- ash
/ # df -h
...
172.17.28.57:/srv/data/kubernetes-worker/default-nginxapp3-claim-pvc-23b2a893-130d-11e9-88fb-525400dd100b
39.1G 7.7G 29.4G 21% /usr/share/nginx/html
2. コンテナーの内容を編集してみる
一方のPod内でHTMLコンテンツを作ってみます。
/ # echo "hello k8s world" >> /usr/share/nginx/html/index.htm / # exit ... % kubectl get svc|grep nginxapp3-nodeport nginxapp3-nodeport NodePort 10.152.183.65 <none> 80:31061/TCP 8m38s
NGINXサーバーにアクセスしてみます。同じNFS共有ボリュームをマウントするので、同じ内容が出力されます。
% kubectl get no -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME vm2 Ready <none> 125m v1.13.1 172.17.28.58 <none> Ubuntu 18.04.1 LTS 4.15.0-43-generic docker://18.6.1 vm3 Ready <none> 125m v1.13.1 172.17.28.66 <none> Ubuntu 18.04.1 LTS 4.15.0-43-generic docker://18.6.1 % curl http://172.17.28.58:31061 hello k8s world % curl http://172.17.28.66:31061 hello k8s world
kubeapi-load-balancerからアクセスしてみます。
% curl http://172.17.28.57:31061 hello k8s world
ちなみに
NFSサーバーをセットアップしたJuju Machineにアクセスすると、先ほど作成したindex.htmを見つけることができます。
ubuntu@vm1:~$ ls -R /srv/data/ /srv/data/: kubernetes-worker /srv/data/kubernetes-worker: default-nginxapp3-claim-pvc-23b2a893-130d-11e9-88fb-525400dd100b /srv/data/kubernetes-worker/default-nginxapp3-claim-pvc-23b2a893-130d-11e9-88fb-525400dd100b: index.htm
以上です。