Kubernetes the Hard Way on OpenStack
Kubernetesの構築をスクラッチで実践できるチュートリアルとしてKubernetes the Hard Wayがあります。来年のはじめくらいにCKAを取得したいと考えているので、本チュートリアルを自宅のOpenStack上で実施してみました。その際の実施手順と少しばかりの解説を残しておきたいと思います。
前提
OpenStackには次のコンポーネントがインストールされているとします。
- Keystone
- Glance
- Nova
- Neutron
- Neutron LBaaSv2
- Designate
次のインスタンスを用意し、HA構成のKubernetesを構成します。 ホスト名でFloatingIPに名前解決ができるようにDesignateを構成しておきます。
Masterサーバ x3
- OS: CentOS 7 Minimal Install
- vCPU: 2
- Mem: 4GB
- ホスト名: hardway-master-[0:2].bbrfkr.mydns.jp
- IP: 10.0.0.[10:12]
- FloatingIP: 192.168.0.[10:12]
Workerサーバ x3
- OS: CentOS 7 Minimal Install
- vCPU: 2
- Mem: 4GB
- ホスト名: hardway-worker-[0:2].bbrfkr.mydns.jp
- IP: 10.0.0.[20:22]
- FloatingIP: 192.168.0.[20:22]
また、FloatingIPに対して到達可能なネットワーク上に作業用端末を用意しておきます。作業用端末ではあらかじめ以下のコマンドが叩けるように準備しておきます。私の場合はWindows 10にWSLのUbuntuをインストールして、その上から叩けるようにしました。
- cfssl
- cfssljson
- kubectl
- openstack
- neutron
Masterサーバのkube-apiserverに対するエンドポイントとしてNeutron LBaaSv2にてロードバランサを切っておきます。また、VIP portに対するセキュリティグループも適切に設定しておきましょう。
- Neutron LBaaSv2 LB
- 名前: kubernetes-the-hard-way
- Internal VIP: 10.0.0.100
- FloatingIP: 192.168.0.100
- リスナーポート: 6443
手順
以降、Hard Wayな手順を示して行きます。作業対象は()付きでmasters、workers、bastion(作業用端末の意)で示していきます。
OS設定
- (masters, workers) OSパッケージの更新とSELinuxの無効化をしておきます。これはKubernetesのインストール要件になります。
sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config sudo yum update -y sudo reboot
CAおよび各種証明書の作成
ここではkube-apiserverとhttps通信するために必要な各種証明書を作成していきます。
- (bastion) CAの署名における設定とCA証明書および鍵を作成します。
cat > ca-config.json <<EOF { "signing": { "default": { "expiry": "8760h" }, "profiles": { "kubernetes": { "usages": ["signing", "key encipherment", "server auth", "client auth"], "expiry": "8760h" } } } } EOF cat > ca-csr.json <<EOF { "CN": "Kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "Kubernetes", "OU": "CA", "ST": "Oregon" } ] } EOF cfssl gencert -initca ca-csr.json | cfssljson -bare ca
- (bastion) Kubernetesクラスタのadminユーザに対するクライアント証明書および鍵を作成します。Kubernetesのx509証明書認証においてはCN(Common Name)に指定した値がクラスタのユーザ名、O(Organization)に指定した値がグループ名として扱われます。
system:masters
グループはデフォルトでKubernetesクラスタのフルコントロール権限を持つグループです。
cat > admin-csr.json <<EOF { "CN": "admin", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "system:masters", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=kubernetes \ admin-csr.json | cfssljson -bare admin
- (bastion) kubeletがkube-apiserverと通信するときのクライアント証明書および鍵を作成します。ここでは厳密にはNode Authorizationというkube-apiserverの認可機能を使うために、CNに
system:node:<インスタンス名>
、Oにsystem:nodes
という値を指定するのが肝となります。
for instance in hardway-worker-0 hardway-worker-1 hardway-worker-2; do cat > ${instance}-csr.json <<EOF { "CN": "system:node:${instance}", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "system:nodes", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF EXTERNAL_IP=$(openstack server show -f json ${instance} | \ jq -r .addresses | \ awk -F= '{ print $2 }' | \ sed 's/,//g' | \ awk '{ print $2 }') INTERNAL_IP=$(openstack server show -f json ${instance} | \ jq -r .addresses | \ awk -F= '{ print $2 }' | \ sed 's/,//g' | \ awk '{ print $1 }') cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \ -profile=kubernetes \ ${instance}-csr.json | cfssljson -bare ${instance} done
- (bastion) kube-controller-managerがkube-apiserverと通信するための証明書および鍵を作成します。
cat > kube-controller-manager-csr.json <<EOF { "CN": "system:kube-controller-manager", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "system:kube-controller-manager", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=kubernetes \ kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
- (bastion) kube-proxyがkube-apiserverと通信するための証明書および鍵を作成します。
cat > kube-proxy-csr.json <<EOF { "CN": "system:kube-proxy", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "system:node-proxier", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=kubernetes \ kube-proxy-csr.json | cfssljson -bare kube-proxy
- (bastion) kube-schedulerがkube-apiserverと通信するための証明書および鍵を作成します。
cat > kube-scheduler-csr.json <<EOF { "CN": "system:kube-scheduler", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "system:kube-scheduler", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=kubernetes \ kube-scheduler-csr.json | cfssljson -bare kube-scheduler
- (bastion) kube-apiserver用のサーバ証明書および鍵を作成します。この証明書で許可されたCNやSAN(Subject Alternative Name)でアクセスしなければkube-apiservertとhttps通信できないので、登録するSAN(
cfssl gencert
コマンドの-hostname
オプションのところ)に注意します。
KUBERNETES_PUBLIC_ADDRESS=$(neutron floatingip-list | grep \ $(neutron lbaas-loadbalancer-show kubernetes-the-hard-way | \ grep vip_port_id | \ awk '{ print $4 }') | \ awk '{ print $8 }') KUBERNETES_INTERNAL_ADDRESS=$(neutron lbaas-loadbalancer-show kubernetes-the-hard-way | \ grep vip_address | \ awk '{ print $4 }') KUBERNETES_PUBLIC_DNS=kubernetes-the-hard-way.bbrfkr.mydns.jp cat > kubernetes-csr.json <<EOF { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "Kubernetes", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF for instance in hardway-master-0 hardway-master-1 hardway-master-2; do MASTER_INTERNAL_IPS=${MASTER_INTERNAL_IPS}$(openstack server show -f json ${instance} | \ jq -r .addresses | \ awk -F= '{ print $2 }' | \ sed 's/,//g' | \ awk '{ print $1 }'), done cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -hostname=10.32.0.1,${MASTER_INTERNAL_IPS}${KUBERNETES_PUBLIC_ADDRESS},${KUBERNETES_INTERNAL_ADDRESS},${KUBERNETES_PUBLIC_DNS},127.0.0.1,kubernetes.default \ -profile=kubernetes \ kubernetes-csr.json | cfssljson -bare kubernetes
- (bastion) ServiceAccountのトークン発行用キーペアを作成します。
cat > service-account-csr.json <<EOF { "CN": "service-accounts", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "Kubernetes", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=kubernetes \ service-account-csr.json | cfssljson -bare service-account
- (bastion) 証明書群をMasterサーバ、Workerサーバに配布します。
for instance in hardway-worker-0 hardway-worker-1 hardway-worker-2; do scp ca.pem ${instance}-key.pem ${instance}.pem centos@${instance}.bbrfkr.mydns.jp:~/ done for instance in hardway-master-0 hardway-master-1 hardway-master-2; do scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ service-account-key.pem service-account.pem centos@${instance}.bbrfkr.mydns.jp:~/ done
kubeconfig群の作成
ここではkube-apiserverと通信するために必要な認証ファイルであるkubeconfigファイル群を作成していきます。
- (bastion) kubelet用のkubeconfigを作成します。
KUBERNETES_PUBLIC_ADDRESS=$(neutron floatingip-list | grep \ $(neutron lbaas-loadbalancer-show kubernetes-the-hard-way | \ grep vip_port_id | \ awk '{ print $4 }') | \ awk '{ print $8 }') for instance in hardway-worker-0 hardway-worker-1 hardway-worker-2; do kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \ --kubeconfig=${instance}.kubeconfig kubectl config set-credentials system:node:${instance} \ --client-certificate=${instance}.pem \ --client-key=${instance}-key.pem \ --embed-certs=true \ --kubeconfig=${instance}.kubeconfig kubectl config set-context default \ --cluster=kubernetes-the-hard-way \ --user=system:node:${instance} \ --kubeconfig=${instance}.kubeconfig kubectl config use-context default --kubeconfig=${instance}.kubeconfig done
- (bastion) kube-proxy用のkubeconfigを作成します。
kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \ --kubeconfig=kube-proxy.kubeconfig kubectl config set-credentials system:kube-proxy \ --client-certificate=kube-proxy.pem \ --client-key=kube-proxy-key.pem \ --embed-certs=true \ --kubeconfig=kube-proxy.kubeconfig kubectl config set-context default \ --cluster=kubernetes-the-hard-way \ --user=system:kube-proxy \ --kubeconfig=kube-proxy.kubeconfig kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
- (bastion) kube-controller-manager用のkubeconfigを作成します。
kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://127.0.0.1:6443 \ --kubeconfig=kube-controller-manager.kubeconfig kubectl config set-credentials system:kube-controller-manager \ --client-certificate=kube-controller-manager.pem \ --client-key=kube-controller-manager-key.pem \ --embed-certs=true \ --kubeconfig=kube-controller-manager.kubeconfig kubectl config set-context default \ --cluster=kubernetes-the-hard-way \ --user=system:kube-controller-manager \ --kubeconfig=kube-controller-manager.kubeconfig kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig
- (bastion) kube-scheduler用のkubeconfigを作成します。
kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://127.0.0.1:6443 \ --kubeconfig=kube-scheduler.kubeconfig kubectl config set-credentials system:kube-scheduler \ --client-certificate=kube-scheduler.pem \ --client-key=kube-scheduler-key.pem \ --embed-certs=true \ --kubeconfig=kube-scheduler.kubeconfig kubectl config set-context default \ --cluster=kubernetes-the-hard-way \ --user=system:kube-scheduler \ --kubeconfig=kube-scheduler.kubeconfig kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig
- (bastion) adminユーザ用のkubeconfigを作成します。
kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://127.0.0.1:6443 \ --kubeconfig=admin.kubeconfig kubectl config set-credentials admin \ --client-certificate=admin.pem \ --client-key=admin-key.pem \ --embed-certs=true \ --kubeconfig=admin.kubeconfig kubectl config set-context default \ --cluster=kubernetes-the-hard-way \ --user=admin \ --kubeconfig=admin.kubeconfig kubectl config use-context default --kubeconfig=admin.kubeconfig
- (bastion) kubeconfig群をMasterサーバ、Workerサーバに配布します。
for instance in hardway-worker-0 hardway-worker-1 hardway-worker-2; do scp ${instance}.kubeconfig kube-proxy.kubeconfig centos@${instance}.bbrfkr.mydns.jp:~/ done for instance in hardway-master-0 hardway-master-1 hardway-master-2; do scp admin.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig centos@${instance}.bbrfkr.mydns.jp:~/ done
データ暗号化用設定ファイルの作成
Kubernetesではetcdにクラスタ情報が格納されますが、ここではその格納データを暗号化するための設定を実施します。
- (bastion) クラスタデータ暗号化用設定ファイルを作成し、Masterサーバに配布します。
ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64) 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 hardway-master-0 hardway-master-1 hardway-master-2; do scp encryption-config.yaml centos@${instance}.bbrfkr.mydns.jp:~/ done
etcdクラスタの構築
ここではMasterサーバ上でetcdのHAクラスタを構築します。
- (masters) etcdバイナリのダウンロードと適切な場所への配置を行います。
sudo yum -y install wget wget "https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz" tar -xvf etcd-v3.3.9-linux-amd64.tar.gz sudo mv etcd-v3.3.9-linux-amd64/etcd* /usr/local/bin/
- (masters) etcd用のsystemd unitファイルを作成し、サービスを有効化します。
sudo mkdir -p /etc/etcd /var/lib/etcd sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/ INTERNAL_IP=$(curl http://169.254.169.254/latest/meta-data/local-ipv4) ETCD_NAME=$(hostname -s) MASTER_0_HOSTNAME=hardway-master-0 MASTER_0_INTERNAL_IP=10.0.0.10 MASTER_1_HOSTNAME=hardway-master-1 MASTER_1_INTERNAL_IP=10.0.0.11 MASTER_2_HOSTNAME=hardway-master-2 MASTER_2_INTERNAL_IP=10.0.0.12 cat <<EOF | sudo tee /etc/systemd/system/etcd.service [Unit] Description=etcd Documentation=https://github.com/coreos [Service] ExecStart=/usr/local/bin/etcd \\ --name ${ETCD_NAME} \\ --cert-file=/etc/etcd/kubernetes.pem \\ --key-file=/etc/etcd/kubernetes-key.pem \\ --peer-cert-file=/etc/etcd/kubernetes.pem \\ --peer-key-file=/etc/etcd/kubernetes-key.pem \\ --trusted-ca-file=/etc/etcd/ca.pem \\ --peer-trusted-ca-file=/etc/etcd/ca.pem \\ --peer-client-cert-auth \\ --client-cert-auth \\ --initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\ --listen-peer-urls https://${INTERNAL_IP}:2380 \\ --listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\ --advertise-client-urls https://${INTERNAL_IP}:2379 \\ --initial-cluster-token etcd-cluster-0 \\ --initial-cluster ${MASTER_0_HOSTNAME}=https://${MASTER_0_INTERNAL_IP}:2380,${MASTER_1_HOSTNAME}=https://${MASTER_1_INTERNAL_IP}:2380,${MASTER_2_HOSTNAME}=https://${MASTER_2_INTERNAL_IP}:2380 \\ --initial-cluster-state new \\ --data-dir=/var/lib/etcd Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable etcd sudo systemctl start etcd
- (masters) etcdの正常動作確認をするには以下のコマンドを実行します。
sudo su - -lc \ "ETCDCTL_API=3 etcdctl member list \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/etcd/ca.pem \ --cert=/etc/etcd/kubernetes.pem \ --key=/etc/etcd/kubernetes-key.pem"
Masterサーバの構築
ここではMasterサーバの構築を実施します。
- (masters) Kubernetesの設定ファイル用ディレクトリを作成します。
sudo mkdir -p /etc/kubernetes/config
- (masters) Masterサーバ用コンポーネントのバイナリをダウンロードし、適切な場所に配置します。
wget \ "https://storage.googleapis.com/kubernetes-release/release/v1.13.1/bin/linux/amd64/kube-apiserver" \ "https://storage.googleapis.com/kubernetes-release/release/v1.13.1/bin/linux/amd64/kube-controller-manager" \ "https://storage.googleapis.com/kubernetes-release/release/v1.13.1/bin/linux/amd64/kube-scheduler" \ "https://storage.googleapis.com/kubernetes-release/release/v1.13.1/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/
- (masters) kube-apiserver用の証明書群の配置とsystemd unitファイルを作成します。ここでKubernetesのServiceリソースで利用するIP帯
10.32.0.0/24
を指定します。
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/ INTERNAL_IP=$(curl http://169.254.169.254/latest/meta-data/local-ipv4) MASTER_0_INTERNAL_IP=10.0.0.10 MASTER_1_INTERNAL_IP=10.0.0.11 MASTER_2_INTERNAL_IP=10.0.0.12 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.pem \\ --enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,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://${MASTER_0_INTERNAL_IP}:2379,https://${MASTER_1_INTERNAL_IP}:2379,https://${MASTER_2_INTERNAL_IP}: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
- (masters) kube-controller-manager用のkubeconfigの配置とsystemd unitファイルを作成します。
--cluster-cidr
オプションにはPodが利用するIP帯172.17.0.0/16
を指定しておきます。
sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/ 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=172.17.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 \\ --allocate-node-cidrs=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
- (masters) kube-scheduler用の設定ファイルおよびkubeconfigの配置とsystemd unitファイルを作成します。
sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/ 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 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
- (masters) Masterサーバの各種サービスを有効化します。
sudo systemctl daemon-reload sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
- (masters(hardway-master-0のみ)) kube-apiserverがWorkerサーバのkubeletに接続可能にするため、RBACの設定を入れておきます。
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - apiVersion: rbac.authorization.k8s.io/v1beta1 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 cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - apiVersion: rbac.authorization.k8s.io/v1beta1 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
Workerサーバの構築
ここではWorkerサーバを構築し、Kubernetesクラスタに参加させます。
- (workers) OS依存パッケージのインストールを行います。
sudo yum -y install socat conntrack ipset
- (workers) Workerサーバ用コンポーネントのバイナリをダウンロードし、適切な場所に配置します。
sudo yum -y install wget wget \ https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.13.0/crictl-v1.13.0-linux-amd64.tar.gz \ https://github.com/containernetworking/plugins/releases/download/v0.6.0/cni-plugins-amd64-v0.6.0.tgz \ https://github.com/opencontainers/runc/releases/download/v1.0.0-rc5/runc.amd64 \ https://github.com/containerd/containerd/releases/download/v1.2.0-rc.0/containerd-1.2.0-rc.0.linux-amd64.tar.gz \ https://storage.googleapis.com/kubernetes-release/release/v1.13.1/bin/linux/amd64/kubectl \ https://storage.googleapis.com/kubernetes-release/release/v1.13.1/bin/linux/amd64/kube-proxy \ https://storage.googleapis.com/kubernetes-release/release/v1.13.1/bin/linux/amd64/kubelet sudo mkdir -p \ /var/lib/kubelet \ /var/lib/kube-proxy \ /var/lib/kubernetes \ /var/run/kubernetes \ /etc/cni/net.d \ /opt/cni/bin sudo mv runc.amd64 runc chmod +x kubectl kube-proxy kubelet runc sudo mv kubectl kube-proxy kubelet runc /usr/local/bin/ sudo tar -xvf crictl-v1.13.0-linux-amd64.tar.gz -C /usr/local/bin/ sudo tar -xvf cni-plugins-amd64-v0.6.0.tgz -C /opt/cni/bin/ sudo tar -xvf containerd-1.2.0-rc.0.linux-amd64.tar.gz sudo mv bin/* /bin sudo rmdir bin
- (workers) CNI(Container Network Interface)のloopbackインタフェースに対する設定を実施します。
cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf { "cniVersion": "0.3.1", "type": "loopback" } EOF
- (workers) コンテナランタイム containerdの設定ファイルとsystemd unitファイルを配置します。本家Kubernetes the Hard WayではgVisorにも対応した設定を行っていますが、CentOS 7のカーネルがデフォルトでは古く、gVisorに対応していないため、省いています。
sudo mkdir -p /etc/containerd/ 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 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
- (workers) kubelet用の証明書群およびkubeconfigを配置し、設定ファイルとsystemd unitファイルを作成します。
WORKER_HOSTNAME=$(hostname -s) sudo mv ${WORKER_HOSTNAME}-key.pem ${WORKER_HOSTNAME}.pem /var/lib/kubelet/ sudo mv ${WORKER_HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig sudo mv ca.pem /var/lib/kubernetes/ 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" resolvConf: "/etc/resolv.conf" runtimeRequestTimeout: "15m" tlsCertFile: "/var/lib/kubelet/${WORKER_HOSTNAME}.pem" tlsPrivateKeyFile: "/var/lib/kubelet/${WORKER_HOSTNAME}-key.pem" EOF 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 \\ --hostname-override=${WORKER_HOSTNAME} --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
- (workers) kube-proxy用のkubeconfigを配置し、設定ファイルとsystemd unitファイルを作成します。
sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig 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: "172.17.0.0/16" EOF 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
- (workers) Workerサーバのサービスを有効化します。同時にKubernetesクラスタへWorkerサーバ登録が行われます。
sudo systemctl daemon-reload sudo systemctl enable containerd kubelet kube-proxy sudo systemctl start containerd kubelet kube-proxy
CNI flannel
とサービスディスカバリ coredns
の導入
ここでは、作業用端末のkubectlを作成したKubernetesクラスタに接続できるよう設定し、CNIとサービスディスカバリを導入して最低限、Kubernetesが機能するようにします。
- (bastion) kubectlを作成したKubernetesクラスタに接続します。
kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://kubernetes-the-hard-way.bbrfkr.mydns.jp:6443 kubectl config set-credentials admin \ --client-certificate=admin.pem \ --client-key=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
- (bastion) CNI
flannel
をデプロイします。
wget https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml sed -i 's@10.244.0.0/16@172.17.0.0/16@g' kube-flannel.yml kubectl apply -f kube-flannel.yml
- (bastion) サービスディスカバリ
coredns
をデプロイします。
kubectl apply -f https://storage.googleapis.com/kubernetes-the-hard-way/coredns.yaml