本来, 基于k8s-doc, 可以很容易架起 k8s 集群, 但因为大陆地区的网络问题, 中间遇到了很多坑, 现在记录一下. 当然了, 如果全程使用 VPN 连接到国陆互联网 的话也不存在问题.

参考:

环境

  • master 节点, 网络地址是 10.0.1.10, 安装了 debian sid
  • 工作节点, 网络地址是 10.0.1.11, 安装了 debian sid
  • kubernetes 版本是 v1.10.0
  • etcd 版本是 3.2.17
  • flannel 版本是 v0.10.0-amd64, 使用flannel 作为节点网络.

首先为Master 节点和工作节点安装服务包

安装并配置 docker

sudo apt install docker.io

接下来, 使用大陆的 docker 镜像, 具体参考 docker-cn

cat << EOF | sudo tee /etc/docker/daemon.json
{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF

然后重启一下 docker 服务:

sudo systemctl restart docker

安装 kubeadm, kubelet, kubectl

需要使用代理服务器, 比如 shadowsocks. 可以用 proxychains 做一次中转.

sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | tee | sudo apt-key add -
echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo proxychains apt-get update
sudo proxychains apt-get install -y kubelet kubeadm kubectl

配置 sysctl

需要禁用系统里的交换分区, 不然会遇到

[ERROR Swap]: running with swap on is not supported. Please disable swap

这样的错误. 参考issue#610

另外, 要允许 iptables 对网桥数据进行处理, 具体可以参考这里.

``shell cat « EOF | sudo tee /etc/sysctl.d/kubernetes.conf vm.swappiness = 0 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF

使用 `swapoff -a` 命令卸载已被挂载的交换分区, 并使用 `free -hlm` 命令确认一下.

载入配置:
```shell
sudo sysctl -p /etc/sysctl.d/kubernetes.conf

如果 br_netfilter 内核模块没有载入的话, 使用以下命令来载入:

sudo modprobe br_netfilter

修改 kubelet 启动参数.

kubelet 初始化好之后, 会拉取 gcr.io/google_containers/pause-amd64:3.1 镜像. 可以修改 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 来修改.

sudo sed -ie '/^ExecStart/s/$/ --pod-infra-container-image=mirrorgooglecontainers/pause-amd64:3.1' \
  /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

然后刷新一下 systemd:

sudo systemctl daemon-reload

配置 Master 节点

安装 docker 镜像

手动安装 docker 镜像, 不然的话需要设置代理.

sudo docker pull mirrorgooglecontainers/etcd-amd64:3.2.17
sudo docker pull mirrorgooglecontainers/kube-apiserver-amd64:v1.10.0
sudo docker pull mirrorgooglecontainers/kube-controller-manager-amd64:v1.10.0
sudo docker pull mirrorgooglecontainers/kube-proxy-amd64:v1.10.0
sudo docker pull mirrorgooglecontainers/kube-scheduler-amd64:v1.10.0

初始化集群

使用 kubeadm init 来初始化时, 默认会从 gcr.io/ 拉取 docker 镜像, 可以指定 etcd 镜像地址.

cat << EOF > kubeadm-master.conf
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
networking:
  podSubnet: 10.244.0.0/16
kubernetesVersion: v1.10.0
etcd:
  image: mirrorgooglecontainers/etcd-amd64:3.2.16
imageRepository: mirrorgooglecontainers
EOF

使用上面的配置文件来初始化:

sudo kubeadm init --config kubeadm-master.conf

如果正常的话, 会提示类似以下信息:

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join 10.0.1.10:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxx

配置 kubectl

上一步 kubeadm init 时, 结尾有提示:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

然后看一下当前的集群状态:

kubectl cluster-info

安装 flannel 网络组件

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

然后查看集群状态:

kubectl get pod --all-namespaces -o wide

里面的 Master 节点应该是 Running 状态. 如果不是, 可以看一下 kubelet 的状态以及日志:

sudo systemctl status kubelet
sudo journalctl -u kubelet

如果有必要, 可以手动拉取 flannel 的镜像:

sudo docker pull quay.io/coreos/flannel:v0.10.0-amd64

配置工作节点

安装 docker 镜像

sudo docker pull mirrorgooglecontainers/kube-proxy-amd64:v1.10.0

加入 Master 节点

在工作节点 (10.0.1.11) 上:

sudo kubeadm join 10.0.1.10:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxx

然后在 Master 节点上, 查看一下集群状态, 如果刚刚加入的工作节点也是 Running 状态, 说明它 已经被成功加到了集群里.

如果状态显示是 NotReady, 就在工作节点上, 看一下 kubelet 服务的状态:

sudo systemctl status kubelet
sudo journalctl -u kubelet

如果错误信息是 network plugin is not ready: cni config uninitialized, 可以这样:

sudo sed -ie 's/$KUBELET_NETWORK_ARGS //' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

具体可参考issue#48798