使用ClusterHAT构建世界上最小的Kubernetes集群-安装第一部分

首先

首先连接ClusterHAT,构建一个包括三个Raspberry Pi Zero的豆腐集群的服务器搭建篇,然后在豆腐集群上构建Kelsey Hightower先生的Kubernetes The Hard Way的第一部分(TLS证书篇)。接下来,我们将安装各种服务器组件。

跟上次一样,我们将按照Kelsay Hightower先生的教程顺序进行,但由于原教程在GCP上准备了6个虚拟机来进行搭建,所以我们将特别重点记录与该步骤不同的地方。上次我们完成了第6章,所以这次我们将从第7章开始。

环境

在之前的帖子中已经提及过。

最终,所有二进制文件和配置文件将被放置在控制器的以下位置:

FolderFile/etc/etcdca.pem
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服务定义,对于对这类事情不太熟悉的人非常有参考价值。

下次安装节点端的各种服务。

广告
将在 10 秒后关闭
bannerAds