#はじめに
30代未経験からエンジニアを目指して勉強中のYNと申します。
インフラ初学者の私ですが、Kubernetes the hard way
を進めるにあたって、インフラに関する基本的な知識を体系的に学ぶことができました。
そこで、初学者目線での学びなどを本記事にまとめておきたいと思います。
#目次
こちらをご覧ください
#Control Planeコンポーネントの設定
それぞれのmastetrノードにAPI Server
、Scheduler
およびController Manager
をインストールします。
##インストール
kube-apiserve
、kube-controller-manager
、kube-scheduler
、kubectl
バイナリをインストールして展開します。
sudo mkdir -p /etc/kubernetes/config
wget -q --show-progress --https-only --timestamping \
"https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-apiserver" \
"https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-controller-manager" \
"https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-scheduler" \
"https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubectl"
実行権限を付与してバイナルフォルダに移動します↓
{
chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
}
##etcdの暗号化の設定を行う
Kubernetesクラスタの情報は全てetcdデータベースに保存されていますが、公式でも述べられているとおり、クラスター内で保持されるデータの暗号化を行う必要があります。
etcdデータベースには、Kubernetes APIを介してアクセス可能なあらゆる情報が含まれています。このため、暗号化ソリューションを活用してetcdのデータのバックアップを暗号化することや、EncryptionConfigurationを利用してデータを暗号化することが可能です。
参照
###暗号化のための適当なkeyを発行する
次のようにしてランダムなkeyを生成します。
ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
head -c 32
はファイルの頭から32バイトの情報を取得します。
/dev
は擬似デバイスファイルで、/dev/udrandom
は乱数を永遠に吐き続けるファイルです。
つまり、32バイトの乱数を取り出してbase64にエンコードしたものをkeyに設定します。
###暗号化設定ファイルを生成する
ファイルを生成してmasterノードで共有します。
encryption-config.yaml
はこの後のAPI-server
の設定で使います。
cat > encryption-config.yaml <<EOF
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: ${ENCRYPTION_KEY}
- identity: {}
EOF
for instance in master-1 master-2; do
scp encryption-config.yaml ${instance}:~/
done
##APIサーバーの設定
etcdサーバーのときと基本的に同じです。設定の全体像を示します。
###事前準備
{
sudo mkdir -p /var/lib/kubernetes/
sudo cp ca.crt ca.key kube-apiserver.crt kube-apiserver.key \
service-account.key service-account.crt \
etcd-server.key etcd-server.crt \
encryption-config.yaml /var/lib/kubernetes/
}
masterノードのinternal IPを取得(してshell変数に格納)します↓
INTERNAL_IP=$(ip addr show enp0s8 | grep "inet " | awk '{print $2}' | cut -d / -f 1)
###kube-apiserver.service
ファイルを設定する
systemdの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=3 \\
--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.crt \\
--enable-admission-plugins=NodeRestriction,ServiceAccount \\
--enable-swagger-ui=true \\
--enable-bootstrap-token-auth=true \\
--etcd-cafile=/var/lib/kubernetes/ca.crt \\
--etcd-certfile=/var/lib/kubernetes/etcd-server.crt \\
--etcd-keyfile=/var/lib/kubernetes/etcd-server.key \\
--etcd-servers=https://192.168.5.11:2379,https://192.168.5.12:2379 \\
--event-ttl=1h \\
--encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
--kubelet-certificate-authority=/var/lib/kubernetes/ca.crt \\
--kubelet-client-certificate=/var/lib/kubernetes/kube-apiserver.crt \\
--kubelet-client-key=/var/lib/kubernetes/kube-apiserver.key \\
--kubelet-https=true \\
--runtime-config=api/all \\
--service-account-key-file=/var/lib/kubernetes/service-account.crt \\
--service-cluster-ip-range=10.96.0.0/24 \\
--service-node-port-range=30000-32767 \\
--tls-cert-file=/var/lib/kubernetes/kube-apiserver.crt \\
--tls-private-key-file=/var/lib/kubernetes/kube-apiserver.key \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
この設定は、全体像におけるAPI-server
とその他のコンポーネントの関係についてを記述していることが見て取れます。その他特記すべき部分としては下記が挙げられます。
--etcd-servers=https://192.168.5.11:2379,https://192.168.5.12:2379
etcdサーバーの冗長化について設定しています
-
--enable-admission-plugins=NodeRestriction,ServiceAccount
:
API-serverに届くリクエストのvaidation方法について設定しています。
Admission controllers limit requests to create, delete, modify or connect to (proxy). They do not support read requests.
The admission control process proceeds in two phases. In the first phase, mutating admission controllers are run. In the second phase, validating admission controllers are run. Note again that some of the controllers are both.
If any of the controllers in either phase reject the request, the entire request is rejected immediately and an error is returned to the end-user.
参考
--authorization-mode=Node,RBAC
APi-serverがKubernetesコンポーネントにどういった権限を認めるかを設定します。参考
##Controller Managerの設定
API-serverと大体一緒です。
###事前準備
sudo cp kube-controller-manager.kubeconfig /var/lib/kubernetes/
###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=192.168.5.0/24 \\
--cluster-name=kubernetes \\
--cluster-signing-cert-file=/var/lib/kubernetes/ca.crt \\
--cluster-signing-key-file=/var/lib/kubernetes/ca.key \\
--kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
--leader-elect=true \\
--root-ca-file=/var/lib/kubernetes/ca.crt \\
--service-account-private-key-file=/var/lib/kubernetes/service-account.key \\
--service-cluster-ip-range=10.96.0.0/24 \\
--use-service-account-credentials=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
この設定を見ても、全体像におけるcontroller-manager
とその他のコンポーネントの関係についてほどんと記述していることが分かります。
また、--leader-elect=true
の部分に着目すると、master-1もしくはmaster-2ノードのどちらかでLeaderが起動していることが分かります。
##Schedulerの設定
これも上記とだいたい一緒です。
###事前準備
sudo cp kube-scheduler.kubeconfig /var/lib/kubernetes/
###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 \\
--kubeconfig=/var/lib/kubernetes/kube-scheduler.kubeconfig \\
--address=127.0.0.1 \\
--leader-elect=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
##control planeの起動
###起動
{
sudo systemctl daemon-reload
sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
}
###動作確認
kubectl get componentstatuses --kubeconfig admin.kubeconfig
#もしくは kubectl get componentstatuses
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health": "true"}
etcd-1 Healthy {"health": "true"}
##Frontend Load Balancerを設定する
外部からAPIサーバーへのアクセスに対するLBを設置します。
####Network Load Balancerを配置する
vagrant ssh loadbalancer
#Install HAProxy
sudo apt-get update && sudo apt-get install -y haproxy
cat <<EOF | sudo tee /etc/haproxy/haproxy.cfg
frontend kubernetes
bind 192.168.5.30:6443
option tcplog
mode tcp
default_backend kubernetes-master-nodes
backend kubernetes-master-nodes
mode tcp
balance roundrobin
option tcp-check
server master-1 192.168.5.11:6443 check fall 3 rise 2
server master-2 192.168.5.12:6443 check fall 3 rise 2
EOF
HAproxyの設定については公式を参照ください。
- frontend =>
192.168.5.30:6443
をlisten.後述のkubernetes-master-nodes
バックエンドにセッションを接続させる - backend =>
kubernetes-master-nodes
バックエンドについて規定する。master-1/master-2にラウンドロビンでスケジューリング。ヘルスチェックは3回連続OKで健全、2回連続失敗でfailと判定。
sudo service haproxy restart
###動作確認
# vagrantクラスタ外のターミナルからアクセス
curl https://192.168.5.30:6443/version -k
{
"major": "1",
"minor": "13",
"gitVersion": "v1.13.0",
"gitCommit": "ddf47ac13c1a9483ea035a79cd7c10005ff21a6d",
"gitTreeState": "clean",
"buildDate": "2018-12-03T20:56:12Z",
"goVersion": "go1.11.2",
"compiler": "gc",
"platform": "linux/amd64"
}