在优麒麟的黑客松活动中,使用了华为云的 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
)。
其他基础设施
- Kubernetes 的 Web 界面(Dashboard):https://github.com/kubernetes/dashboard/wiki/Installation
- 资源监控(metrics-server):https://github.com/kubernetes-incubator/metrics-server