文章目录

  • 前言
  • 1. 集群信息
    • 节点规划
    • 组件版本
    • 环境架构
  • 2. 安装前准备
    • 设置hosts解析
    • 调整系统配置
    • 安装docker
  • 3. 初始化集群
    • 安装 kubeadm、kubelet 和 kubectl
    • 初始化配置文件
    • 提前下载镜像
    • 初始化master节点
    • 添加slave节点到集群中
  • 4. 网络插件
  • 5. 集群设置
    • 设置 master 节点是否可调度
    • 设置kubectl自动补全
  • 6. 调整证书过期
  • 7. 验证集群
  • 8. 部署dashboard
    • 清理集群
  • 9. 总结

前言

前面讲了 k8s 的理论特性,那么今天将会带领大家动手搭建一个 k8s 集群

1. 集群信息

节点规划

部署 k8s 集群的节点按照用途可以划分为如下 2 类角色:
 
(1)master: 集群的 master 节点,集群的初始化节点,基础配置不低于 2 C 4 G;
 
(2)slave: 集群的 slave 节点,可以多台,基础配置不低于 2 C 4 G;

本篇文章演示 slave 节点的添加,会部署 1 台 master + 2 台 slave,节点规划如下:

组件版本

环境架构

这里看一个类似的架构图

2. 安装前准备

设置hosts解析

操作节点:所有节点(k8s-master, k8s-slave)均需执行

  • 修改 hostname :hostname 必须只能包含小写字母、数字、",""-",且开头结尾必须是小写字母或数字
# 在master节点$ hostnamectl set-hostname k8s-master #设置master节点的hostname# 在slave-1节点$ hostnamectl set-hostname k8s-slave1 #设置slave1节点的hostname# 在slave-2节点$ hostnamectl set-hostname k8s-slave2 #设置slave2节点的hostname
  • 添加 hosts 解析
$ cat >>/etc/hosts<<EOF172.21.51.143 k8s-master172.21.51.67 k8s-slave1172.21.51.68 k8s-slave2EOF

调整系统配置

操作节点: 所有的 masterslave 节点(k8s-master, k8s-slave)需要执行

下述操作均以 k8s-master 为例,其他节点均是相同的操作(iphostname 的值换成对应机器的真实值)

  • 设置安全组开放端口

如果节点间无安全组限制(内网机器间可以任意访问),可以忽略,否则,至少保证如下端口可通:
 
k8s-master 节点:TCP:6443,2379,2380,60080,60081;UDP协议端口全部打开
 
k8s-slave 节点:UDP协议端口全部打开

  • 设置iptables
$ iptables -P FORWARD ACCEPT
  • 关闭swap
$ swapoff -a# 防止开机自动挂载 swap 分区$ sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
  • 修改内核参数
$ cat <<EOF >/etc/sysctl.d/k8s.confnet.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1net.ipv4.ip_forward=1vm.max_map_count=262144EOF$ modprobe br_netfilter$ sysctl -p /etc/sysctl.d/k8s.conf
  • 设置yum源
$ curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo$ curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo[kubernetes]name=Kubernetesbaseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64enabled=1gpgcheck=0repo_gpgcheck=0gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpghttp://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpgEOF$ yum clean all && yum makecache 

安装docker

所有节点都要安装

## 查看所有的可用版本$ yum list docker-ce --showduplicates | sort -r##安装旧版本 yum install docker-ce-cli-18.09.9-3.el7docker-ce-18.09.9-3.el7## 安装源里最新版本$ yum install docker-ce-20.10.12 -y## 配置docker加速$ mkdir -p /etc/dockervi /etc/docker/daemon.json{"insecure-registries": ["172.21.51.143:5000" ],"registry-mirrors" : ["https://8xpk5wnt.mirror.aliyuncs.com" ##用自己的阿里镜像加速器网址]}## 启动docker$ systemctl enable docker && systemctl start docker

3. 初始化集群

安装 kubeadm、kubelet 和 kubectl

kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。

操作节点: 所有的 masterslave 节点(k8s-master, k8s-slave) 需要执行

$ yum install -y kubelet-1.21.5 kubeadm-1.21.5 kubectl-1.21.5 --disableexcludes=kubernetes## 查看kubeadm 版本$ kubeadm version## 设置kubelet开机启动$ systemctl enable kubelet 

初始化配置文件

操作节点: 只在 master 节点(k8s-master)执行

$ kubeadm config print init-defaults > kubeadm.yaml$ cat kubeadm.yaml ##编写yaml文件apiVersion: kubeadm.k8s.io/v1beta2bootstrapTokens:- groups:- system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages:- signing- authenticationkind: InitConfigurationlocalAPIEndpoint:advertiseAddress: 172.21.51.143bindPort: 6443nodeRegistration:criSocket: /var/run/dockershim.sockname: k8s-mastertaints: null---apiServer:timeoutForControlPlane: 4m0sapiVersion: kubeadm.k8s.io/v1beta2certificatesDir: /etc/kubernetes/pkiclusterName: kubernetescontrollerManager: {}dns:type: CoreDNSetcd:local:dataDir: /var/lib/etcdimageRepository: registry.aliyuncs.com/google_containerskind: ClusterConfigurationkubernetesVersion: 1.21.5networking:dnsDomain: cluster.localpodSubnet: 10.244.0.0/16serviceSubnet: 10.96.0.0/12scheduler: {}

提前下载镜像

操作节点:只在 master 节点(k8s-master)执行

 # 查看需要使用的镜像列表,若无问题,将得到如下列表$ kubeadm config images list --config kubeadm.yamlregistry.aliyuncs.com/google_containers/kube-apiserver:v1.16.0registry.aliyuncs.com/google_containers/kube-controller-manager:v1.16.0registry.aliyuncs.com/google_containers/kube-scheduler:v1.16.0registry.aliyuncs.com/google_containers/kube-proxy:v1.16.0registry.aliyuncs.com/google_containers/pause:3.1registry.aliyuncs.com/google_containers/etcd:3.3.15-0registry.aliyuncs.com/google_containers/coredns:1.21.5# 提前下载镜像到本地$ kubeadm config images pull --config kubeadm.yaml[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.16.0[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.16.0[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.16.0[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.16.0[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.1[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.3.15-0[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:1.21.5

初始化master节点

操作节点:只在 master 节点(k8s-master)执行

$ kubeadm init --config kubeadm.yaml

若初始化成功后,最后会提示如下信息:

...Your Kubernetes master has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configYou 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 172.21.51.143:6443 --token abcdef.0123456789abcdef \--discovery-token-ca-cert-hash sha256:1c4305f032f4bf534f628c32f5039084f4b103c922ff71b12a5f0f98d1ca9a4f

接下来按照上述提示信息操作,配置 kubectl 客户端的认证

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

⚠️注意:此时使用 kubectl get nodes 查看节点应该处于 notReady 状态,因为还未配置网络插件
 
若执行初始化过程中出错,根据错误信息调整后,执行 kubeadm reset 后再次执行 init 操作即可

添加slave节点到集群中

操作节点:所有的 slave 节点(k8s-slave)需要执行在每台 slave 节点,执行如下命令;
 
该命令是在 kubeadm init 成功后提示信息中打印出来的,需要替换成实际 init 后打印出的命令。

$ kubeadm join 172.21.51.143:6443 --token abcdef.0123456789abcdef \--discovery-token-ca-cert-hash sha256:1c4305f032f4bf534f628c32f5039084f4b103c922ff71b12a5f0f98d1ca9a4f

如果忘记添加命令,可以通过如下命令生成:

$ kubeadm token create --print-join-command

4. 网络插件

操作节点:只在 master 节点(k8s-master)执行,CNI

  • 下载 flannelyaml 文件
$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  • 修改配置,指定网卡名称,大概在文件的 190 行,添加一行配置:
$ vi kube-flannel.yml...containers:- name: kube-flannelimage: rancher/mirrored-flannelcni-flannel:v0.16.1command:- /opt/bin/flanneldargs:- --ip-masq- --kube-subnet-mgr- --iface=eth0# 如果机器存在多网卡的话,指定内网网卡的名称,默认不指定的话会找第一块网卡resources:requests:cpu: "100m"...
  • 执行安装 flannel 网络插件
# 先拉取镜像,此过程C内速度比较慢$ docker pull rancher/mirrored-flannelcni-flannel:v0.16.1# 执行flannel安装$ kubectl apply -f kube-flannel.yml

5. 集群设置

设置 master 节点是否可调度

操作节点:k8s-master

默认部署成功后,master 节点无法调度业务 pod,如需设置 master 节点也可以参与 pod 的调度,需执行:

$ kubectl taint node k8s-master node-role.kubernetes.io/master:NoSchedule-

设置kubectl自动补全

操作节点:k8s-master

$ yum install bash-completion -y$ source /usr/share/bash-completion/bash_completion$ source <(kubectl completion bash)$ echo "source <(kubectl completion bash)" >> ~/.bashrc

6. 调整证书过期

使用 kubeadm 安装的集群,证书默认有效期为 1 年,可以通过如下方式修改为 10 年。

$ cd /etc/kubernetes/pki# 查看当前证书有效期$ for i in $(ls *.crt); do echo "===== $i ====="; openssl x509 -in $i -text -noout | grep -A 3 'Validity' ; done$ mkdir backup_key; cp -rp ./* backup_key/$ git clone https://github.com/yuyicai/update-kube-cert.git$ cd update-kube-cert/ $ bash update-kubeadm-cert.sh all# 重建管理服务$ kubectl -n kube-system delete po kube-apiserver-k8s-master kube-controller-manager-k8s-master kube-scheduler-k8s-master

7. 验证集群

操作节点: 在 master 节点(k8s-master)执行

$ kubectl get nodes#观察集群节点是否全部Ready

创建测试 nginx 服务

$ kubectl runtest-nginx --image=nginx:alpine

查看 pod 是否创建成功,并访问 pod ip 测试是否可用

$ kubectl get po -o wideNAMEREADY STATUSRESTARTS AGE IP NODE NOMINATED NODE READINESS GATEStest-nginx-5bd8859b98-5nnnw 1/1 Running 09s10.244.1.2 k8s-slave1  $ curl 10.244.1.2...

Welcome to nginx!

If you see this page, the nginx web server is successfully installed andworking. Further configuration is required.

For online documentation and support please refer tonginx.org.
Commercial support is available atnginx.com.

Thank you for using nginx.

8. 部署dashboard

  • 部署服务
$ wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml$ vi recommended.yaml# 修改Service为NodePort类型,文件的45行上下......kind: ServiceapiVersion: v1metadata:labels:k8s-app: kubernetes-dashboardname: kubernetes-dashboardnamespace: kubernetes-dashboardspec:ports:- port: 443targetPort: 8443selector:k8s-app: kubernetes-dashboardtype: NodePort# 加上type=NodePort变成NodePort类型的服务......
  • 查看访问地址,本例为 30133 端口
$ kubectl apply -f recommended.yaml$ kubectl -n kubernetes-dashboard get svcNAMETYPECLUSTER-IPEXTERNAL-IP PORT(S) AGEdashboard-metrics-scraper ClusterIP 10.105.62.124 <none>8000/TCP31mkubernetes-dashboardNodePort10.103.74.46<none>443:30133/TCP 31m 
  • 访问
  • 创建 ServiceAccount 进行访问
$ vi dashboard-admin.confkind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:name: adminannotations:rbac.authorization.kubernetes.io/autoupdate: "true"roleRef:kind: ClusterRolename: cluster-adminapiGroup: rbac.authorization.k8s.iosubjects:- kind: ServiceAccountname: adminnamespace: kubernetes-dashboard---apiVersion: v1kind: ServiceAccountmetadata:name: adminnamespace: kubernetes-dashboard$ kubectl apply -f dashboard-admin.conf$ kubectl -n kubernetes-dashboard get secret |grep admin-tokenadmin-token-fqdpfkubernetes.io/service-account-token 37m17s# 使用该命令拿到token,然后粘贴到浏览器$ kubectl -n kubernetes-dashboard get secret admin-token-fqdpf -o jsonpath={.data.token}|base64 -deyJhbGciOiJSUzI1NiIsImtpZCI6Ik1rb2xHWHMwbWFPMjJaRzhleGRqaExnVi1BLVNRc2txaEhETmVpRzlDeDQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi1mcWRwZiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjYyNWMxNjJlLTQ1ZG...
  • 粘贴到此处
  • 搭建成功

清理集群

如果在集群安装过程中遇到了其他问题,我们可以使用下面的命令来进行重置:

# 在全部集群节点执行kubeadm resetifconfig cni0 down && ip link delete cni0ifconfig flannel.1 down && ip link delete flannel.1rm -rf /run/flannel/subnet.envrm -rf /var/lib/cni/mv /etc/kubernetes/ /tmpmv /var/lib/etcd /tmpmv ~/.kube /tmpiptables -Fiptables -t nat -Fipvsadm -Cip link del kube-ipvs0ip link del dummy0

9. 总结

K8S 是目前容器管理的一个主流,是实现 PaaS 的重要组成部分,所以我认为学习它是非常有价值的;
 
但是 K8S 可以说博大精深,不是短时间内可以掌握的,或者说只能掌握一些简单的操作;
 
另外 docker 已经被弃用了,早期的 k8s 的确是用 docker 作为容器运行时,但是从去年还是前年就不用了,取而代之的是 CRI-O 或者直接调用 containerd ,所以 docker 可以简单了解一下,不用花太多精力深入,