在华为云使用 Kubeadm 搭建单 Master 集群

2019/04/26 16:54 pm posted in  Kubernetes

在优麒麟的黑客松活动中,使用了华为云的 ECS 作为实验环境载体。在前期测试中,华为云自己提供的 1.9 版本的 Kubernetes 服务,不知道是因为版本过低还是 Api Server 参数配置的缘故,无法使 Pod 内获得完全的 root 权限,导致优麒麟的镜像无法正常启动,因此采取了自建 Kube 集群的方式。

目前自建的是 1.13.2 版本的单 Master 集群,采用的工具是 Kubeadm,流程也可以参考官方文档:https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/

准备工作

创建华为云 ECS 实例若干,确保所有机器网络互通,关闭 SELinux、swap。

在所有的机器中安装依赖:

Docker

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

kubeadm 和 kubelet

首先添加国内源(注意这个 apt key 需要科学上网才能拿到)

apt-get update && apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF > /etc/apt/sources.list.d/kubernetes.list
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main
EOF
apt-get update

apt-get install kubelet=1.13.2-00 kubeadm=1.13.2-00 -y

查看 Kube 组件依赖的镜像

# kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.13.2
k8s.gcr.io/kube-controller-manager:v1.13.2
k8s.gcr.io/kube-scheduler:v1.13.2
k8s.gcr.io/kube-proxy:v1.13.2
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:3.2.24
k8s.gcr.io/coredns:1.2.6

k8s.gcr.io 在国内是无法访问的,可以曲线救国 pull 好并缓存在机器上。

CoreDNS 的镜像可以在 DockerHub 中拉取:

docker pull coredns/coredns:1.2.6
docker tag coredns/coredns:1.2.6 k8s.gcr.io/coredns:1.2.6

剩余的镜像在 DaoCloud 可以拉取到:

# docker images | grep gcr-mirror
daocloud.io/gcr-mirror/kube-controller-manager-amd64   v1.13.2             b9027a78d94c        3 months ago        146MB
daocloud.io/gcr-mirror/kube-proxy-amd64                v1.13.2             01cfa56edcfc        3 months ago        80.3MB
daocloud.io/gcr-mirror/kube-apiserver-amd64            v1.13.2             177db4b8e93a        3 months ago        181MB
daocloud.io/gcr-mirror/kube-scheduler-amd64            v1.13.2             3193be46e0b3        3 months ago        79.6MB
daocloud.io/gcr-mirror/etcd-amd64                      3.2.24              3cab8e1b9802        7 months ago        220MB
daocloud.io/gcr-mirror/kubernetes-dashboard-amd64      v1.8.3              0c60bcf89900        14 months ago       102MB
daocloud.io/gcr-mirror/pause-amd64                     3.1                 da86e6ba6ca1        16 months ago       742kB

修改 kubelet 的配置

首先是确定 docker 的 Cgroup Driver,如果不是 systemd,则需要修改 kubelet 的配置。

# docker info | grep -i cgroup
Cgroup Driver: cgroupfs

第二是因为优麒麟镜像需要特权执行,因此需要添加允许 Pod 使用特权的 flag 参数。综上,修改 kubelet 的配置文件:

# cat /etc/default/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=cgroupfs --allow-privileged=true"

启动和配置集群

创建 master 节点(xxx.xxx.xxx.xxx,为该节点外网 ip,以支持外网访问):

kubeadm init  --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=0.0.0.0 --apiserver-cert-extra-sans=xxx.xxx.xxx.xxx

init 完成后可以根据指示配置 kubeconfig,然后就可以在当前机器使用 kbuectl 控制集群了。

因为 init 时在证书里包含了外网地址,将 kubeconfig 下载到本地,并修改其中的 api server 地址为外网 ip 可以在本地访问该集群。

配置网络插件,因为目前没有需求使用网络隔离,因此使用了坑少的 flannel:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

配置 Node 节点,可以用个 kubeadm 来生成 bootstrap token 以接入 node:

# kubeadm token create --print-join-command
kubeadm join 192.168.0.165:6443 --token eu6d1j.zax8lj1sfhy***** --discovery-token-ca-cert-hash sha256:6d29f0a87379711da7012c7b3f1e50af4eb32186e92a4e2fd89c58e30bd*****

直接在 node 执行稍等片刻便可接入。

踩坑

华为云的 DNS 配置有些奇怪,/etc/resolv.conf 中的 DNS 为 127.0.0.1,因此导致集群中的 CoreDNS 异常:CoreDNS 将主机中 /etc/resolv.conf 的 DNS 作为上游服务器,如果是 127.0.0.1,发生了循环。

[FATAL] plugin/loop: Seen "HINFO IN 8205794187887631643.5216586587165434789." more than twice, loop detected

讨论:https://github.com/coredns/coredns/issues/1986

集群中的 Pod 默认使用 CoreDNS 作为 DNS 服务器,因此现象是网络连接不正常(打不开网页,但是直接访问 ip 是正常的)。目前解决方式是在 CoreDNS 的 ConfigMap 中手动指定 114.114.114.114 作为上游服务器(也可以直接修改 /etc/resolv.conf)。

其他基础设施