はじめに
[Oracle Cloud] Oracle CloudでKubernetes the Hard Wayする (その①)からの続きです。
Kubenets the Hard Way in OCI (前回の続きから最後まで)
ワーカー・ノードの構成
★ WORKERノード設定:worker01/worker02/worker03で繰り返す
------------------------------------- < ここから > -------------------------------------
rpmパッケージのインストール
socat、conntrack、ipsetをインストールします
## worker01にログイン
(client)$ ssh worker01.private
※worker02・worker03作業時は、各ノードにログインして作業します。読み替えてください
(worker)$ sudo yum install -y socat conntrack ipset
________________< 出力は省略 >________________
swapの無効化
デフォルトでは、swapが有効化されているとkubeletがfailするそうなので、swapを無効化します
By default the kubelet will fail to start if swap is enabled. It is recommended that swap be disabled to ensure Kubernetes can provide proper resource allocation and quality of service.
## swapの状態を確認する
(worker):$ sudo swapon --show
________________< コマンド実行後 出力 >________________
NAME TYPE SIZE USED PRIO
/dev/sda2 partition 8G 0B -2
⇒ デフォルトでは有効化されている
## swapを無効化する
(worker):$ sudo swapoff -a
(worker):$ sudo cp -pi /etc/fstab /etc/fstab.$(date '+%Y%m%d')
(worker):$ sudo vi /etc/fstab
//swapのエントリをコメントアウトする//
# UUID=2ed28945-ff72-47d4-a34f-dedaed22eaec swap swap defaults,_netdev,x-initrd.mount 0 0
## 再度swapの状態を確認し、何も出力されないことを確認する
(worker):$ sudo swapon --show
ワーカー用バイナリのインストール
## ディレクトリを作成
(worker):$ sudo mkdir -p \
/etc/cni/net.d \
/opt/cni/bin \
/var/lib/kubelet \
/var/lib/kube-proxy \
/var/lib/kubernetes \
/var/run/kubernetes
## ファイルの展開
(worker):$ {
mkdir containerd
tar -xf crictl-v1.18.0-linux-amd64.tar.gz
tar -xf containerd-1.3.6-linux-amd64.tar.gz -C containerd
sudo tar -xf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin/
sudo mv runc.amd64 runc
chmod +x crictl kubectl kube-proxy kubelet runc
sudo mv crictl kubectl kube-proxy kubelet runc /usr/local/bin/
sudo mv containerd/bin/* /bin/
}
## 確認
(worker):$ cd /usr/local/bin/
(worker):$ ll crictl kubectl kube-proxy kubelet runc
________________< コマンド実行後 出力 >________________
-rwxr-xr-x. 1 opc opc 28447123 Apr 1 2020 crictl
-rwxrwxr-x. 1 opc opc 44036096 Jul 15 2020 kubectl
-rwxrwxr-x. 1 opc opc 113292024 Jul 15 2020 kubelet
-rwxrwxr-x. 1 opc opc 38383616 Jul 15 2020 kube-proxy
-rwxrwxr-x. 1 opc opc 12642864 Jul 30 10:33 runc
⇒ 上記ファイルが存在することを確認
(worker):$ cd -
(worker):$ ll /opt/cni/bin
________________< コマンド実行後 出力 >________________
total 70496
-rwxr-xr-x. 1 root root 4159518 May 13 2020 bandwidth
-rwxr-xr-x. 1 root root 4671647 May 13 2020 bridge
-rwxr-xr-x. 1 root root 12124326 May 13 2020 dhcp
-rwxr-xr-x. 1 root root 5945760 May 13 2020 firewall
-rwxr-xr-x. 1 root root 3069556 May 13 2020 flannel
-rwxr-xr-x. 1 root root 4174394 May 13 2020 host-device
-rwxr-xr-x. 1 root root 3614480 May 13 2020 host-local
-rwxr-xr-x. 1 root root 4314598 May 13 2020 ipvlan
-rwxr-xr-x. 1 root root 3209463 May 13 2020 loopback
-rwxr-xr-x. 1 root root 4389622 May 13 2020 macvlan
-rwxr-xr-x. 1 root root 3939867 May 13 2020 portmap
-rwxr-xr-x. 1 root root 4590277 May 13 2020 ptp
-rwxr-xr-x. 1 root root 3392826 May 13 2020 sbr
-rwxr-xr-x. 1 root root 2885430 May 13 2020 static
-rwxr-xr-x. 1 root root 3356587 May 13 2020 tuning
-rwxr-xr-x. 1 root root 4314446 May 13 2020 vlan
⇒ 上記ファイルが存在することを確認
(worker):$ ll /bin/containerd* /bin/ctr
________________< コマンド実行後 出力 >________________
-rwxr-xr-x. 1 opc opc 53283200 Jun 30 2020 /bin/containerd
-rwxr-xr-x. 1 opc opc 7180288 Jun 30 2020 /bin/containerd-shim
-rwxr-xr-x. 1 opc opc 8802304 Jun 30 2020 /bin/containerd-shim-runc-v1
-rwxr-xr-x. 1 opc opc 8806400 Jun 30 2020 /bin/containerd-shim-runc-v2
-rwxr-xr-x. 1 opc opc 25063104 Jun 30 2020 /bin/containerd-stress
-rwxr-xr-x. 1 opc opc 26991648 Jun 30 2020 /bin/ctr
⇒ 上記ファイルが存在することを確認
CNIネットワークの構成
## POD用ネットワークアドレスを変数に設定
(worker):$ POD_CIDR=<★作業しているworkerノードに応じて、以下のネットワークレンジを指定します★>
* worker01の場合:10.200.0.0/24
* worker02の場合:10.200.1.0/24
* worker03の場合:10.200.2.0/24
## bridgeネットワーク用の設定ファイルを生成
(worker):$ cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
{
"cniVersion": "0.3.1",
"name": "bridge",
"type": "bridge",
"bridge": "cnio0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "${POD_CIDR}"}]
],
"routes": [{"dst": "0.0.0.0/0"}]
}
}
EOF
________________< 出力は省略 >________________
## 確認
(worker):$ cat /etc/cni/net.d/10-bridge.conf
________________< 出力は省略 >________________
⇒ 変数部分が意図した値に設定されていること
## loopback用ネットワーク設定ファイルを生成
(worker):$ cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
{
"cniVersion": "0.3.1",
"name": "lo",
"type": "loopback"
}
EOF
________________< 出力は省略 >________________
(worker):$ cat /etc/cni/net.d/99-loopback.conf
________________< 出力は省略 >________________
⇒ 設定が書き込まれていること
Containerdの設定
## ディレクトリ作成
(worker):$ sudo mkdir -p /etc/containerd/
## containerdの設定ファイル作成
(worker):$ cat << EOF | sudo tee /etc/containerd/config.toml
[plugins]
[plugins.cri.containerd]
snapshotter = "overlayfs"
[plugins.cri.containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runc"
runtime_root = ""
EOF
________________< 出力は省略 >________________
## 確認
(worker):$ cat /etc/containerd/config.toml
________________< 出力は省略 >________________
⇒ 設定が書き込まれていること
## containerdのsystemdサービス設定ファイルを作成
(worker):$ cat <<EOF | sudo tee /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
EOF
________________< 出力は省略 >________________
(worker):$ cat /etc/systemd/system/containerd.service
________________< 出力は省略 >________________
⇒ 設定が書き込まれていること
kubeletの設定
## 証明書およびkubeconfigの配賦
(worker):$ {
sudo mv ${HOSTNAME}-key.pem ${HOSTNAME}.pem /var/lib/kubelet/
sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig
sudo mv ca.pem /var/lib/kubernetes/
}
## kubelet設定ファイルの作成
## オリジナルのkubernetes the hard wayには、以下のエントリがあります。
## resolvConf: "/run/systemd/resolve/resolv.conf"
## ただ、OCIで提供されているOELのイメージにはsystemd-resolvedがデフォルトでインストールされておらず、
## このエントリがあると、pod起動時にエラーになったため削除しています
(worker):$ cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
enabled: true
x509:
clientCAFile: "/var/lib/kubernetes/ca.pem"
authorization:
mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
- "10.32.0.10"
podCIDR: "${POD_CIDR}"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/${HOSTNAME}.pem"
tlsPrivateKeyFile: "/var/lib/kubelet/${HOSTNAME}-key.pem"
EOF
________________< 出力は省略 >________________
## 確認
(worker):$ cat /var/lib/kubelet/kubelet-config.yaml
________________< 出力は省略 >________________
⇒ 設定が書き込まれていること
## kubelet用systemdサービス設定ファイルの作成
(worker):$ cat <<EOF | sudo tee /etc/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--config=/var/lib/kubelet/kubelet-config.yaml \\
--container-runtime=remote \\
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \\
--image-pull-progress-deadline=2m \\
--kubeconfig=/var/lib/kubelet/kubeconfig \\
--network-plugin=cni \\
--register-node=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
________________< 出力は省略 >________________
## 確認
(worker):$ cat /etc/systemd/system/kubelet.service
________________< 出力は省略 >________________
⇒ 設定が書き込まれていること
Kubertenes Proxyの設定
## kubeconfigの配賦
(worker):$ sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
## kubernetes proxy設定ファイルの作成
(worker):$ cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "10.200.0.0/16"
EOF
________________< 出力は省略 >________________
## 確認
(worker):$ cat /var/lib/kube-proxy/kube-proxy-config.yaml
________________< 出力は省略 >________________
⇒ 設定が書き込まれていること
## kubernetes proxy用systemdサービス設定ファイルの作成
(worker):$ cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
________________< 出力は省略 >________________
## 確認
(worker):$ cat /etc/systemd/system/kube-proxy.service
________________< 出力は省略 >________________
⇒ 設定が書き込まれていること
サービスの起動
## サービス起動
(worker):$ {
sudo systemctl daemon-reload
sudo systemctl enable containerd kubelet kube-proxy
sudo systemctl start containerd kubelet kube-proxy
}
________________< 出力は省略 >________________
## 確認
(worker):$ systemctl status containerd kubelet kube-proxy
________________< コマンド実行後 出力 >________________
● containerd.service - containerd container runtime
Loaded: loaded (/etc/systemd/system/containerd.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2021-01-23 03:17:04 GMT; 28s ago
Docs: https://containerd.io
Process: 13075 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
//出力省略:running状態であること//
● kubelet.service - Kubernetes Kubelet
Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2021-01-23 03:17:04 GMT; 28s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 13085 (kubelet)
//出力省略:running状態であること//
● kube-proxy.service - Kubernetes Kube Proxy
Loaded: loaded (/etc/systemd/system/kube-proxy.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2021-01-23 03:17:04 GMT; 28s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 13084 (kube-proxy)
//出力省略:running状態であること//
## workerノードからログアウトし、clientノードに戻る
(worker):$ exit
動作確認
(client):$ ssh controller01.private kubectl get nodes --kubeconfig admin.kubeconfig
________________< コマンド実行後 出力 >________________
<worker01のみ完了時>
NAME STATUS ROLES AGE VERSION
worker01 Ready <none> 4m43s v1.18.6
<worker02まで完了時>
NAME STATUS ROLES AGE VERSION
worker01 Ready <none> 9m46s v1.18.6
worker02 Ready <none> 14s v1.18.6
<worker03まで完了時>
NAME STATUS ROLES AGE VERSION
worker01 Ready <none> 25m v1.18.6
worker02 Ready <none> 16m v1.18.6
worker03 Ready <none> 3m28s v1.18.6
------------------------------------- < ここまで > -------------------------------------
上記作業をworker02・worker03まで繰り返す
リモートからkubectlコマンドを実行するための設定
クライアント・ノードから、adminユーザ権限でkubectlコマンドを実行できるように設定します

## admin.kubeconfigファイルが存在するディレクトリに移動
(client):$ cd $HOME/kubectl/kubeconfig
(client):$ ll admin.kubeconfig
________________< コマンド実行後 出力 >________________
-rw-------. 1 opc opc 6261 Jan 22 04:44 admin.kubeconfig
⇒ 上記ファイルが存在すること
## LBのIPを変数に設定
(client):$ LB_IP=★LBのPrivate IP★
(client):$ {
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=$HOME/cfssl/cert/ca.pem \
--embed-certs=true \
--server=https://${LB_IP}:6443
kubectl config set-credentials admin \
--client-certificate=$HOME/cfssl/cert/admin.pem \
--client-key=$HOME/cfssl/cert/admin-key.pem
kubectl config set-context kubernetes-the-hard-way \
--cluster=kubernetes-the-hard-way \
--user=admin
kubectl config use-context kubernetes-the-hard-way
}
________________< コマンド実行後 出力 >________________
Cluster "kubernetes-the-hard-way" set.
User "admin" set.
Context "kubernetes-the-hard-way" modified.
Switched to context "kubernetes-the-hard-way".
## 動作確認
(client):$ kubectl get componentstatuses
________________< コマンド実行後 出力 >________________
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-2 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
⇒ 上記のように出力されること
(client):$ kubectl get nodes
________________< コマンド実行後 出力 >________________
NAME STATUS ROLES AGE VERSION
worker01 Ready <none> 37m v1.18.6
worker02 Ready <none> 28m v1.18.6
worker03 Ready <none> 15m v1.18.6
⇒ 上記のように出力されること
ルート表の修正
Pod用ネットワークの通信が各ワーカー・ノードにルーティングされるように設定します
Cloud Shellから以下のコマンドを実行します
## ワーカー・ノードのIPを設定
(CShell):$ WORKER01_IP=★worker01のIP★
(CShell):$ WORKER02_IP=★worker02のIP★
(CShell):$ WORKER03_IP=★worker03のIP★
## 各ワーカーノードのNIC OCIDを取得
(CShell):$ WORKER01_VNIC_OCID=$(oci --profile k8s compute instance list-vnics --raw-output --query 'data[?"hostname-label"==`worker01` && "lifecycle-state"==`AVAILABLE`].id |[0]')
(CShell):$ echo ${WORKER01_VNIC_OCID}
________________< コマンド実行後 出力 >________________
ocid1.vnic.oc1.ap-tokyo-1.abxhiljrlc4vueta5b26dpvn3crji7nvlgvitfdrvvcadmuc4hrxsnouwj4q
⇒ ocid1.vnicから始まるIDが出力されること
(CShell):$ WORKER02_VNIC_OCID=$(oci --profile k8s compute instance list-vnics --raw-output --query 'data[?"hostname-label"==`worker02` && "lifecycle-state"==`AVAILABLE`].id |[0]')
(CShell):$ echo ${WORKER02_VNIC_OCID}
________________< コマンド実行後 出力 >________________
ocid1.vnic.oc1.ap-tokyo-1.abxhiljrg56hd3cqq5luef7e2oikwaxqsulxbturobk32fzeog5j7uhhc3oa
⇒ ocid1.vnicから始まるIDが出力されること
(CShell):$ WORKER03_VNIC_OCID=$(oci --profile k8s compute instance list-vnics --raw-output --query 'data[?"hostname-label"==`worker03` && "lifecycle-state"==`AVAILABLE`].id |[0]')
(CShell):$ echo ${WORKER03_VNIC_OCID}
________________< コマンド実行後 出力 >________________
ocid1.vnic.oc1.ap-tokyo-1.abxhiljrnlvv2zeie7wzlln2shp23gl2hjrhddxxd4zejwz222uuqjatgxha
⇒ ocid1.vnicから始まるIDが出力されること
## 各VNICで、ソース・宛先チェック処理をスキップするように設定する
(CShell):$ for vnic_ocid in ${WORKER01_VNIC_OCID} ${WORKER02_VNIC_OCID} ${WORKER03_VNIC_OCID}
do
oci --profile k8s network vnic update \
--force \
--vnic-id ${vnic_ocid} --skip-source-dest-check true
done
________________< 出力は省略 >________________
## PrivateサブネットのルートテーブルのOCIDを取得
(CShell):$ ROUTE_OCID=$(oci --profile k8s network route-table list --raw-output --query 'data[?"display-name"==`route-table-private` && "lifecycle-state"==`AVAILABLE`].id |[0]')
(CShell)$ echo ${ROUTE_OCID}
________________< コマンド実行後 出力 >________________
ocid1.routetable.oc1.ap-tokyo-1.aaaaaaaaowoavnonhkmy5356rkefyy5ofrqtebxuqcxiz7tzprv7y3weg2mq
⇒ ocid1.routetableから始まるIDが出力されること
## NAT GWのOCIDを取得
(CShell):$ NAT_GW_OCID=$(oci --profile k8s network nat-gateway list --raw-output --query 'data[].id |[0]')
(CShell):$ echo ${NAT_GW_OCID}
________________< コマンド実行後 出力 >________________
ocid1.natgateway.oc1.ap-tokyo-1.aaaaaaaa6i65puwgi23reds2pacxlt3zhfjn6rjnro7cdw4dysjz2vqjlaqq
⇒ ocid1.natgatewayから始まるIDが出力されること
## 各ワーカーノードのPrivate IP OCIDを取得
(CShell):$ WORKER01_IP_OCID=$(oci --profile k8s network private-ip list --ip-address ${WORKER01_IP} --raw-output --query 'data[].id |[0]')
(CShell):$ echo ${WORKER01_IP_OCID}
________________< コマンド実行後 出力 >________________
ocid1.privateip.oc1.ap-tokyo-1.abxhiljr2vtr2tjqbl6y2ewfnw6b25xbwjevxixwyjlwfbeweels362eiuxq
⇒ ocid1.privateipから始まるIDが出力されること
(CShell):$ WORKER02_IP_OCID=$(oci --profile k8s network private-ip list --ip-address ${WORKER02_IP} --raw-output --query 'data[].id |[0]')
(CShell):$ echo ${WORKER02_IP_OCID}
________________< コマンド実行後 出力 >________________
ocid1.privateip.oc1.ap-tokyo-1.abxhiljr2tkmyt6nmdogjlkic7hcqcnsi5ubs4xs64j57i5vppuoodp2uzza
⇒ ocid1.privateipから始まるIDが出力されること
(CShell):$ WORKER03_IP_OCID=$(oci --profile k8s network private-ip list --ip-address ${WORKER03_IP} --raw-output --query 'data[].id |[0]')
(CShell):$ echo ${WORKER03_IP_OCID}
________________< コマンド実行後 出力 >________________
ocid1.privateip.oc1.ap-tokyo-1.abxhiljrs6lzm5zzi243pis6kjurzpn2o54nsswopzcszrju2xo4s5whng5q
⇒ ocid1.privateipから始まるIDが出力されること
## Privateサブネットのルート表をアップデートする
(CShell):$ oci --profile k8s network route-table update --force \
--rt-id ${ROUTE_OCID} \
--route-rules '[{"destination":"0.0.0.0/0", "networkEntityId":"'${NAT_GW_OCID}'"}
,{"destination":"10.200.0.0/24", "networkEntityId":"'${WORKER01_IP_OCID}'"}
,{"destination":"10.200.1.0/24", "networkEntityId":"'${WORKER02_IP_OCID}'"}
,{"destination":"10.200.2.0/24", "networkEntityId":"'${WORKER03_IP_OCID}'"}]'
________________< 出力は省略 >________________
更新後、Privateサブネットのルート・ルールが以下のように変更されていること

DNSクラスター・アドオンのインストール
CoreDNSをインストールする
サービス・ディスカバリに利用する、Kubernetes内部の名前解決用のPodをデプロイします
クライアント・ノードから以下のコマンドを実行します
(client):$ kubectl apply -f https://storage.googleapis.com/kubernetes-the-hard-way/coredns-1.7.0.yaml
________________< コマンド実行後 出力 >________________
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
configmap/coredns created
deployment.apps/coredns created
service/kube-dns created
## 状態確認
(client):$ kubectl get pods -l k8s-app=kube-dns -n kube-system
________________< コマンド実行後 出力 >________________
NAME READY STATUS RESTARTS AGE
coredns-5677dc4cdb-n9xhf 0/1 ContainerCreating 0 36s
coredns-5677dc4cdb-tng6q 0/1 ContainerCreating 0 36s
⇒ 上記のように出力されること
CoreDNSの動作確認
## busybox PODの作成
(client):$ kubectl run busybox --image=busybox:1.28 --command -- sleep 3600
________________< コマンド実行後 出力 >________________
pod/busybox created
## 状態確認
(client):$ kubectl get pods -l run=busybox
________________< コマンド実行後 出力 >________________
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 14m
⇒ 一定期間経過後、Running状態になること
(client):$ POD_NAME=$(kubectl get pods -l run=busybox -o jsonpath="{.items[0].metadata.name}")
(client):$ kubectl exec -ti $POD_NAME -- nslookup kubernetes
________________< コマンド実行後 出力 >________________
Server: 10.32.0.10
Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.32.0.1 kubernetes.default.svc.cluster.local
⇒ 上記のように出力されること
Smoke Test
これですべての設定が終わったので、Kubernetesクラスタが適切に動作するかのテストを行います。Smoke testは、簡易テストって意味だそうです。知りませんでした
Data Encryptionテスト
etcdのデータが暗号化されているかどうかをテストします。
## シークレットを作成
(client):$ kubectl create secret generic kubernetes-the-hard-way \
--from-literal="mykey=mydata"
________________< コマンド実行後 出力 >________________
secret/kubernetes-the-hard-way created
## controller01にログイン
(client):$ ssh controller01.private
## 確認
(controller01):$ sudo su -
(controller01):# etcdctl get \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.pem \
--cert=/etc/etcd/kubernetes.pem \
--key=/etc/etcd/kubernetes-key.pem\
/registry/secrets/default/kubernetes-the-hard-way | hexdump -C
________________< コマンド実行後 出力 >________________
00000000 2f 72 65 67 69 73 74 72 79 2f 73 65 63 72 65 74 |/registry/secret|
00000010 73 2f 64 65 66 61 75 6c 74 2f 6b 75 62 65 72 6e |s/default/kubern|
00000020 65 74 65 73 2d 74 68 65 2d 68 61 72 64 2d 77 61 |etes-the-hard-wa|
00000030 79 0a 6b 38 73 3a 65 6e 63 3a 61 65 73 63 62 63 |y.k8s:enc:aescbc|★
00000040 3a 76 31 3a 6b 65 79 31 3a 45 44 cf ea fa fa b6 |:v1:key1:ED.....|★
00000050 33 b0 bd 7d 0b 1b 7b 77 9b 8e 2a 05 58 c1 aa 87 |3..}..{w..*.X...|
00000060 21 9e ee 9f f4 29 71 fd 9f 55 e2 11 b6 2c 59 31 |!....)q..U...,Y1|
00000070 f4 6b c8 cd 96 e0 a0 5b 8f 86 40 bf 83 25 97 84 |.k.....[..@..%..|
//以降の出力省略//
k8s:enc:aescbc:v1:key1という文字列が出力されれればよいみたいです。
## controller01からログアウトして、クライアント・ノードに戻ります
(controller01):# exit
(controller01):$ exit
デプロイメント
nginxのコンテナをデプロイします
## Podを作成
(client):$ kubectl create deployment nginx --image=nginx
________________< コマンド実行後 出力 >________________
deployment.apps/nginx created
## 確認
(client):$ kubectl get pods -l app=nginx
________________< コマンド実行後 出力 >________________
NAME READY STATUS RESTARTS AGE
nginx-f89759699-kfj9q 1/1 Running 0 31s
⇒ Running状態になることを確認します
ポート・フォワーディング
ポートフォワードが行えることを確認します
## POD名を取得します
(client):$ POD_NAME=$(kubectl get pods -l app=nginx -o jsonpath="{.items[0].metadata.name}")
(client):$ kubectl port-forward $POD_NAME 8080:80
________________< コマンド実行後 出力 >________________
Forwarding from 127.0.0.1:8080 -> 80
⇒ この状態で待機状態になります
## もう一つターミナルを起動して、クライアント・ノードにログインします
(client):$ netstat -ntpl
________________< コマンド実行後 出力 >________________
//省略//
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 10204/kubectl
//省略//
⇒ kubectlコマンドがローカル・ホストの8080をリッスンしていることを確認します
## nginxにアクセスできるか確認します
(client):$ curl --head http://127.0.0.1:8080
________________< コマンド実行後 出力 >________________
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Sat, 23 Jan 2021 23:56:56 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 15 Dec 2020 13:59:38 GMT
Connection: keep-alive
ETag: "5fd8c14a-264"
Accept-Ranges: bytes
## アクセスすると、kubectl実行側のプロンプトに、以下のようなログが出力されます
________________< kubectl側 出力 >________________
Handling connection for 8080
## Ctrl+Cキーを押下してkubectlの実行を停止します
ログ
POD(nginx)が出力するログを参照できることを確認します
(client):$ kubectl logs $POD_NAME
________________< コマンド実行後 出力 >________________
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
127.0.0.1 - - [23/Jan/2021:23:56:56 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
コマンド実行
POD(nginx)内で任意コマンドが実行できることを確認します
(client):$ kubectl exec -ti $POD_NAME -- nginx -v
________________< コマンド実行後 出力 >________________
nginx version: nginx/1.19.6
⇒ nginxのバージョンが出力されることを確認します
サービス
サービスを利用したアクセスができることを確認します
## サービスの作成
(client):$ kubectl expose deployment nginx --port 80 --type NodePort
________________< コマンド実行後 出力 >________________
service/nginx exposed
## 確認
(client):$ kubectl get svc nginx
________________< コマンド実行後 出力 >________________
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.32.0.246 <none> 80:30663/TCP 80s
⇒ 上記のように出力されます
## ポート番号を取得して変数に格納
(client):$ NODE_PORT=$(kubectl get svc nginx \
--output=jsonpath='{range .spec.ports[0]}{.nodePort}')
(client):$ WORKER01_IP=★Worker01のIPを入力★
## worker01(POD実行ノード)のサービス用ポートにアクセス
(client):$ curl -I http://${WORKER01_IP}:${NODE_PORT}
________________< コマンド実行後 出力 >________________
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Sun, 24 Jan 2021 00:19:54 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 15 Dec 2020 13:59:38 GMT
Connection: keep-alive
ETag: "5fd8c14a-264"
Accept-Ranges: bytes
⇒ nginxからのレスポンスがあることを確認します
後片付け
・Computeインスタンスとネットワーク(LB含む)を削除します
ComputeインスタンスとLBは従量課金対象になるため、いらなくなったら削除します


