#はじめに
30代未経験からエンジニアを目指して勉強中のYNと申します。
インフラ初学者の私ですが、Kubernetes the hard way
を進めるにあたって、インフラに関する基本的な知識を体系的に学ぶことができました。
そこで、初学者目線での学びなどを本記事にまとめておきたいと思います。
#目次
こちらをご覧ください
#Workerノードを設定する
ここではWorkerノードにkubelet
とkube-proxy
をインストールします。
##kubeletのサーバー/クライアント証明書を生成
下図の通り、TLS証明書をつくります。
master-1$ cat > openssl-worker-1.cnf <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = worker-1
IP.1 = 192.168.5.21
EOF
openssl genrsa -out worker-1.key 2048
openssl req -new -key worker-1.key -subj "/CN=system:node:worker-1/O=system:nodes" -out worker-1.csr -config openssl-worker-1.cnf
openssl x509 -req -in worker-1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out worker-1.crt -extensions v3_req -extfile openssl-worker-1.cnf -days 1000
##kubelet Configuration ファイルを生成する
ここで、クラスター内外からのkube-apiserverへのリクエストにおける認証について整理しておくと、こちらに規定されている通り、API-server
へリクエストを送るに当たってクライアント認証の方法は4つのモードがあります。
- Node
- ABAC
- RBAC
- Webhook
その中でも、Nodeモードはkubelet
にのみ許された特権的な権限で、様々なAPI操作権限を有します。このNodeモードを使って認証するため、後述のkubeconfig
ファイルにsystem:node:worker-1
を設定する必要があります。
ここから、kubelet
の設定ファイルを作っていきます。
###LBのIPをshell変数にメモする
LOADBALANCER_ADDRESS=192.168.5.30
###worker-1.kubeconfigファイルを生成する
{
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=https://${LOADBALANCER_ADDRESS}:6443 \
--kubeconfig=worker-1.kubeconfig
kubectl config set-credentials system:node:worker-1 \
--client-certificate=worker-1.crt \
--client-key=worker-1.key \
--embed-certs=true \
--kubeconfig=worker-1.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:node:worker-1 \
--kubeconfig=worker-1.kubeconfig
kubectl config use-context default --kubeconfig=worker-1.kubeconfig
}
###作ったconfigファイルをworker-1ノードに移動する
scp ca.crt worker-1.crt worker-1.key worker-1.kubeconfig worker-1:~/
##worker-1ノードの設定
ここから、worker-1ノードの設定をしていきます。
###worker-1ノードににkubelet
/kube-proxy
/kubekubectl
をインストール
wget -q --show-progress --https-only --timestamping \
https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubectl \
https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-proxy \
https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubelet
###適切なディレクトリを作成
sudo mkdir -p \
/etc/cni/net.d \
/opt/cni/bin \
/var/lib/kubelet \
/var/lib/kube-proxy \
/var/lib/kubernetes \
/var/run/kubernetes
###実行権限を付与してディレクトリ移動
{
chmod +x kubectl kube-proxy kubelet
sudo mv kubectl kube-proxy kubelet /usr/local/bin/
}
###kubelet
の設定
####必要なデータを適切なディレクトリに移動する
{
sudo mv ${HOSTNAME}.key ${HOSTNAME}.crt /var/lib/kubelet/
sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig
sudo mv ca.crt /var/lib/kubernetes/
}
####kubelet-config.yaml
をつくる
cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous: #(1)
enabled: false
webhook: #(2)
enabled: true
x509: #(3)
clientCAFile: "/var/lib/kubernetes/ca.crt"
authorization:
mode: Webhook #(4)
clusterDomain: "cluster.local"
clusterDNS:
- "10.96.0.10"
resolvConf: "/run/systemd/resolve/resolv.conf" #(5)
runtimeRequestTimeout: "15m" #(6)
EOF
KubeletConfiguration
の詳細はこちらにありますが、上記を解説してみます。
- (1) kubeletへの(podなどからの)リクエストは全て認証を必要とさせます。
Enables anonymous requests to the Kubelet server. Requests that are not rejected by another authentication method are treated as anonymous requests. Anonymous requests have a username of
system:anonymous
, and a group name ofsystem:unauthenticated
.
- (2) kubeletの認証モードをwebhookに設定します。
※Webhookとは
Webhook - A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen.
- (3) kubeletがサーバーとして働く際に、利用するルート認証局の証明書の場所を指定します。
File containing x509 Certificate used for serving HTTPS (with intermediate certs, if any, concatenated after server cert).
- (4) kubeletによるリソースへのアクセス制御モードをwebhookにします。
Authorization mode for Kubelet server. Valid options are
AlwaysAllow
orWebhook
.
- (5) コンテナのDNS解決の設定ファイルの場所。後述する
kubelet.service
unitが使用してるubuntuネームサーバーの設定ファイルを指定します。
Resolver configuration file used as the basis for the container DNS resolution configuration.
- (6) コンテナ操作に時間がかかる場合のタイムアウト設定を指定します。
Timeout of all runtime requests except long running request -
pull
,logs
,exec
andattach
. When timeout exceeded, kubelet will cancel the request, throw out an error and retry later.
####kubelet.service
ファイルを設定する
このserviceをenableにすることで、ノード起動と共にkubeletが起動します。
workerノードには既にdockerがインストール済で、依存関係にdocker.service
が入っていることに注目します。
cat <<EOF | sudo tee /etc/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--config=/var/lib/kubelet/kubelet-config.yaml \\
--image-pull-progress-deadline=2m \\
--kubeconfig=/var/lib/kubelet/kubeconfig \\
--tls-cert-file=/var/lib/kubelet/${HOSTNAME}.crt \\
--tls-private-key-file=/var/lib/kubelet/${HOSTNAME}.key \\
--network-plugin=cni \\
--register-node=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
###kube-proxy
の設定
以前に生成したkube-proxy.kubeconfig
を使ってkube-proxy-config.yaml
をつくります。
####必要なデータを適切なディレクトリに移動する
sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
####kube-proxy-config.yaml
をつくる
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" #(1)
clusterCIDR: "192.168.5.0/24"
EOF
(1) proxy modeを規定します。各modeにおけるkube-proxyの挙動についてはこちらを参照ください。
- Which proxy mode to use: 'userspace' (older) or 'iptables' (faster) or 'ipvs' or 'kernelspace' (windows). If blank, use the best-available proxy (currently iptables). If the iptables proxy is selected, regardless of how, but the system's kernel or iptables versions are insufficient, this always falls back to the userspace proxy.
- デフォルトでは、iptablesモードにおけるkube-proxyはバックエンドPodをランダムで選択します。
- トラフィックのハンドリングのためにiptablesを使用すると、システムのオーバーヘッドが少なくなります。
- kube-proxyがiptablesモードで稼働し、最初に選択されたPodが応答しない場合、そのコネクションは失敗します。
KubeProxyConfiguration
の詳細はこちらを参照ください。
kube-proxy
はKubernetesクラスタ内で非常に大事な役割を果たしています。下図のようにユーザーおよびPodがノードを意識せず通信できるのはkube-proxy
とCNIがうまく機能しているからであり、ここがKubernetesクラスタのミソだと思います。
####kubelet.service
ファイルを設定する
このserviceをenableにすることで、ノード起動と共にkube-proxyが起動します。
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
###kubelet
とkube-proxy
を起動する
{
sudo systemctl daemon-reload
sudo systemctl enable kubelet kube-proxy
sudo systemctl start kubelet kube-proxy
}
###動作確認
kubectl get nodes
NAME STATUS ROLES AGE VERSION
worker-1 NotReady <none> 93s v1.13.0