环境准备

准备2台干净的虚拟机,如果之前安装过docker或者k8s,需要卸载干净。

2台机器网络能够相互连通,操作系统centos7以上,root权限

系统规划

2台虚拟机分别命名为kube1,kube2

kube1作为控制平面(master)节点,kube2作为工作(worker)节点

修改/etc/hosts文件,2台都需要操作,在文件最后添加域名解析,类似下面这样

192.168.1.101  kube1
192.168.1.102  kube2

以上命令实际上只是修改了本地的dns,hostname使用下面的命令再修改一下

hostname kube1    #在第一台机器上执行
hostname kube2    #在第二台机器上执行

安装前准备

所有机器都需要满足要求,包括master和worker

确保每个节点上mac地址和product_uuid的唯一性

查看mac地址

ip link

查看product_uuid

cat /sys/class/dmi/id/product_uuid

允许 iptables 检查桥接流量

使用以下代码使br_netfilter被加载,使 iptables 能够正确地查看桥接流量

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
​
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

开放所需端口

以下端口是k8s集群需要用到的端口,要确保开放

master节点

协议方向端口范围作用使用者
TCP入站6443Kubernetes API 服务器所有组件
TCP入站2379-2380etcd 服务器客户端 APIkube-apiserver, etcd
TCP入站10250Kubelet APIkubelet 自身、控制平面组件
TCP入站10251kube-schedulerkube-scheduler 自身
TCP入站10252kube-controller-managerkube-controller-manager 自身

使用命令:

firewall-cmd --permanent --zone=public --add-port=6443/tcp --add-port=2379-2380/tcp --add-port=10250/tcp --add-port=10251/tcp --add-port=10252/tcp 
firewall-cmd --reload

worker节点

协议方向端口范围作用使用者
TCP入站10250Kubelet APIkubelet 自身、控制平面组件
TCP入站30000-32767NodePort 服务所有组件
firewall-cmd --permanent --add-port=10250/tcp --add-port=30000-32767/tcp
firewall-cmd --reload

安装docker

安装yum辅助工具

yum install -y yum-utils

添加docker软件源

yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

查看可用的docker版本,安装docker时,建议加上docker版本,以便于以后维护

yum list docker-ce --showduplicates | sort -r

选择一个docker版本进行安装,我选择了docker-ce 3:19.03.9-3.el7,对应docker-ce-cli 1:19.03.9-3.el7,官方给出的安装命令如下,所以containerd.io不需要指定版本

yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

执行以下命令进行安装

yum install docker-ce-19.03.9 docker-ce-cli-19.03.9 containerd.io

安装完成后启动docker,并将docker设置为开机启动

如果不将docker设置为开机启动,kubeadm init时会报错

systemctl start docker
systemctl enable docker

测试docker是否安装成功

docker run hello-world

如果出现如下字样,说明docker应该安装成功了

Hello from Docker! This message shows that your installation appears to be working correctly.

设置docker国内下载源

tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","https://registry.docker-cn.com"]
}
EOF

关闭swap分区

swapoff -a                  #临时关闭swap分区
vim /etc/fstab              #注释swap的那一行
free -m                     #检查swap分区是否已关闭

关闭selinux

setenforce 0                #临时关闭
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
#永久关闭

安装 kubeadm、kubelet 和 kubectl

你需要在每台机器上安装以下的软件包:

kubeadm:用来初始化集群的指令。 kubelet:在集群中的每个节点上用来启动 Pod 和容器等。 kubectl:用来与集群通信的命令行工具。

官方使用了google的镜像,但是国内很难下载到,所以我们将它换成中科大的镜像(其他的镜像站也可以用,个人觉得还是中科大的最好用),但是中科大的镜像站没有找到gpg的key,所以就不做gpgcheck了。

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.ustc.edu.cn/kubernetes/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl  #屏蔽不想更新的RPM包可用通配符多个RPM包之间使用空格分离
EOF
#可以使用命令找一个喜欢的版本 yum list kubelet --showduplicates | sort -r
sudo yum install -y kubelet-1.19.8 kubeadm-1.19.8 kubectl-1.19.8 --disableexcludes=kubernetes
​
sudo systemctl enable --now kubelet  #--now代表enable的同时start

启动之后,kubelet 现在每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环。

组建集群

简单介绍一下master节点和worker节点的组成。

master节点就是控制平面节点(官方文档中直译过来的叫法),worker node代表工作节点,从图中可以看到,master节点包含:apiserver、coltroller-manager、scheduler、etcd四个组件,worker节点包含:container-runtime、kubeproxy、kubelet三个组件。

但是master节点也可以同时也是worker节点,所以安装的时候,master节点也包含:kubelet、kuberproxy、container runtime。container runtime大多数情况下使用docker。

 

kubeadm init之前的准备工作

下载kubeadm init时需要用到的docker image

因为默认的配置是从google下载,而且镜像名称中带有k8s.gcr.io,使用国内源直接下载可能会出现问题,所以,我们先降需要用到的docker images下载好

使用以下命令查看需要用到的docker images,因为kubeadm、kubectl、kubelet都使用了1.19.8的版本,所以kubernetes也使用1.19.8版本了官网说: kubelet 的版本不可以超过 API server的版本,可以理解为kubernetes的版本高于kubelet是没有问题的,版本相同应该是最好的。

kubeadm --kubernetes-version 1.19.8 config images list

返回结果:

k8s.gcr.io/kube-apiserver:v1.19.8
k8s.gcr.io/kube-controller-manager:v1.19.8
k8s.gcr.io/kube-scheduler:v1.19.8
k8s.gcr.io/kube-proxy:v1.19.8
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns:1.7.0

从国内镜像站将这些docker image全部下载好。

我的办法是从https://hub.docker.com/search?q=&type=image这个网站上逐个去搜

kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、pause、etcd、coredns

下面以kube-apiserver为例说明

从docker hub上搜到这个镜像之后,使用docker pull下载下来,类似下面这个例子

 

docker pull k8smx/kube-apiserver:v1.19.8

使用docker images可以看到已经下载到了这个docker images

[root@brdev1 ~]# docker images
REPOSITORY                        TAG       IMAGE ID       CREATED       SIZE
aiotceo/kube-apiserver            v1.20.5   d7e24aeb3b10   3 weeks ago   122MB
k8s.gcr.io/kube-apiserver         v1.20.5   d7e24aeb3b10   3 weeks ago   122MB
aiotceo/kube-controller-manager   v1.20.5   6f0c3da8c99e   3 weeks ago   116MB
hello-world                       latest    d1165f221234   4 weeks ago   13.3kB
k8smx/kube-apiserver              v1.19.8   9ba91a90b7d1   7 weeks ago   119MB

然后将其重命名为k8s.gcr.io/kube-apiserver:v1.19.8

[root@brdev1 ~]# docker tag k8smx/kube-apiserver:v1.19.8 k8s.gcr.io/kube-apiserver:v1.19.8
[root@brdev1 ~]# docker images
REPOSITORY                        TAG       IMAGE ID       CREATED       SIZE
aiotceo/kube-apiserver            v1.20.5   d7e24aeb3b10   3 weeks ago   122MB
k8s.gcr.io/kube-apiserver         v1.20.5   d7e24aeb3b10   3 weeks ago   122MB
aiotceo/kube-controller-manager   v1.20.5   6f0c3da8c99e   3 weeks ago   116MB
hello-world                       latest    d1165f221234   4 weeks ago   13.3kB
k8smx/kube-apiserver              v1.19.8   9ba91a90b7d1   7 weeks ago   119MB
k8s.gcr.io/kube-apiserver         v1.19.8   9ba91a90b7d1   7 weeks ago   119MB

可以看到我们需要的k8s.gcr.io/kube-apiserver:v1.19.8已经在本地了,用相同的方法下载其余docker image

这个下载地址的docker image挺全的:https://hub.docker.com/u/k8smx,大家可以从这里下载。

我也已经将所需要的docker images全部放到腾讯微云上了,有需要的小伙伴可以直接下载,使用方法会在下文中说到。

微云地址:https://share.weiyun.com/s93S1fWw

执行kubeadm init并安装pod网络组件

kubeadm init初始化集群

kubeadm init之前规划好service和pod的网络空间,找一个跟现有网络不冲突的网络段即可,我随便选了两个网段

service网络空间 --service-cidr=10.18.0.0/16

pod网络空间 --pod-network-cidr=10.19.0.0/16

kubeadm所在机器的IP --apiserver-advertise-address=192.168.1.101

kubernetes版本 --kubernetes-version=1.19.8

执行kubeadm init

kubeadm init --kubernetes-version=1.19.8 \
--apiserver-advertise-address=192.168.1.101 \
--service-cidr=10.18.0.0/16 \
--pod-network-cidr=10.19.0.0/16

大概2分钟左右,就执行成功了。

Your Kubernetes control-plane 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/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.101:6443 --token 73vi27.3gndl08t126iaba0 \
    --discovery-token-ca-cert-hash sha256:9bf4639635b62b347d76d0fbb43dc31cf72973c3fa2b358cd9101e422ec851a7

按照提示所述,执行以下命令

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

按照提示所述,在worker节点执行以下命令就可以加入集群了

kubeadm join 192.168.1.101:6443 --token 73vi27.3gndl08t126iaba0 \
    --discovery-token-ca-cert-hash sha256:9bf4639635b62b347d76d0fbb43dc31cf72973c3fa2b358cd9101e422ec851a7

安装pod网络组件

下面的pod网络安装方法是参考了calico的快速开始,后来在实际部署中发现了更完善的部署方式,会在后续文章中介绍。

pod网络组件的功能是使pod之间能够像独立的设备一样通信。官方说: 目前 Calico 是 kubeadm 项目中执行 e2e 测试的唯一 CNI 插件。那么我们就选择calico吧。

安装pod网络组件很简单,要搞懂它的原理稍微复杂一点,我们这里只讲安装,复杂的原理以后有时间再说

kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
wget https://docs.projectcalico.org/manifests/custom-resources.yaml

打开 custom-resources.yaml文件,文件内容很少,把cdir改成kubeadm init使所用到的--pod-network-cidr=10.19.0.0/16中的10.19.0.0/16,然后执行

kubectl create -f custom-resources.yaml

等待一段时间(这个过程也是需要下载docker image的),使用以下命令查看calico的相关的3个pod状态都为running,就代表calico安装成功了。

[root@brdev1 ~]# kubectl get pods -n calico-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-7b498688c4-djwrc   1/1     Running   0          71m
calico-node-bvbcq                          1/1     Running   0          71m
calico-typha-fdd8c8f74-5qx8j               1/1     Running   0          71m

然后再检查一下所有的pod是否都处于running状态

[root@brdev1 ~]# kubectl get pods --all-namespaces
NAMESPACE         NAME                                       READY   STATUS    RESTARTS   AGE
calico-system     calico-kube-controllers-7b498688c4-djwrc   1/1     Running   0          76m
calico-system     calico-node-bvbcq                          1/1     Running   0          76m
calico-system     calico-typha-fdd8c8f74-5qx8j               1/1     Running   0          76m
kube-system       coredns-f9fd979d6-gfc45                    1/1     Running   0          17h
kube-system       coredns-f9fd979d6-q8hjd                    1/1     Running   0          17h
kube-system       etcd-brdev1                                1/1     Running   1          17h
kube-system       kube-apiserver-brdev1                      1/1     Running   0          17h
kube-system       kube-controller-manager-brdev1             1/1     Running   4          17h
kube-system       kube-proxy-hcm5k                           1/1     Running   0          17h
kube-system       kube-scheduler-brdev1                      1/1     Running   4          17h
tigera-operator   tigera-operator-675ccbb69c-z2459           1/1     Running   3          78m

kubeadm join加入集群

上面介绍过worker node的组成包含:kubelet、kubeproxy、runtime,其中kubelet和runtime(也就是docker)已经安装好了,还差kubeproxy,kubeadm join的时候会自动去下载kubeproxy,还是老问题,google下载不到,所以要提前为worker node准备好kubeproxy配套的docker image,启动kubeproxy需要用到的docker image除了k8s.gcr.io/kube-proxy,还需要k8s.gcr.io/pause。

除了kubeproxy,每一个节点(包括master和worker)都需要calico,calico是能从网上下载到的,但是为了更快启动,直接从master节点上k8s相关的docker images全部导到worker中。

1、在master node上将与k8s相关的docker images全部导出

docker save -o k8s.1.19.8.tar k8s.gcr.io/kube-apiserver:v1.19.8 k8s.gcr.io/kube-proxy:v1.19.8 k8s.gcr.io/kube-controller-manager:v1.19.8 k8s.gcr.io/kube-scheduler:v1.19.8 k8s.gcr.io/etcd:3.4.13-0 k8s.gcr.io/coredns:1.7.0 k8s.gcr.io/pause:3.2 calico/node:v3.18.1 calico/typha:v3.18.1 calico/pod2daemon-flexvol:v3.18.1 calico/cni:v3.18.1 calico/kube-controllers:v3.18.1

2、在worker上导入k8s.1.19.8.tar

docker load < k8s.1.19.8.tar

3、执行kubeadm join

kubeadm join 192.168.1.101:6443 --token 73vi27.3gndl08t126iaba0 \
    --discovery-token-ca-cert-hash sha256:9bf4639635b62b347d76d0fbb43dc31cf72973c3fa2b358cd9101e422ec851a7

等待一段时间查看各node状态,可以看到都已经ready了。

[root@brdev1 ~]# kubectl get node -o wide
NAME          STATUS   ROLES    AGE    VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION               CONTAINER-RUNTIME

kube1        Ready    master   18h    v1.19.8   192.168.1.101   <none>        CentOS Linux 7 (Core)   3.10.0-514.2.2.el7.x86_64    docker://19.03.9

kube2        Ready    <none>   96m    v1.19.8   192.168.1.102   <none>        CentOS Linux 7 (Core)   3.10.0-957.12.2.el7.x86_64   docker://19.03.9

到此为止,单控制平面节点的k8s集群就搭建完成了。

后续知识点学习

1、增加worker节点、网络插件flannel和calico对比

2、通过部署服务来学习k8s的各种概念和使用方式

3、k8s证书概念以及证书续期的两种方式

4、高可用k8s集群介绍和使用kubespray安装高可用k8s集群

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐