#kubeadm #kubernetes #集群 #golang #etcd

使用 kubeadm 搭建自己的 kubernetes 集群

简介

kubernetes 是一款非常优秀的容器编排工具,可以管理你所有节点上的运行的 docker 容器。并且可以非常方便横向扩展、服务转移、服务升级。自从用上了 k8s 集群,再也不用担心服务单点啦~

背景

前段时间刚入了 3 台服务器,都是 2核8G5M 的,近期想着要么搭建一个集群吧,正好可以体验下 kubernetes, 玩了这么多年的 Docker 都一起没有把编排工具用起来。趁这个机会实现下自己的心愿吧,以后上服务什么的也可以简化点。

有了这个想法,找了个没有阳光的午后,就开始了这次搭建的旅程。

由于 3 台服务器是通过不同账号买的,还有一台是腾讯的,所以用内网组集群是没有希望了,只能用公网来搭建。

这其中就碰到了许多的问题,请让我慢慢道来。

开始

服务器都到位了,就可以开始这次搭建的旅程了。先看下基本信息

三台服务器都是 CentOS 7.4 的,当然系统环境并不能影响我们安装 kubernetes 的脚步。

先看下基本的节点信息。
主机名称 IP

master	123.123.123.123
node01	123.123.123.124
node02	123.123.123.125

注意 : 这里对节点名有个要求,所有节点不能重名,kubernetes
会以此名字来唯一标识这个节点。按理我们也不会设置重复的主机名。

所有节点的 Docker 版本:docker-ce 18.09.0
还没有安装 docker ? 这个可能可以提供点帮助
docker 安装完之后,最好配置下镜像加速,加速下载镜像的速度。
可以看这文章的前半部分设置使用重新打 tag 的方式,拉取 k8s.gcr.io 的镜像

kubeadm 是官方提供的安装集群搭建工具,使用此工具可以大大简化搭建的流程。

因为我用的是外网,不方便直接写出来,所以我把我记录的步骤中的所有 IP 都换成了假的,仅仅是 IP 换了,基本的都是我实际的操作过程。

正式开始操作服务器

阿里云的机器忽略,腾讯云的机器需要关闭防火墙。

$ systemctl stop firewalld
$ systemctl disable firewalld

关闭 selinux

selinux(Security Enhance Linux): 安全加强的Linux, 安全性加强的同时,对于操作性就降低很多,因为对新用户不太友好,所以不了解的朋友可以选择关闭它。

$ vim /etc/sysconfig/selinux

SELINUX 中的对应的配置改为 SELINUX=disabled

临时关闭 SELINUX

$ setenforce 0

两个操作合一起之后,当你重启的时候 SELINUX 依然是关闭的状态。

关闭 Swap 内存, 交换分区 Swap 就不要使用了,毕竟集群还是要稳定性为主的

$ swapoff -a

修改 linux 内核参数,阿里云的机器忽略。腾讯云的机器需要执行这一步,否则后面加入集群的时候会报这个错。

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

修改完之后执行, 查看配置是否生效

$ sysctl --system

配置好所有的基本工作,下面开始安装 kubectl kubeadm kubelet

  • kubectl : Kubectl 这个命令主要用来管理 Kubernetes 集群。
  • kubeadm : 搭建本集群所需要的命令
  • kubelet : kubelet 会在每个节点启动,来处理来自 Master 节点下发到本节点的任务。管理Pod和其中的容器
    kubelet会在API Server上注册节点信息,定期向Master汇报节点资源使用情况,kubelet不管理不是由Kubernetes创建的容器。

配置 kubectl kubeadm kubelet 三个软件的镜像源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

注意 : 如果你的服务器和我一样,是国内的话除香港台湾地区
很可能是访问不了 google 的, 需要使用代理才能安装这三个软件
可以参照我之前的文章进行配置 在 linux 服务器命令行中使用代理服务

开始安装,并启动 kubelet

$ yum install -y kubectl kubeadm kubelet
$ systemctl enable kubelet
$ systemctl start kubelet

说明
kubectl 是命令行工具,所以不用启动
kubeadm 是集群搭建工具,也不用启动
kubelet 是节点管理工具,需要在所有节点启动

注意 : 以上所有教程,都需要在三台机子上操作,包括安装 kubectl kubeadm kubelet,启动 kubelet

在所有机子上成功操作以上命令后,下面开始初始化主节点

在主节点上执行以下命令

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

注意
如果此条命令一直卡着,或者过了一段时间后报拉取镜像超时的问题
那么,你可以设置一下 docker 的代理,使用代理来拉取镜像。
当然你也可以使用重新 tag 的方式来拉取镜像。
参考: 使用重新打 tag 的方式,拉取 k8s.gcr.io 的镜像
当然,如果你用的和我版本一致,可以直接拉取我的镜像,或者看看有没有其它人有作了同步。

解释

  • kubeadm init : 为初始化命令
  • --pod-network-cidr=10.244.0.0/16 : 指定 pod 网络的 IP 地址范围。如果设置,控制平面将自动为每个节点分配 CIDRs
  • --apiserver-cert-extra-sans 123.123.123.123 : 设置了这个,之后加入节点验证证书阶段就不会报错了。 用于API服务器服务证书的可选额外主题替代名称(SANs)。可以是 IP 地址和 DNS 名称。
  • --apiserver-advertise-address 123.123.123.123 : 把这个设置为外网 IP 按理说可以实现公网组集群
    可是我试了很多次都没有初始化成功,一直显示 ETCD启动不了,我猜可能是因为我机子上的公网并没有绑定在我服务器的网卡上,导致并不能 ETCD 不能监听在些 IP上于是我把这一条配置去掉了,后面我用了其它方法来加入集群。
    API 服务器将通知它正在监听的IP地址。指定 0.0.0.0 来使用默认网络接口的地址。

不出意外的话,你可能会看到如下的输出:

# 这之前的就忽略吧
...
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

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 192.168.0.1:6443 --token 1fmns7.rgtgtpmkxskfagck --discovery-token-ca-cert-hash sha256:d8e62583fc2b88cb9f866a1b35e279a8668e13537404c837f14f2c6cda037674

这里需要你去执行, 可能你的输出和我不一致,请复制你自己的

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

安装 pod 网络附加组件 flannel

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

最后,你可以看到一行加入集群的命令:

$ kubeadm join 192.168.0.1:6443 --token 1fmns7.rgtgtpmkxskfagck --discovery-token-ca-cert-hash sha256:d8e62583fc2b88cb9f866a1b35e279a8668e13537404c837f14f2c6cda037674

注意 在所有从节点也需要以下镜像,如果本地网络环境有限制,需要预先拉取,以保证加入集群成功。

  • k8s.gcr.io/pause:3.1
  • quay.io/coreos/flannel:v0.10.0-amd64
  • k8s.gcr.io/kube-proxy:v1.13.1

以上镜像可以和之前拉取的方式相同

只要在其它两个节点上执行这一命令,你就可以把执行的服务器那台服务加入集群了。

查看主节点信息 kubectl get pods --all-namespaces

[root@master ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                                    READY   STATUS             RESTARTS   AGE
kube-system   coredns-86c58d9df4-4gs57                1/1     Running             0          1h
kube-system   coredns-86c58d9df4-7g5kx                1/1     Running             0          1h
kube-system   etcd-master                             1/1     Running             0          1h
kube-system   kube-apiserver-master                   1/1     Running             0          1h
kube-system   kube-controller-manager-master          1/1     Running             2          1h
kube-system   kube-flannel-ds-amd64-c69hl             1/1     Running             0          1h
kube-system   kube-flannel-ds-amd64-nq7s5             1/1     Running             0          1h
kube-system   kube-flannel-ds-amd64-xg7ct             1/1     Running             0          1h
kube-system   kube-proxy-n27rj                        1/1     Running             0          1h
kube-system   kube-proxy-tj2xj                        1/1     Running             0          1h
kube-system   kube-proxy-zx7d8                        1/1     Running             0          1h
kube-system   kube-scheduler-master                   1/1     Running             1          1h

以上输出解释

如果显示 READY 状态全为 1/1 那表示已经完成集群搭建。

如果出现 0/1 的情况,可以使用以下命令查看是由于哪些原因报的错。

$ kubectl describe pod kube-flannel-ds-amd64-c69hl --namespace kube-system

其中 kube-flannel-ds-amd64-c69hl 为上面 pod 的名字,加上 --namespace kube-system 确保系统的 pod 也能显示

注意
因为我在初始化阶段去掉了 --apiserver-advertise-address 123.123.123.123 这个配置,所以当前加入集群的命令给我展示了内网的 IP 192.168.0.1:6443
由于我 3 台机子是不互通的,于是我只能在其它机器上用 iptables 作了 IP 转发
具体可参考文章: 使用 iptables 将 IP 重定向
这样,我也成功得加入到集群了。如果有什么好的方法,请和我也说说。

在每个节点执行,如果内网不通,可参照上面注意部分

$ kubeadm join 192.168.0.1:6443 --token 1fmns7.rgtgtpmkxskfagck --discovery-token-ca-cert-hash sha256:d8e62583fc2b88cb9f866a1b35e279a8668e13537404c837f14f2c6cda037674

上面命令执行成功后,你就完成了集群的搭建工作了。

不过,如果由于其它原因,或者想再搭建一次,可以执行 reset 操作,重置所有配置,恢复到刚安装好 kubectl kubeadm kubelet 的状态,再来一次。我就执行了这个命令不下 20 次

$ kubeadm reset

此命令会把所有启动的镜像全部删除,还会删除一些生成的配置文件。但是都是执行 init 生成的,所以删了也没有关系。

节点加入集群完成后,在主节点通过 kubectl get nodes 查看节点信息

[root@master ~]# kubectl get nodes
NAME     STATUS     ROLES    AGE  VERSION
node01   Ready   	<none>   1h   v1.13.0
node02   Ready   	<none>   1h   v1.13.0
master   Ready      master   1h   v1.13.0
[root@master ~]#

小结

到这里,你已经搭建好了集群。下一步,就可以尽情得玩耍了。

对于我,我则想先从下面三个方向入手。

  • Web UI (Dashboard) : kubernetes 的管理面板
  • Kubernetes Ingress Controller : Kubernetes + Traefik
  • 监控 : Grafana + Prometheus 监控 Kubernetes 及集群内其它服务

主要从上面三个点来玩 Kubernetes 加油~

Author Mo 最后更新: 2019-06-03 23:16:47