Kubernetes the Hard Way on Azure : 8. コントロールプレーン

こんにちは。
引き続き、Kubernetes the Hard Way on Azure を進めていきます。

8. Bootstrapping the Kubernetes Control Plane

このラボでは、2つのコンピューティングインスタンス間でKubernetesコントロールプレーンをブートストラップし、高可用性のために構成します。また、APIサーバをリモートクライアントに公開する外部ロードバランサを作成します。

各ノードにインストールされるコンポーネントは以下です。

  • Kubernetes APIサーバ
  • スケジューラ
  • コントローラーマネージャ

    f:id:dombri:20200212114238j:plain

本日はこの辺り。Kubernetes の要達の登場です。

Prerequisites

このラボのコマンドは、各コントローラインスタンス(controller-0 ,controller-1)で実行する必要があります。

Azコマンドを使用して各コントローラインスタンスにログインし、パブリックIPとsshを見つけます。

CONTROLLER="controller-1"
PUBLIC_IP_ADDRESS=$(az network public-ip show -g kubernetes \
 -n ${CONTROLLER}-pip --query "ipAddress" -otsv)

ssh kuberoot@${PUBLIC_IP_ADDRESS}


Running commands in parallel with tmux

Tmux を使用して、複数のコンピューティングインスタンスで同時にコマンドを実行できます。
参照

Provision the Kubernetes Control Plane

Kubernetes構成ディレクトリを作成します。
memo: tmux の使い方  参考:http://kanjuku-tomato.blogspot.com/2014/02/tmux.html

# tmux の起動
tmux

# 起動中のセッションの確認
tmux list-sessions

# 起動中のクライアントを確認
tmux list-client

# sessionのデタッチ(tmuxを継続させたままクライアントを終了)
Ctrl-b

# sessionのアタッチ
tmux attach -t 0

# sessionの削除
tmux kill-session

# 全てのsessionの削除
tmux kill-server

# 新しいウィンドウの作成
Ctrl-b + c
# 画面下の番号がウィンドウ、現在のものに*

# ウィンドウの切替
Ctrl-b + ウィンドウの番号

# ウィンドウの一覧
Ctrl-b + w

# ペインの操作(水平分割)
Ctrl-b + "

# ペインの動作(垂直分割)
Ctrl-b + %

# ペイン間の移動
Ctrl-b + o

# 分割の削除
Ctrl-b + x

Kubernetes構成ディレクトリを作成します。

sudo mkdir -p /etc/kubernetes/config


Download and Install the Kubernetes Controller Binaries

Kubernetesの公式リリースバイナリをダウンロードします。

wget -q --show-progress --https-only --timestamping \
 "https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/linux/amd64/kube-apiserver" \
 "https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/linux/amd64/kube-controller-manager" \
 "https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/linux/amd64/kube-scheduler" \
 "https://storage.googleapis.com/kubernetes-release/release/v1.15.0/bin/linux/amd64/kubectl"

Kubernetesバイナリをインストールします。

{
 chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
 sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
}


Configure the Kubernetes API Server

{
 sudo mkdir -p /var/lib/kubernetes/
 sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
  service-account-key.pem service-account.pem \
  encryption-config.yaml /var/lib/kubernetes/
}

インスタンスの内部IPアドレスを使用して、APIサーバをクラスタのメンバに公表します。現在のコンピューティングインスタンスの内部IPアドレスを取得します。

INTERNAL_IP=$(ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')

systemdユニットファイル [kube-apiserver.service] を作成します。

cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
 --advertise-address=${INTERNAL_IP} \\
 --allow-privileged=true \\
 --apiserver-count=2 \\
 --audit-log-maxage=30 \\
 --audit-log-maxbackup=3 \\
 --audit-log-maxsize=100 \\
 --audit-log-path=/var/log/audit.log \\
 --authorization-mode=Node,RBAC \\
 --bind-address=0.0.0.0 \\
 --client-ca-file=/var/lib/kubernetes/ca.pem \\
 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass,PersistentVolumeClaimResize,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota \\
 --enable-swagger-ui=true \\
 --etcd-cafile=/var/lib/kubernetes/ca.pem \\
 --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
 --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
 --etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379 \\
 --event-ttl=1h \\
 --experimental-encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
 --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
 --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
 --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
 --kubelet-https=true \\
 --runtime-config=api/all \\
 --service-account-key-file=/var/lib/kubernetes/service-account.pem \\
 --service-cluster-ip-range=10.32.0.0/24 \\
 --service-node-port-range=30000-32767 \\
 --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
 --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
 --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF


Configure the Kubernetes Controller Manager

kubeconfig [kube-controller-manager] を所定の場所に移動します。

sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/

systemdユニットファイル [kube-controller-manager.service] を作成します。

cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-controller-manager \\
 --address=0.0.0.0 \\
 --cluster-cidr=10.200.0.0/16 \\
 --cluster-name=kubernetes \\
 --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\
 --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\
 --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
 --leader-elect=true \\
 --root-ca-file=/var/lib/kubernetes/ca.pem \\
 --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\
 --service-cluster-ip-range=10.32.0.0/24 \\
 --use-service-account-credentials=true \\
 --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF


Configure the Kubernetes Scheduler

kubeconfig [kube-scheduler] を所定の場所に移動します。

sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/

構成ファイル [Kube-scheduler.yaml] を作成します。

cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
clientConnection:
 kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
 leaderElect: true
EOF

systemdユニットファイル [kube-scheduler.service] を作成します。

cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-scheduler \\
 --config=/etc/kubernetes/config/kube-scheduler.yaml \\
 --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF


Start the Controller Services

コントローラ サービスを起動します。

{
 sudo systemctl daemon-reload
 sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
 sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
}


Verification

kubectl get componentstatuses

NAME        STATUS  MESSAGE      ERROR
controller-manager Healthy ok 
scheduler      Healthy ok 
etcd-0       Healthy {"health":"true"} 
etcd-1       Healthy {"health":"true"}  

※全てのコントローラノードで確かめてください

RBAC for Kubelet Authorization

RBACアクセス許可 を構成して、Kubernetes APIサーバが各ワーカノードのKubelet APIにアクセスできるようにします。 Kubelet APIへのアクセスは、Pod で metrics、logs を取得し、コマンドを実行するために必要です。

このチュートリアルでは、Kubelet --authorization-mode フラグをWebhookに設定します。 Webhook モードは、SubjectAccessReview API を使用して承認を決定します。

コントローラノードに接続(一つでOK)

CONTROLLER="controller-0"
PUBLIC_IP_ADDRESS=$(az network public-ip show -g kubernetes \
 -n ${CONTROLLER}-pip --query "ipAddress" -otsv)

ssh kuberoot@${PUBLIC_IP_ADDRESS}

Kubelet APIにアクセスし、Podの管理に関連する最も一般的なタスクを実行する権限を持つClusterRolesystem:kube-apiserver-to-kubelet を作成します。

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
 annotations:
  rbac.authorization.kubernetes.io/autoupdate: "true"
 labels:
  kubernetes.io/bootstrapping: rbac-defaults
 name: system:kube-apiserver-to-kubelet
rules:
 - apiGroups:
   - ""
  resources:
   - nodes/proxy
   - nodes/stats
   - nodes/log
   - nodes/spec
   - nodes/metrics
  verbs:
   - "*"
EOF

Kubernetes APIサーバは --kubelet-client-certificate フラグで定義されたクライアント証明書を使用して、[kubernetes] ユーザとして Kubelet に対して認証を行います。

system:kube-apiserver-to-kubelet ClusterRoleを kubernetesユーザ にバインドします。

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
 name: system:kube-apiserver
 namespace: ""
roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: ClusterRole
 name: system:kube-apiserver-to-kubelet
subjects:
 - apiGroup: rbac.authorization.k8s.io
  kind: User
  name: kubernetes
EOF


The Kubernetes Frontend Load Balancer

このセクションでは、Kubernetes APIサーバの前に外部ロードバランサをプロビジョニングします。静的IPアドレス [Kubernetes-the-hard-way] は、ロードバランサにアタッチされます。

このチュートリアルで作成されたコンピューティングインスタンスには、このセクションを完了する権限がありません。コントロールインスタンスの作成に使用したのと同じマシンから次のコマンドを実行します。

ロードバランサの正常性プローブを、後続のLBルールの前提条件として作成します。

az network lb probe create -g kubernetes \
 --lb-name kubernetes-lb \
 --name kubernetes-apiserver-probe \
 --port 6443 \
 --protocol tcp

外部ロードバランサのネットワークリソースを作成します。

az network lb rule create -g kubernetes \
 -n kubernetes-apiserver-rule \
 --protocol tcp \
 --lb-name kubernetes-lb \
 --frontend-ip-name LoadBalancerFrontEnd \
 --frontend-port 6443 \
 --backend-pool-name kubernetes-lb-pool \
 --backend-port 6443 \
 --probe-name kubernetes-apiserver-probe


Verification

静的IPアドレス[kubernetes-the-hard-way]を取得します。

KUBERNETES_PUBLIC_IP_ADDRESS=$(az network public-ip show -g kubernetes \
 -n kubernetes-pip --query ipAddress -otsv)

Kubernetesバージョン情報のHTTPリクエストを実行します。

curl --cacert ca.pem https://$KUBERNETES_PUBLIC_IP_ADDRESS:6443/version
{
 "major": "1",
 "minor": "15",
 "gitVersion": "v1.15.0",
 "gitCommit": "e8462b5b5dc2584fdcd18e6bcfe9f1e4d970a529",
 "gitTreeState": "clean",
 "buildDate": "2019-06-19T16:32:14Z",
 "goVersion": "go1.12.5",
 "compiler": "gc",
 "platform": "linux/amd64"
}

設定できていることを確認できました。

まとめ

  • コントロールプレーンの構築
    • Kubernetes APIサーバ
    • スケジューラ
    • コントローラーマネージャ
  • ロードバランサの構築

9.へ続きます。