この記事では、CoreOSクラスタ上にKubernetesを設定する方法を紹介します。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
#前提条件と目標
まずは基本的なCoreOSクラスタから始めましょう。Alibaba Cloudはすでに設定可能なクラスタを提供しているので、詳細についてはあまり触れないことにします。クラスタに必要なのは、少なくともマスターノードとワーカーノードです。ノードには、Kubernetesの中で専門的な役割を割り当てることにしますが、参考までに、これらのノードは互換性があります。ノードの1つであるマスターは、コントロールマネージャとAPIサーバを実行します。
このチュートリアルでは、CoreOSのWebサイトで公開されている実装ガイドを参考にしました。CoreOS クラスタがすべてセットアップされた状態で、次に進んでみましょう。ここでは、2つのサンプル BareMetal ノードを使用します。
#マスターノード
ノード1をマスターとします。CoreOSノードのSSHから始めます。
certsというディレクトリを作成します。
$ mkdir certs
$ cd certs
cert_generator.sh
としてcertsディレクトリに以下のスクリプトを貼り付けます。
#!/bin/bash
# Creating TLS certs
echo "Creating CA ROOT**********************************************************************"
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"
echo "creating API Server certs*************************************************************"
echo "Enter Master Node IP address:"
read master_Ip
cat >openssl.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 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
IP.1 = 10.3.0.1
IP.2 = $master_Ip
EOF
openssl genrsa -out apiserver-key.pem 2048
openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config openssl.cnf
openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile openssl.cnf
echo "Creating worker nodes"
cat > worker-openssl.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]
IP.1 = \$ENV::WORKER_IP
EOF
echo "Enter the number of worker nodes:"
read worker_node_num
for (( c=1; c<= $worker_node_num; c++ ))
do
echo "Enter the IP Address for the worker node_$c :"
read ip
openssl genrsa -out kube-$c-worker-key.pem 2048
WORKER_IP=$ip openssl req -new -key kube-$c-worker-key.pem -out kube-$c-worker.csr -subj "/CN=kube-$c" -config worker-openssl.cnf
WORKER_IP=$ip openssl x509 -req -in kube-$c-worker.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out kube-$c-worker.pem -days 365 -extensions v3_req -extfile worker-openssl.cnf
done
echo "Creating Admin certs********************************************************"
openssl genrsa -out admin-key.pem 2048
openssl req -new -key admin-key.pem -out admin.csr -subj "/CN=kube-admin"
openssl x509 -req -in admin.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out admin.pem -days 365
echo "DONE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
実行可能なスクリプトを設定します。
$ chmod +x cert_generator.sh
実行スクリプトが実行されると、ノードの詳細を入力するように促されるはずです。その後、Kubernetesのインストール上で実行するための証明書を生成します。
以下のように生成された鍵を作成するディレクトリを作成します。
$ mkdir -p /etc/kubernetes/ssl
certsから以下のcertsを/etc/kubernetes/ssl
にコピーします。
/etc/kubernetes/ssl/ca.pem
/etc/kubernetes/ssl/apiserver.pem
/etc/kubernetes/ssl/apiserver-key.pem
#ネットワーク構成
次に、/etc/flannel/options.envにflannelのローカル設定を取得し、etcdにクラスタレベルの設定をソースとして取得するように設定してみましょう。以下の内容を含むスクリプトを作成し、以下の点に注意してください。
1、${ADVERTISE_IP}
をマシンのパブリックIPに置き換えてください。
2、${ETCD_ENDPOINTS}
を置き換えてください。
FLANNELD_IFACE=${ADVERTISE_IP}
FLANNELD_ETCD_ENDPOINTS=${ETCD_ENDPOINTS}
次に、flannel起動時に上記の設定を含むドロップインを以下のように作成します。
/etc/systemd/system/flanneld.service.d/40-ExecStartPre-symlink.conf
[Service]
ExecStartPre=/usr/bin/ln -sf /etc/flannel/options.env /run/flannel/options.env
#Dockerの設定
クラスタのポッドネットワークを管理するために、flannelにDockerを設定しておく必要があります。Dockerが起動する前にflannelが実行されることを要求する必要があります。systemdのドロップイン、/etc/systemd/system/docker.service.d/40-flannel.conf
を適用してみましょう。
[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env
Docker CNI Optionsファイルを起動し、etc/kubernetes/cni/docker_opts_cni.en
DOCKER_OPT_BIP=""
DOCKER_OPT_IPMASQ=""
flannelネットワークを使用している場合は、以下のコマンドでflannel CNIの設定を行います。
/etc/kubernetes/cni/net.d/10-flannel.conf
{
"name": "podnet",
"type": "flannel",
"delegate": {
"isDefaultGateway": true
}
}
Kubeletユニットの作成
Kubelet はポッドの起動と停止、その他のマシンレベルのタスクを担当します。先ほどインストールしたTLS証明書を使って、マスターノード上で動作するAPIサーバと通信します。
etc/systemd/system/kubelet.service
を作成します。
1、${ADVERTISE_IP}
をこのノードのパブリックIPに置き換えてください。
2、${DNS_SERVICE_IP}
を10.3.0.10
に置き換えてください。
[Service]
Environment=KUBELET_VERSION=v1.5.1_coreos.0
Environment="RKT_OPTS=--uuid-file-save=/var/run/kubelet-pod.uuid \
--volume var-log,kind=host,source=/var/log \
--mount volume=var-log,target=/var/log \
--volume dns,kind=host,source=/etc/resolv.conf \
--mount volume=dns,target=/etc/resolv.conf"
ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
ExecStartPre=/usr/bin/mkdir -p /var/log/containers
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/run/kubelet-pod.uuid
ExecStart=/usr/lib/coreos/kubelet-wrapper \
--api-servers=http://127.0.0.1:8080 \
--register-schedulable=false \
--cni-conf-dir=/etc/kubernetes/cni/net.d \
--network-plugin=cni \
--container-runtime=docker \
--allow-privileged=true \
--pod-manifest-path=/etc/kubernetes/manifests \
--hostname-override=${ADVERTISE_IP} \
--cluster_dns=${DNS_SERVICE_IP} \
--cluster_domain=cluster.local
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/run/kubelet-pod.uuid
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
###kube-apiserverポッドのセットアップ
API サーバーはワークロードの多くを処理し、ほとんどのアクティビティが行われます。API サーバーはステートレスで、リクエストを処理し、フィードバックを提供し、必要に応じて結果を etcd に保存します。
etc/kubernetes/manifests/kube-apiserver.yaml
を作成します。
1、 ${ETCD_ENDPOINTS}
をCoreOSホストに置き換えてください。
2、${SERVICE_IP_RANGE}
を10.3.0.0.0/24
に置き換えてください。
3、${ADVERTISE_IP}
をこのノードのパブリックIPに置き換えてください。
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
hostNetwork: true
containers:
- name: kube-apiserver
image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
command:
- /hyperkube
- apiserver
- --bind-address=0.0.0.0
- --etcd-servers=${ETCD_ENDPOINTS}
- --allow-privileged=true
- --service-cluster-ip-range=${SERVICE_IP_RANGE}
- --secure-port=443
- --advertise-address=${ADVERTISE_IP}
- --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota
- --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem
- --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
- --client-ca-file=/etc/kubernetes/ssl/ca.pem
- --service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem
- --runtime-config=extensions/v1beta1/networkpolicies=true
- --anonymous-auth=false
livenessProbe:
httpGet:
host: 127.0.0.1
port: 8080
path: /healthz
initialDelaySeconds: 15
timeoutSeconds: 15
ports:
- containerPort: 443
hostPort: 443
name: https
- containerPort: 8080
hostPort: 8080
name: local
volumeMounts:
- mountPath: /etc/kubernetes/ssl
name: ssl-certs-kubernetes
readOnly: true
- mountPath: /etc/ssl/certs
name: ssl-certs-host
readOnly: true
volumes:
- hostPath:
path: /etc/kubernetes/ssl
name: ssl-certs-kubernetes
- hostPath:
path: /usr/share/ca-certificates
name: ssl-certs-host
###kube-proxy Podのセットアップ
API サーバで行ったように、サービスやポッドへのトラフィックの誘導を担当するプロキシを実行します。プロキシはAPIサーバと定期的に通信を行うことで最新の情報を提供します。プロキシはクラスタ内のマスターノードとワーカーノードの両方をサポートしています。
設定は必要なく、/etc/kubernetes/manifests/kube-proxy.yaml
を作成することから始めます。
apiVersion: v1
kind: Pod
metadata:
name: kube-proxy
namespace: kube-system
spec:
hostNetwork: true
containers:
- name: kube-proxy
image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
command:
- /hyperkube
- proxy
- --master=http://127.0.0.1:8080
securityContext:
privileged: true
volumeMounts:
- mountPath: /etc/ssl/certs
name: ssl-certs-host
readOnly: true
volumes:
- hostPath:
path: /usr/share/ca-certificates
name: ssl-certs-host
###kube-controller-manager Podのセットアップ
ディスク内のTLS証明書を使用する/etc/kubernetes/manifests/kube-controller-manager.yaml
を作成します。
apiVersion: v1
kind: Pod
metadata:
name: kube-controller-manager
namespace: kube-system
spec:
hostNetwork: true
containers:
- name: kube-controller-manager
image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
command:
- /hyperkube
- controller-manager
- --master=http://127.0.0.1:8080
- --leader-elect=true
- --service-account-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
- --root-ca-file=/etc/kubernetes/ssl/ca.pem
resources:
requests:
cpu: 200m
livenessProbe:
httpGet:
host: 127.0.0.1
path: /healthz
port: 10252
initialDelaySeconds: 15
timeoutSeconds: 15
volumeMounts:
- mountPath: /etc/kubernetes/ssl
name: ssl-certs-kubernetes
readOnly: true
- mountPath: /etc/ssl/certs
name: ssl-certs-host
readOnly: true
hostNetwork: true
volumes:
- hostPath:
path: /etc/kubernetes/ssl
name: ssl-certs-kubernetes
- hostPath:
path: /usr/share/ca-certificates
name: ssl-certs-host
###kube-cheduler Podのセットアップ
次に、スケジューラを設定して、APIの予定外のポッドを追跡してマシンを割り当て、その決定をAPに更新します。
etc/kubernetes/manifests/kube-scheduler.yaml File
を作成します。
apiVersion: v1
kind: Pod
metadata:
name: kube-scheduler
namespace: kube-system
spec:
hostNetwork: true
containers:
- name: kube-scheduler
image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
command:
- /hyperkube
- scheduler
- --master=http://127.0.0.1:8080
- --leader-elect=true
resources:
requests:
cpu: 100m
livenessProbe:
httpGet:
host: 127.0.0.1
path: /healthz
port: 10251
initialDelaySeconds: 15
timeoutSeconds: 15
###変化されたユニットを読み込む
このように実装した変更点をすべて再スキャンするようにシステムに指示してみましょう。
$ sudo systemctl daemon-reload
###Flannelネットワークの設定
etcd がFlannelのクラスタレベルの設定を保存していることはすでに述べました。したがって、ポッドネットワークのIP範囲を設定しておきましょう。etccd はすでに起動しているので、今が設定するのに適したタイミングです。あるいは、etcd を起動して
1、$POD_NETWORK
の代わりに 10.2.0.0/16
を配置します。
2、$ETCD_SERVER
の代わりに、$ETCD_ENDPOINTS
の url (http://ip:port)
を配置します。
$ curl -X PUT -d "value={\"Network\":\"$POD_NETWORK\",\"Backend\":{\"Type\":\"vxlan\"}}" "$ETCD_SERVER/v2/keys/coreos.com/network/config"
変更を有効にするためにflannelを再起動します。これはひいては docker デーモンを再起動し、コンテナの実行に影響を与える可能性があります。
$ sudo systemctl start flanneld
$ sudo systemctl enable flanneld
###Kubeletを起動
これですべての設定が完了し、kubeletを起動する準備が整いました。また、コントローラ、スケジューラ、プロキシ、Pod APIサーバのマニフェストも立ち上げて実行します。
$ sudo systemctl start kubelet
再起動後にkubeletが起動することを確認してください。
$ sudo systemctl enable kubelet
#ワーカーノード
ワーカーノードの場合は、まずディレクトリを作成し、ワーカーノードに生成したSSLキーを配置します。
$ mkdir -p /etc/kubernetes/ssl
certsから**/etc/kubernetes/ssl**に貼り付けます。
/etc/kubernetes/ssl/ca.pem
/etc/kubernetes/ssl/kube-1-worker-apiserver.pem
/etc/kubernetes/ssl/kube-1-worker-apiserver-key.pem
#ネットワーク構成
以前に行ったように、flannelのローカル設定は /etc/flannel/options.env
から取得し、etcd はクラスタレベルの設定を格納します。このファイルを複製し、必要な調整を行ってください。
1、${ADVERTISE_IP}
の代わりにマシンのパブリックIPに置き換えてください。
2、${ETCD_ENDPOINTS}
を置き換えてください。
FLANNELD_IFACE=${ADVERTISE_IP}
FLANNELD_ETCD_ENDPOINTS=${ETCD_ENDPOINTS}
flannel再起動で上記の構成を使用するためのドロップインを作成します。/etc/systemd/system/flanneld.service.d/40-ExecStartPre-symlink.conf
[Service].
ExecStartPre=/usr/bin/ln -sf /etc/flannel/options.env /run/flannel/options.env
#Dockerの設定
次に、Dockerがクラスタのポッドネットワークを管理するためにflannelを使用するように設定します。方法は上で行った実装と同様で、Dockerが起動する前にflannelを起動する必要があります。
ここでは、/etc/systemd/system/docker.service.d/40-flannel.conf
という systemd drop-inを適用してみます。
[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env
etc/kubernetes/cni/docker_opts_cni.env
のようにDocker CNI Optionsファイルを起動します。
DOCKER_OPT_BIP=""
DOCKER_OPT_IPMASQ=""
Flannel ネットワークに依存している場合は、以下のように Flannel CNI の設定を行います。/etc/kubernetes/cni/net.d/10-flannel.conf
{
"name": "podnet",
"type": "flannel",
"delegate": {
"isDefaultGateway": true
}
}
#Kubeletユニットの作成
ワーカーノードでは、以下のようなkubeletサービスを作成してみましょう。
etc/systemd/system/kubelet.service
を作成します。
1、${ADVERTISE_IP}をノードのパブリックIPに置き換える。
2、${DNS_SERVICE_IP}を10.3.0.10に置き換えてください。
3、${MASTER_HOST}を置き換えてください。
Environment=KUBELET_VERSION=v1.5.1_coreos.0
Environment="RKT_OPTS=--uuid-file-save=/var/run/kubelet-pod.uuid \
--volume dns,kind=host,source=/etc/resolv.conf \
--mount volume=dns,target=/etc/resolv.conf \
--volume var-log,kind=host,source=/var/log \
--mount volume=var-log,target=/var/log"
ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
ExecStartPre=/usr/bin/mkdir -p /var/log/containers
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/run/kubelet-pod.uuid
ExecStart=/usr/lib/coreos/kubelet-wrapper \
--api-servers=${MASTER_HOST} \
--cni-conf-dir=/etc/kubernetes/cni/net.d \
--network-plugin=cni \
--container-runtime=docker \
--register-node=true \
--allow-privileged=true \
--pod-manifest-path=/etc/kubernetes/manifests \
--hostname-override=${ADVERTISE_IP} \
--cluster_dns=${DNS_SERVICE_IP} \
--cluster_domain=cluster.local \
--kubeconfig=/etc/kubernetes/worker-kubeconfig.yaml \
--tls-cert-file=/etc/kubernetes/ssl/worker.pem \
--tls-private-key-file=/etc/kubernetes/ssl/worker-key.pem
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/run/kubelet-pod.uuid
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
###kube-proxy Podの設定
etc/kubernetes/manifests/kube-proxy.yaml
ファイルを作成します。
apiVersion: v1
kind: Pod
metadata:
name: kube-proxy
namespace: kube-system
spec:
hostNetwork: true
containers:
- name: kube-proxy
image: quay.io/coreos/hyperkube:v1.5.1_coreos.0
command:
- /hyperkube
- proxy
- --master=${MASTER_HOST}
- --kubeconfig=/etc/kubernetes/worker-kubeconfig.yaml
securityContext:
privileged: true
volumeMounts:
- mountPath: /etc/ssl/certs
name: "ssl-certs"
- mountPath: /etc/kubernetes/worker-kubeconfig.yaml
name: "kubeconfig"
readOnly: true
- mountPath: /etc/kubernetes/ssl
name: "etc-kube-ssl"
readOnly: true
volumes:
- name: "ssl-certs"
hostPath:
path: "/usr/share/ca-certificates"
- name: "kubeconfig"
hostPath:
path: "/etc/kubernetes/worker-kubeconfig.yaml"
- name: "etc-kube-ssl"
hostPath:
path: "/etc/kubernetes/ssl"
###Kubeconfigの設定
Kubernetesコンポーネントが安全に通信するためには、認証設定の定義にkubeconfigを使用します。今回のユースケースでは、kubeletとproxyが読み込んだ設定により、それらがAPIと通信できるようにします。
まずファイルを作成します。/etc/kubernetes/worker-kubeconfig.yaml
を作成します。
/etc/kubernetes/worker-kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- name: local
cluster:
certificate-authority: /etc/kubernetes/ssl/ca.pem
users:
- name: kubelet
user:
client-certificate: /etc/kubernetes/ssl/worker.pem
client-key: /etc/kubernetes/ssl/worker-key.pem
contexts:
- context:
cluster: local
user: kubelet
name: kubelet-context
current-context: kubelet-context
###サービスの開始
ワーカーサービスの開始準備が整いました。
###変更した内容の読み込み
このように変更した内容を更新するためにディスクを再スキャンするようにシステムに指示してみましょう。
$ sudo systemctl daemon-reload
###kubeletとflannelを起動する
kubeletを起動して、プロキシを起動します。
$ sudo systemctl start flanneld
$ sudo systemctl start kubelet
各ブート時にサービスの起動を強制します。
$ sudo systemctl enable flanneld
Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to /etc/systemd/system/flanneld.service.
$ sudo systemctl enable kubelet
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /etc/systemd/system/kubelet.service.
To check the health of the kubelet systemd unit that we created, run systemctl status kubelet.service.
#結論
ここまで読んでくださった方、おめでとうございます。KubernetesをCoreOSクラスタ上で実行するように簡単に設定することができます。Kubernetesの詳細については、このチュートリアルの他の記事を参照してください。注意点として、このチュートリアルでは、特にIPアドレスを正しく変更して、クラスタ上で動作させるようにしてください。お疲れ様でした。
Alibaba Cloudのアカウントをお持ちですか?アカウントにサインアップして、40以上の製品を無料でお試しください。詳細については、Alibaba Cloudの利用を開始するを参照してください。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ