使用ClusterHAT构建世界上最小的Kubernetes集群-安装第一部分
首先
首先连接ClusterHAT,构建一个包括三个Raspberry Pi Zero的豆腐集群的服务器搭建篇,然后在豆腐集群上构建Kelsey Hightower先生的Kubernetes The Hard Way的第一部分(TLS证书篇)。接下来,我们将安装各种服务器组件。
跟上次一样,我们将按照Kelsay Hightower先生的教程顺序进行,但由于原教程在GCP上准备了6个虚拟机来进行搭建,所以我们将特别重点记录与该步骤不同的地方。上次我们完成了第6章,所以这次我们将从第7章开始。
环境
在之前的帖子中已经提及过。
最终,所有二进制文件和配置文件将被放置在控制器的以下位置:
kubernetes-key.pem
kubernetes.pem/etc/systemd/systemetcd.service
kube-apiserver.service
kube-controller-manager.service
kube-sccheduler.service/usr/local/binetcd
etcdctl
kube-apiserver
kube-controller-manager
kube-schedule
kubectl/var/lib/kubernetesca-key.pem
ca.pem
encryption-config.yaml
kubernetes-key.pem
kubernetes.pem
7. 引导etcd集群
首先安装保存集群各种状态的etcd。在教程中,我们为三个控制器分别安装etcd并进行集群化,但是在豆腐集群中,只将Pi3 B设备作为主控制器,并且本次只需在该控制器上进行安装(虽然在节点上也安装并集群化没有任何问题)。
这里更加重要。树莓派3B的CPU是64位的,但是Raspbian操作系统本身是32位的。教程中提到了安装64位版本的二进制文件,所以需要将这一步骤改为32位。不幸的是,由于Go语言对32位的限制,etcd不支持32位,因此需要自己构建。
感谢在安装Kubernetes到树莓派3上(第2部分)方面对etcd的源码安装提供的帮助。
#Goのインストール
$ wget https://storage.googleapis.com/golang/go1.10.1.linux-armv6l.tar.gz
$ tar zxf go1.10.1.linux-armv6l.tar.gz
$ sudo mv go /usr/local
$ echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc
# Gitのインストール
$ sudo apt-get install git
# etcdのインストール
$ export GOOS=linux
$ export GOARCH=arm
$ export GOARM=7
$ git clone --branch v3.3.4 https://github.com/coreos/etcd.git
$ cd etcd
$ ./build
$ sudo mv bin/* /usr/local/bin
$ sudo mkdir -p /etc/etcd /var/lib/etcd
# 第5章で生成した証明書とキーをコピーしたフォルダに移動してから実行
$ sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/
创建一个用于etcd的.service文件。首先获取主机名,然后将其定义为集群内的实例名称。
# INTERNAL_IPは直接コントローラーのIPを設定
$ INTERNAL_IP="192.168.1.100"
# ホスト名を取得。etcdクラスタ内で一意となる名前であれば良。
$ ETCD_NAME=$(hostname -s)
# etcd.serviceファイルの生成
$ cat > etcd.service <<EOF
[Unit]
Description=etcd
Documentation=https://github.com/coreos
After=network.target
[Service]
Type=notify
Restart=always
RestartSec=5s
LimitNOFILE=40000
TimeoutStartSec=0
Environment="ETCD_UNSUPPORTED_ARCH=arm"
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,http://127.0.0.1:2379 \\
--advertise-client-urls https://${INTERNAL_IP}:2379 \\
--initial-cluster-token etcd-cluster-0 \\
--initial-cluster controller=https://${INTERNAL_IP}:2380 \\
--initial-cluster-state new \\
--data-dir=/var/lib/etcd
[Install]
WantedBy=multi-user.target
EOF
本来etcd是用来注册和运营多个实例作为集群的,但这次我们首先要验证是否只使用一个实例可以工作。具体来说,我们只在initial-cluster参数中注册了一个实例(也就是控制器)的定义。如果要组建集群,只需要在这里列举即可。
另一个重要的事情是没有原始环境参数”ETCD_UNSUPPORTED_ARCH=arm”。当在不受支持的平台上运行etcd时,即使它已经针对该平台编译,也会输出警告并终止进程(警告被视为错误)。通过明确指定ETCD_UNSUPPORTED_ARCH参数,可以避免出现警告。
将服务文件移动至指定位置并启动。
$ sudo mv etcd.service /etc/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable etcd
Created symlink /etc/systemd/system/multi-user.target.wants/etcd.service → /etc/systemd/system/etcd.service.
$ sudo systemctl start etcd
# 稼働確認
$ ETCDCTL_API=3 etcdctl member list
371464a192041f5c, started, controller, https://192.168.1.100:2380, https://192.168.1.100:2379
完成了。
用引导程序引导Kubernetes控制平面
终于进入了最关键阶段。
安装各种服务
不同于etcd,Kubernetes针对ARM平台提供了二进制文件,可以获取它们。(需要注意的是,与etcd不同,构建Kubernetes需要使用make命令)基于这一点,稍作修改以校正教程中关于获取二进制文件的部分。
首先获取每个服务的二进制文件,并将其安装到控制器上。
# ARM版バイナリを取得
$ wget -q --show-progress --https-only --timestamping \
"https://storage.googleapis.com/kubernetes-release/release/v1.10.2/bin/linux/arm/kube-apiserver" \
"https://storage.googleapis.com/kubernetes-release/release/v1.10.2/bin/linux/arm/kube-controller-manager" \
"https://storage.googleapis.com/kubernetes-release/release/v1.10.2/bin/linux/arm/kube-scheduler" \
"https://storage.googleapis.com/kubernetes-release/release/v1.10.2/bin/linux/arm/kubectl"
# インストール
$ chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
$ sudo mkdir -p /var/lib/kubernetes/
$ sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
# TLS証明書&キー及び設定ファイルの設置
$ sudo mkdir -p /var/lib/kubernetes/
# 第5章及び6章で生成した証明書、キー、設定ファイルをコピーしたフォルダに移動してから実行
$ sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem encryption-config.yaml /var/lib/kubernetes/
然后生成API-Server的.service文件。
$ cat > kube-apiserver.service <<EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
--admission-control=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
--advertise-address=192.168.1.100 \\
--allow-privileged=true \\
--apiserver-count=1 \\
--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-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://192.168.1.100:2379 \\
--event-ttl=1h \\
--experimental-encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
--insecure-bind-address=127.0.0.1 \\
--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/ca-key.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
--service-node-port-range=30000-32767 \\
--tls-ca-file=/var/lib/kubernetes/ca.pem \\
--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
生成 Control Manager 的 .service 文件。
$ cat > kube-controller-manager.service <<EOF
[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 \\
--leader-elect=true \\
--master=http://127.0.0.1:8080 \\
--root-ca-file=/var/lib/kubernetes/ca.pem \\
--service-account-private-key-file=/var/lib/kubernetes/ca-key.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
接下来生成Scheduler的.service文件。
$ cat > kube-scheduler.service <<EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-scheduler \\
--leader-elect=true \\
--master=http://127.0.0.1:8080 \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
启动所有这些服务。
$ sudo mv kube-apiserver.service kube-scheduler.service kube-controller-manager.service /etc/systemd/system/
$ 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
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
只要健康检查通过,就完成了。
API-Server向Kubelet的身份认证
为了管理API服务器上的每个Pod,需要访问每个节点上配置的Kubelet。首先,需要定义用于访问Kubelet的ClusterRole。
#以下をコントローラーにて実行
$ cat <<EOF | kubectl apply -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
#以下の結果が返ってくれば成功
clusterrole "system:kube-apiserver-to-kubelet" created
需要将这个 ClusterRole 与实际的 API-Server 访问 Kubelet 时使用的用户关联起来。这个用户正如在TLS认证部分提到的证书发行章节中所述,被指定为 API-Server 的 CN,即 kubernetes。这可以通过生成 ClusterRoleBinding 来实现。
#以下をコントローラーにて実行
$ cat <<EOF | kubectl apply -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
#以下の結果が返ってくれば成功
clusterrolebinding "system:kube-apiserver" created
总的来说 / 最后
etcd的安装有点小问题,但之后进展相对顺利。(原始手册质量很高)此外,它不仅解释了Kubernetes,还解释了Linux的systemd服务定义,对于对这类事情不太熟悉的人非常有参考价值。
下次安装节点端的各种服务。