利用Kubeadm搭建Kubernetes集群

在搭建环境之前,我们来看一张更丰富的k8s的架构图:

img

img

  • 核心层:Kubernetes 最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态 Provision 等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy 等)
  • 接口层:kubectl 命令行工具、客户端 SDK 以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴 Kubernetes 外部:日志、监控、配置管理、CI、CD、Workflow等 Kubernetes 内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等。

在更进一步了解了k8s集群的架构后,我们就可以来正式的安装我们的k8s集群环境了,我们这里使用的是kubeadm工具来进行集群的搭建。

1、kubeadm

kubeadm是Kubernetes官方提供的用于快速安装 Kubernetes 集群的工具,通过将集群的各个组件进行容器化安装管理,通过kubeadm的方式安装集群比二进制的方式安装要方便不少。它提供了 kubeadm init 以及 kubeadm join 这两个命令作为快速创建 kubernetes 集群的最佳实践。kubeadm 通过执行必要的操作来启动和运行一个最小可用的集群。它被故意设计为只关心启动集群,而不是准备节点环境的工作。同样的,诸如安装各种各样的可有可无的插件,例如 Kubernetes 控制面板、监控解决方案以及特定云提供商的插件,这些都不在它负责的范围。正式Kubernetes环境这里还是建议通过二进制的方式进行安装。

2、基础环境

这里我们准备三台Centos7的主机用于安装,后续节点可以根据需要添加即可。

Master:172.16.200.1

Node01:172.16.200.2

Node02:172.16.200.3

img

img

禁用防火墙

systemctl stop firewalld
systemctl disable firewalld

禁用Selinux

setenforce 0 
# cat /etc/selinux/config 
SELINUX=disabled

创建/etc/sysctl.d/k8s.conf文件(开启路由转发):

net.bridge.bridge-nf-call-ip6tables = 1 
net.bridge.bridge-nf-call-iptables = 1 
net.ipv4.ip_forward = 1

执行如下命令使修改生效:

# modprobe br_netfilter 
# sysctl -p /etc/sysctl.d/k8s.conf

3、镜像拉取

在安装Kubeadm之前、我们先把Master节点需要使用的节点提前下载好。因为Kubeadm默认会去Google的镜像站下载镜像,如果节点不能正常访问Google就会安装失败(当然,如果你有科学上网工具、这里就可以忽略啦!)。我们需要提前将所需的gcr.io上面的镜像下载到节点上面,当然前提条件是你已经成功安装了docker。

Master节点,执行下面的命令(这里我是在hub.docker.com上googlecontainersmirrors镜像仓库查找的相应版本,如果下载失败可以到hub上自己去搜索并下载):

docker pull googlecontainersmirrors/kube-apiserver-amd64:v1.17.3
docker pull googlecontainersmirrors/kube-scheduler-amd64:v1.17.3
docker pull googlecontainersmirrors/kube-controller-manager-amd64:v1.17.3
docker pull googlecontainersmirrors/kube-proxy-amd64:v1.17.3
docker pull googlecontainersmirrors/k8s-dns-kube-dns-amd64:1.14.8
docker pull googlecontainersmirrors/k8s-dns-dnsmasq-nanny-amd64:1.14.8
docker pull googlecontainersmirrors/k8s-dns-sidecar-amd64:1.14.8
docker pull azhu/etcd:3.4.3-0
docker pull tkestack/flannel-amd64:v0.11.0
docker pull googlecontainersmirrors/pause-amd64:3.1
docker pull coredns/coredns:1.6.5


docker pull googlecontainersmirrors/kube-apiserver-amd64:v1.17.3
docker pull googlecontainersmirrors/kube-scheduler-amd64:v1.17.3
docker pull googlecontainersmirrors/kube-controller-manager-amd64:v1.17.3
docker pull googlecontainersmirrors/kube-proxy-amd64:v1.17.3
docker pull googlecontainersmirrors/k8s-dns-kube-dns-amd64:v1.14.8
docker pull googlecontainersmirrors/k8s-dns-dnsmasq-nanny-amd64:v1.14.8
docker pull googlecontainersmirrors/k8s-dns-sidecar-amd64:v1.14.8
docker pull googlecontainersmirrors/etcd-amd64:v3.2.17
docker pull tkestack/flannel-amd64:v0.11.0
docker pull googlecontainersmirrors/pause:3.1

docker tag googlecontainersmirrors/kube-proxy-amd64:v1.17.3 k8s.gcr.io/kube-proxy:v1.17.3 
docker tag googlecontainersmirrors/kube-apiserver-amd64:v1.17.3  k8s.gcr.io/kube-apiserver:v1.17.3 
docker tag googlecontainersmirrors/kube-controller-manager-amd64:v1.17.3  k8s.gcr.io/kube-controller-manager:v1.17.3
docker tag googlecontainersmirrors/kube-scheduler-amd64:v1.17.3 k8s.gcr.io/kube-scheduler:v1.17.3 
docker tag tkestack/flannel-amd64:v0.11.0  quay.io/coreos/flannel:v0.11.0-amd64
docker tag azhu/etcd:3.4.3-0 k8s.gcr.io/etcd:3.4.3-0
docker tag googlecontainersmirrors/k8s-dns-dnsmasq-nanny-amd64:1.14.8 k8s.gcr.io/k8s-dns-dnsmasq-nanny:1.14.8
docker tag googlecontainersmirrors/k8s-dns-sidecar-amd64:1.14.8 k8s.gcr.io/k8s-dns-sidecar:1.14.8
docker tag googlecontainersmirrors/k8s-dns-kube-dns-amd64:1.14.8  k8s.gcr.io/k8s-dns-kube-dns:1.14.8
docker tag googlecontainersmirrors/pause-amd64:3.1  k8s.gcr.io/pause:3.1
docker tag coredns/coredns:1.6.5 k8s.gcr.io/coredns:1.6.5

注:上面打tag的镜像名称包括tag必须这样写、不能修改。如果修改了、我们在初始化集群的时候会报错的、这里报错信息忘记截图了、只有报错文本如下:

[root@Master ~]# kubeadm init --kubernetes-version=v1.17.3 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=172.16.200.1
W0306 23:36:35.232895    4297 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0306 23:36:35.233283    4297 validation.go:28] Cannot validate kubelet config - no validator is available
[init] Using Kubernetes version: v1.17.3
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-apiserver:v1.17.3: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1
        [ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-controller-manager:v1.17.3: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1
        [ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-scheduler:v1.17.3: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1
        [ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-proxy:v1.17.3: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1
        [ERROR ImagePull]: failed to pull image k8s.gcr.io/pause:3.1: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1
        [ERROR ImagePull]: failed to pull image k8s.gcr.io/etcd:3.4.3-0: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1
        [ERROR ImagePull]: failed to pull image k8s.gcr.io/coredns:1.6.5: output: Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
, error: exit status 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
[root@Master ~]#

img

可以将上面的命令保存为一个shell(k8s-images.sh)脚本,然后直接执行即可。这些镜像是在master节点上需要使用到的镜像,一定要提前下载下来。

注:安装完成之后、可以把从googlecontainersmirrors镜像站下载的镜像都删除、也可以不删除。

4、安装 kubeadm、kubelet、kubectl

在确保docker安装完成后,上面的相关环境配置也完成了,对应所需要的镜像(如果可以科学上网可以跳过这一步)也下载完成了,现在我们就可以来安装kubeadm了,我们这里是通过指定yum源的方式来进行安装的:

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

当然了,上面的yum源也是需要科学上网的,如果不能科学上网的话,我们可以使用阿里云的源进行安装:

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

img

img

img

这里我们可以直接安装,由于我们上面的相关镜像是关联的1.17.3版本,所以我们安装的时候需要指定版本。yum源配置完成后,执行安装命令即可:

# yum makecache fast && yum install -y kubelet-1.17.3 kubeadm-1.17.3 kubectl-1.17.3

这里我们需要同步安装kubelet,因为我们需要把所有的组件都容器化;同时安装kubectl对集群进行操作。正常情况我们可以都能顺利安装完成上面的文件。

5、配置 kubelet

默认情况docker的cgroup-driver是cgroupfs,安装完成后我们需要保证kubelet生成的配置文件和docker的配置文件这二者必须一致才行,如果不一致、我们在初始化集群的过程中系统会提示错误。我们可以通过docker info命令查看docker的默认配置是cgroupfs:

img

img

这里有两种方案解决这个问题、第一种是去修改Docker的配置:

添加或者修改配置文件如下:img

第二种方案就是修改Kubelet的配置文件(这里我查看了官方文档、还是修改失败、有知道的小伙伴可以私信告诉我一下、感谢)。

另外还有一个问题是关于交换分区的,Kubernetes从1.8开始要求关闭系统的 Swap ,如果不关闭,默认配置的kubelet将无法启动,当然最好的还是将swap给关掉,这样能提高kubelet的性能。不会的小伙伴请自行百度、这里就不再展示了。

6、初始化集群

到这里我们的准备工作就完成了,接下来我们就可以在master节点上用kubeadm命令来初始化我们的集群了:

# kubeadm init –kubernetes-version=v1.17.3 –pod-network-cidr=10.244.0.0/16 –apiserver-advertise-address=172.16.200.1

命令非常简单,就是kubeadm init,后面的参数是需要安装的集群版本,因为我们这里选择flannel作为 Pod 的网络插件,所以需要指定–pod-network-cidr=10.244.0.0/16(有一些小伙伴会有疑问、我怎么知道network的网段是多少呢?别着急https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/这里给出了提示)、因为我们这里使用的是flannel、我们可以按照官网的提示进行操作:

img

然后是apiserver的通信地址,这里就是我们master节点的IP 地址。执行上面的命令,如果出现 running with swap on is not supported. Please disable swap之类的错误,则我们还需要增加一个参数–ignore-preflight-errors=Swap来忽略swap的错误提示信息:

img

初始化完成之后我们还需要按照提示执行如下操作:

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

注:最后提示的 kubeadm join 代码一定记得保存下来、后面把node节点添加到集群的时候会用到,如果token值忘记了、我们可以通过 kubeadm token list 进行查看。

kubeadm join 172.16.200.1:6443 --token fo8xdf.2nquay0n95hp6y0s \
--discovery-token-ca-cert-hash sha256:65e23be381550fe8e232c5952c9786b6f6b16ba080d022d9e4d26005339435e5

上面kubeadm 默认生成的token默认有效期是24小时,过期之后该token就不可用了。解决方案如下:

通过 kubeadm token create 命令重新生成token,并通过下面的命令获取ca证书sha256编码hash值,然后通过上面的join命令重新添加即可:

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
# 获取如下的值:
0fd95a9bc67a7bf0ef42da968a0d55d92e52898ec37c971bd77ee501d845b538

初始化完成之后我们可以通过:kubectl get pods –all-namspaces 命令查看所有的namspaces:

img

然后我们需要初始化我们的网络环境,通过wget命令下载kube-flannel.yml文件,该连接也可以去https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/这里查看:

wget https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml

下载完成之后,执行kubectl apply -f kube-flannel.yml创建网络:

img

执行完成之后我们可以通过 kubectl get nodes查看节点信息只有Master;到这里、Master节点就已经初始化完成了、下面我们就可以去部署Node节点了:

img

7、安装Node节点

安装Node节点之前我们需要参考文章上面的基础环境配置把Node节点的基础环境配置完成,然后拉取Node节点需要的镜像(这里的操作通Master节点、我就不再详细叙述了),然后采用和Master节点同样的操作安装kubeadm、kubeadm安装完成以后我们就可以使用kubeadm控制Node节点了(这里同样略过):

docker pull googlecontainersmirrors/kube-proxy-amd64:v1.17.3
docker pull googlecontainersmirrors/pause-amd64:3.1 
docker pull tkestack/flannel-amd64:v0.11.0
docker pull googlecontainersmirrors/kubernetes-dashboard-amd64:v1.10.1
docker pull googlecontainersmirrors/heapster-grafana-amd64:v5.0.4
docker pull googlecontainersmirrors/heapster-influxdb-amd64:v1.5.2
docker pull googlecontainersmirrors/heapster-amd64:v1.7.0

docker tag googlecontainersmirrors/kube-proxy-amd64:v1.17.3 k8s.gcr.io/kube-proxy:v1.17.3
docker tag googlecontainersmirrors/heapster-amd64:v1.7.0 k8s.gcr.io/heapster:v1.7.0
docker tag tkestack/flannel-amd64:v0.11.0 quay.io/coreos/flannel:v0.11.0-amd64
docker tag googlecontainersmirrors/kubernetes-dashboard-amd64:v1.10.1 k8s.gcr.io/kubernetes-dashboard:v1.10.1
docker tag googlecontainersmirrors/heapster-influxdb-amd64:v1.5.2 k8s.gcr.io/heapster-influxdb:v1.5.2
docker tag googlecontainersmirrors/heapster-grafana-amd64:v5.0.4 k8s.gcr.io/heapster-grafana:v5.0.4
docker tag googlecontainersmirrors/pause-amd64:3.1 k8s.gcr.io/pause:3.1

img

然后我们通过下面的命令把node节点添加到集群里面去(如果token过期、请参考上文进行修改):

kubeadm join 172.16.200.1:6443 --token fo8xdf.2nquay0n95hp6y0s \ 
--discovery-token-ca-cert-hash sha256:65e23be381550fe8e232c5952c9786b6f6b16ba080d022d9e4d26005339435e5

img

我们可以通过kubectl get cs查看组件状态;kubectl get csr查看证书请求记录。到这里我们通过kubeadm安装Kubernetes集群就已经成功了、后面我们讲继续安装dashaboard、通过web界面把集群状态都展示出来。

img

推荐文章