k8s集群搭建完整过程

1.安装前说明

服务器必须是Centos 7.2及以上,Kubernetes 我们采用1.15.*版本
Docker-ce v18.06.3,Etcd 3.2.9,Flanneld v0.7.0-amd64
TLS 认证通信(所有组件,如etcd、kubernetes master 和node)
RBAC 授权,kubedns、dashboard
注意事项:
Docker安装的版本需与K8s版本批配,不然会出问题
Kubernetes 1.15.2 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.15.1 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.15.0 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.5 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.4 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.3 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.2 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.1 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.0 -->Docker版本1.1

2.环境准备

之前在本机笔记本开VMWare跑集群,感觉资源有些吃紧,看到某公有云在搞促销,直接下手三台服务器(2核+4G+5M带宽)



分别登录三台服务器修改Host Name

hostnamectl set-hostname k8s-master  \#Master节点
hostnamectl set-hostname k8s-node1  \#node1节点
hostnamectl set-hostname k8s-node2  \#node2节点

修改后,我们三台主机如下:

name IP 数量
k8s-master 192.168.0.66 Master节点
k8s-node1 192.168.0.137 工作节点1
k8s-node2 192.168.0.230 工作节点2

3.环境初始化

以下步骤在三台服务器上均执行一遍
关闭selinux

setenforce 0
\# sed -i  's@^\(SELINUX=\).*@\1disabled@' /etc/selinux/config

关闭防火墙及IP TABLE

systemctl  stop firewalld.service
systemctl  disable firewalld.service
systemctl disable iptables  
systemctl stop iptables

设置host
vim /etc/hosts
192.168.0.66 k8s-master
192.168.0.137 k8s-node1
192.168.0.230 k8s-node2

4.安装Docker

备份源
sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
修改OS源为阿里的仓库

curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

安装常用命令
yum -y install conntrack ipvsadm ipset jq sysstat curl iptables libseccomp wget lrzsz nmap lsof net-tools zip unzip vim telnet
安装依赖项
yum install -y yum-utils device-mapper-persistent-data lvm2
安装Docker源为阿里
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
清理缓存
yum clean all
** 重新生成缓存**
yum makecache
再次查看yum源信息
yum repolist


可以看出,我们的源已经更新到aliyun.com。
下一步我们开始安装Docker
安装指定版本的Docker,如果不知道版本名称,可以用如下命令查看
yum list docker-ce --showduplicates | sort -r

我们安装18.06.3版本,k8s对应1.15.*
sudo yum install docker-ce-18.06.3.ce-3.el7
安装完毕后,我们测试下

[root@k8s-master ~]# docker version
Client:
 Version:           18.06.3-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        d7080c1
 Built:             Wed Feb 20 02:26:51 2019
 OS/Arch:           linux/amd64
 Experimental:      false

启动Docker
sudo chkconfig docker on #设置开机启动
systemctl start docker
修改Docker镜像仓库为国内镜像

部分系统安装后未生成daemon.json,请执行以下命令

[root@promote ~]# mkdir -p /etc/docker
[root@promote ~]# touch /etc/docker/daemon.json 
[root@promote ~]# vim /etc/docker/daemon.json

配置文件内容格式如下:

{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors":["公网仓库地址"]
}

公网仓库地址以下三个任选其一,也可以找其他开放的仓库地址或自建仓库
https://docker.mirrors.ustc.edu.cn
https://registry.docker-cn.com
http://hub-mirror.c.163.com
修改后刷新daemon.json,重启docker服务使配置生效

systemctl daemon-reload
sudo systemctl restart docker.service

执行完后,可以查看下docker状态及详细信息

service docker status
docker info

如果不能正常启动docker,大概率是daemon.json文件有问题
我检查了好几次该文件的内容,因为是复制的内容,所以符号是中文的,单词也拼写错误,需要注意的几点如下:
1、注意符号是否是英文符号
2、单词是否拼写正确
3、json文件格式是否正确
以上步骤在三台机器均执行完毕后,且Docker状态正常,我们就开始安装K8S集群了

5.安装K8S

以下安装步骤在3台服务器上均执行一遍
安装K8S源

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

导入公钥

wget  https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
rpm --import yum-key.gpg
wget https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
rpm --import rpm-package-key.gpg

安装
yum install -y kubelet-1.15.9-0 kubeadm-1.15.9-0 kubectl-1.15.9-0
启动
systemctl enable kubelet && systemctl start kubelet # 自启动kubelet
systemctl status kubelet #查看状态
说明
kubectl 是命令行工具,所以不用启动
kubeadm 是集群搭建工具,也不用启动
kubelet 是节点管理工具,需要在所有节点启动
注意 : 以上所有教程,都需要在集群所有机器上均操作一遍,包括安装 kubectl kubeadm kubelet,启动 kubelet
在虚拟机上部署k8s 1.9版本需要关闭操作系统交换分区
# swapoff -a
初始化K8S集群
在master节点上执行如下命令,其他节点不执行
注意命令的master ip及主机名,我的master主机名是k8s-master

kubeadm init --kubernetes-version=v1.15.9 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.0.66 --apiserver-cert-extra-sans=192.168.0.66,k8s-master   --image-repository registry.aliyuncs.com/google_containers

参数含义:
--kubernetes-version:指定kubeadm版本;
--pod-network-cidr:指定pod所属网络
--image-repository 指定下载源
--service-cidr:指定service网段,负载均衡ip
--ignore-preflight-errors=Swap/all:忽略 swap/所有 报错
--apiserver-advertise-address 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。
--pod-network-cidr 指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对 --pod-network-cidr 有自己的要求,这里设置为 10.244.0.0/16 是因为我们将使用 flannel 网络方案,必须设置成这个  CIDR。在后面的实践中我们会切换到其他网络方案,比如 Canal。
初始化过程简要如下:
① kubeadm 执行初始化前的检查。
② 生成 token 和证书。
③ 生成 KubeConfig 文件,kubelet 需要这个文件与 Master 通信。
④ 安装 Master 组件,会从 goolge 的 Registry 下载组件的 Docker 镜像,这一步可能会花一些时间,主要取决于网络质量。
⑤ 安装附加组件 kube-proxy 和 kube-dns。
⑥ Kubernetes Master 初始化成功。
⑦ 提示如何配置 kubectl,后面会实践。
⑧ 提示如何安装 Pod 网络,后面会实践。
⑨ 提示如何注册其他节点到 Cluster,后面会实践。
我们执行初始化时报了一个错误:
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
error execution phase preflight: [preflight] Some fatal errors occurred:
出现[WARNING IsDockerSystemdCheck],是由于docker的Cgroup Driver和kubelet的Cgroup Driver不一致导致的,此处选择修改docker的和kubelet一致
docker info | grep Cgroup #查看当前的cgroup
默认系统返回:Cgroup Driver: cgroupfs,我们要修改为systemd

vim /etc/docker/daemon.json 加入下面这一行
"exec-opts": ["native.cgroupdriver=systemd"]
我本机修改后的daemon.json如下,配置了多个国内的镜像源

 {
 "registry-mirrors":["https://mirror.ccs.tencentyun.com","https://docker.mirrors.ustc.edu.cn", "https://dockerhub.azk8s.cn", "https://reg-mirror.qiniu.com","https://registry.docker-cn.com"],
 "exec-opts": ["native.cgroupdriver=systemd"]
}

刷新并重启docker

systemctl daemon-reload 
systemctl restart docker

然后我们重新执行初始化命令提示
[ERROR FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists
由于第一次没初始化成功,但相关文件没有清理,我们执行下面的命令,重置下环境,再初始化
kubeadm reset
重新执行初始化,约半分钟,系统提示成功,系统生成的加入节点的命令和token自行保存下备用

以下信息自行保存起来备用
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 
Then you can join any number of worker nodes by running the following on each as root:
 
kubeadm join 192.168.0.66:6443 --token 46lv86.ts6k9yc4p0dwsu1c \
    --discovery-token-ca-cert-hash sha256:956c98d52f3a0981a5b44d70317b89696f03418eef4efe921a991b31a3644727 

新版本的k8s初始化时会提示,因为官方要求镜像从k8s.gcr.io官方获取,但我们可以自己手动操作。
'''docker pull coredns/coredns
docker tag coredns/coredns:latest registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
docker rmi coredns/coredns:latest

kubeadm init --kubernetes-version=v1.21.1 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.0.16.8 --apiserver-cert-extra-sans=10.0.16.8,k8s-master --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
'''

6.配置K8S

将当前用户配置为集群管理员(如果不配置,下次连接时会无法使用kubectl)

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

部署flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
加入子节点
然后到其他两个节点执行如下命令,添加节点到master.

前面保存的加入节点命令和token,这个环节使用,后续有新服务器加入同样在新节点执行该命令即可
kubeadm join 192.168.0.66:6443 --token 46lv86.ts6k9yc4p0dwsu1c \
    --discovery-token-ca-cert-hash sha256:956c98d52f3 ****

加入完毕后,我们用命令kubectl get nodes获取所有节点

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS     ROLES    AGE    VERSION
k8s-master   Ready      master   115m   v1.15.9
k8s-node1    NotReady   <none>   111m   v1.15.9
k8s-node2    Ready      <none>   111m   v1.15.9

验证安装信息

检查系统基础模块健康度
[root@k8s-master ~]# kubectl get componentstatus
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}  
检查node状态,如果有工作节点NotReady,等几分钟一般就会正常
[root@k8s-master ~]# kubectl get nodes
NAME         STATUS     ROLES    AGE    VERSION
k8s-master   Ready      master   115m   v1.15.9
k8s-node1    NotReady   <none>   111m   v1.15.9
k8s-node2    Ready      <none>   111m   v1.15.9
检查系统pod状态
[root@k8s-master ~]# kubectl get pods -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-94d74667-l8lqt               1/1     Running   0          115m
coredns-94d74667-svgrk               1/1     Running   0          115m
etcd-k8s-master                      1/1     Running   0          115m
kube-apiserver-k8s-master            1/1     Running   0          114m
kube-controller-manager-k8s-master   1/1     Running   0          115m
kube-flannel-ds-amd64-64zsm          1/1     Running   0          2m5s
kube-flannel-ds-amd64-csb8h          1/1     Running   0          2m5s
kube-flannel-ds-amd64-nfcsh          1/1     Running   0          2m5s
kube-proxy-b669n                     1/1     Running   0          112m
kube-proxy-d84cb                     1/1     Running   0          115m
kube-proxy-w7tv7                     1/1     Running   0          111m
kube-scheduler-k8s-master            1/1     Running   0          115m

可能会遇到的错误:
FileContent--proc-sys-net-bridge-bridge-nf-call-iptables
解决命令:
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
测试K8S集群
这里为了快速地验证一下我们的K8S集群是否可用,创建一个示例Pod:

[root@k8s-master ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
[root@k8s-master ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
[root@k8s-master ~]# kubectl get pod,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-554b9c67f9-n9rsv   1/1     Running   0          17s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        129m
service/nginx        NodePort    10.98.172.7   <none>        80:30030/TCP   9s

如果想要看到Pod更多的信息,比如pod被部署在了哪个Node上,可以通过 kubectl get pods,svc -o wide来查看。
因为我们采用的是NodePort方式,该模式会直接将服务映射为主机的一个端口,用户通过主机IP+端口可以访问到该服务,其映射暴露出的端口号会在30000-32767范围内随机取一个,上面部署的nginx我们看到其端口是30030,那么我们用公网122.112.xx.xx:30030测试,如下图所示,已经可以访问到nginx默认页。



PS:公有云服务默认有防火墙,需要自行到云管理界面开放这些端口的访问,否则会认为k8s问题,排查起来很浪费时间。

7.安装Dashboard

Dashboard是k8s的管理UI界面,其安装过程最复杂的是证书的处理。
获取并修改Dashboard安装的Yaml文件

wget http://mirror.faasx.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

修改该文件配置
vim kubernetes-dashboard.yaml
按i,然后按方向键滚动到最后,节点是kind: service这部分

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  type: NodePort  插入这一行,注意对齐及空格
  ports:
    - port: 443
      nodePort: 30000  插入一行,如果指定,则K8S会自动分配一个端口,注意手工填写端口范围不能超出k8s默认限制,
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

esc wq保存
以下开始处理证书
mkdir key && cd key
生成证书
openssl genrsa -out dashboard.key 2048

我这里写的自己的node1节点,因为我是通过nodeport访问的;如果通过apiserver访问,可以写成自己的master节点ip
openssl req -new -out dashboard.csr -key dashboard.key -subj '/CN=192.168.0.66'
openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt 
创建新的证书secret
kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kube-system

执行安装
kubectl apply -f kubernetes-dashboard.yaml

安装可能需要几分钟,通过kubectl get pod -n kube-system查看状态

创建用户信息
1.创建一个叫admin-user的服务账号:

[root@k8s01 ~]# vim dashboard-admin.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system

然后执行创建用户
kubectl create -f dashboard-admin.yaml
2.直接绑定admin角色:

vim admin-user-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

执行绑定:
kubectl create -f admin-user-role-binding.yaml
3.查看绑定是否成功
kubectl get clusterrolebinding


验证安装
查看pod运行状态

kubectl get pod -n kube-system | grep dashboard
kubernetes-dashboard-8594bd9565-rx5xg   1/1     Running   0          5m57s
查看dashborad service
kubectl get svc -n kube-system|grep dashboard
kubernetes-dashboard   NodePort    10.110.157.149   <none>        443:30000/TCP            6m26s
查看pod运行日志,关注有没有错误
kubernetes-dashboard-8594bd9565-zjwgv是pod的名称,每个环境产生的名称各不相同
kubectl logs kubernetes-dashboard-8594bd9565-zjwgv -n kube-system

获取登录Dashboard的Token

找到admin-user-token用户
kubectl -n kube-system get secret

如上图所示,我们环境的这个帐户名是admin-user-token-mmc64

获取token串
kubectl -n kube-system describe secret admin-user-token-mmc64


如上图所示,该帐户的登录token已经产生,自行复制保存下来,后面登录dashboard就使用这个token,我们输入https://ip:30000测试下登录,注意dahsboard是使用的https协议。

输入前面我们获取到的token进行登录


至此,我们K8S集群的基本安装完成。

8.后记

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

配置k8s忽略使用swap

KUBELET_EXTRA_ARGS="--fail-swap-on=false"

配置docker代理

[Service]
Environment="HTTPS_PROXY=http://www.ik8s.io:10080"
Environment="NO_PROXY=127.0.0.0/8"
systemctl daemon-reload
systemctl restart docker

如果要卸载dashboard

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

推荐阅读更多精彩内容