使用kubeadm安装单master节点的k8s集群

使用kubeadm安装单master节点的k8s集群

环境准备

准备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 入站 6443 Kubernetes API 服务器 所有组件
TCP 入站 2379-2380 etcd 服务器客户端 API kube-apiserver, etcd
TCP 入站 10250 Kubelet API kubelet 自身、控制平面组件
TCP 入站 10251 kube-scheduler kube-scheduler 自身
TCP 入站 10252 kube-controller-manager kube-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 入站 10250 Kubelet API kubelet 自身、控制平面组件
TCP 入站 30000-32767 NodePort 服务 所有组件
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。

image-20210407201842062.png

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下载下来,类似下面这个例子

image-20210408191155763.png
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集群

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容