在极客时间的“深入剖析 Kubernetes”专栏中,作者用的系统是 Ubuntu 16.04 LTS,安装 Kubernetes 1.11. 我读这个专栏的时候,已经有了 Ubuntu 18.04,而 Kubernetes 已经发布1.14版本了。码农在学习的过程中频繁遇到这样的问题,一般一本书出版的时候,软件已经发布了好几个新版本,书里的内容就略微过时了。但是虽然版本有更新,根基不会变得这么快,我们学习应该把重点放在靠下的原理层面,而不是新的语法、功能这些,所以好的教程、书籍仍有非常大的价值。为了跟随作者的脚步好好体验一番,我决定按文中的思路,安装1.11版本的 Kubernetes. 这里就记录一下专栏文章里没有写到的东西,以及因为软件版本引发的一些问题的解决办法。

先说明一下,我的网络稍微特殊,可以访问 k8s.gcr.io,quay.io。

准备虚拟机

先用 VirtualBox 准备两台虚拟机。实际上我是安装了一台,稍微配置一下以后 Clone 出另一台的。

我给它们各4GB内存,网卡用 bridged network 配置,这样里面的系统就可以访问公网,而且虚拟机之间、宿主机之间都可以互相访问。

安装 Ubuntu 用的是 minimal installation. 安装完成后做了下面操作,默认不启动图形界面,安装 ssh,vim 等工具:

sudo apt update
sudo apt upgrade
sudo apt install ssh vim

sudo systemctl set-default multi-user.target

两台需要分别配置 hostname:

hostnamectl set-hostname k8s[master|node].mydomain.com

安装 Kubernetes

按照文中命令下载 apt key 的时候,遇到了 SSL 相关的错误,我稍微查了一下没找到解决办法,于是在 Mac 上下载后传入了虚拟机,用 apt-key add 导入。

apt.kubernetes.io 无法访问,改成 USTC 的镜像:

deb http://mirrors.ustc.edu.cn/kubernetes/apt/ kubernetes-xenial main

安装 docker.io 和 kubeadm 的时候要注意了,因为二者都有新的版本,所以需要指定版本安装。虽然是依赖,kubelet 也需要指定这个低版本,不然会安装最新的1.14。使用命令 apt policy PACKAGE 可以查看一个软件在源中提供的所有版本号。

sudo apt install kubeadm=1.11.9-00 docker.io=18.06.1-0ubuntu1.2~18.04.1 kubelet=1.11.9-00 kubectl=1.11.9-00

kubeadm 我用了 1.11.9 这个 1.11 里最高的版本号。kubeadm preflight check 对 docker 这个版本还是会有警告,但是我决定试一下,因为 apt policy 找到的最低的版本号是 17.12,还是比 kubeadm 说的 Max validated version: 17.03 高。如果是 docker 18.09,kubeadm preflight check 会报错。

Kubernetes 要求禁用 swap:

sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

默认 docker daemon 不让普通用户连接,如果觉得不方便,把自己加到 docker 组里:

sudo usermod -a -G docker $USER

我用文章里的 kubeadm.yaml 初始化 master 的时候,发现 kubeadm 会因无法访问 dl.k8s.io 而退出。查了一下发现因为我们写的版本是 stable-1.11,它要去 https://dl.k8s.io/release/stable-1.11.txt 这个 URL 去找一个小版本列表。既然这样,那就指定一个版本:

kubernetesVersion: "v1.11.9"

k8s.gcr.io 无法访问怎么办?从镜像 pull 然后 tag:

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager-amd64:v1.11.9
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver-amd64:v1.11.9
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler-amd64:v1.11.9
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd-amd64:3.2.18
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager-amd64:v1.11.9 k8s.gcr.io/kube-controller-manager-amd64:v1.11.9
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver-amd64:v1.11.9 k8s.gcr.io/kube-apiserver-amd64:v1.11.9
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler-amd64:v1.11.9 k8s.gcr.io/kube-scheduler-amd64:v1.11.9
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd-amd64:3.2.18 k8s.gcr.io/etcd-amd64:3.2.18

# 不是 master 节点的话只需 pull 这几个 image 即可:
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.1.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy-amd64:v1.11.9
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.1.3 k8s.gcr.io/coredns:1.1.3
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy-amd64:v1.11.9 k8s.gcr.io/kube-proxy-amd64:v1.11.9
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1 k8s.gcr.io/pause:3.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1

最新的 rook 部署稍微有变动,在前面加了一条命令:

kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/common.yaml
kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/operator.yaml
kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/cluster.yaml

部署完成后,发现它现在所有的 pod 都放在同一个 namespace "rook-ceph" 中了

期间踩到的坑大概就这些。