通过kubeadm搭建K8S 1.16集群实践

文章内容非全部原创,有各位大佬的博客摘抄,也有自己踩坑的实践,主要记录一下整个学习和搭建过程,给有需要的同学。

1. K8S概述
有人说先看源码再搭建环境,有人说先玩一把再看源码,各有利弊,个人比较偏向实践性人格,所以我先准备搭建一个测试环境再看源码。
Master节点:

Master节点上面主要由四个模块组成,APIServer,schedule,controller-manager,etcd

APIServer: APIServer负责对外提供RESTful的kubernetes API的服务,它是系统管理指令的统一接口,任何对资源的增删该查都要交给APIServer处理后再交给etcd,如图,kubectl(kubernetes提供的客户端工具,该工具内部是对kubernetes API的调用)是直接和APIServer交互的。

schedule: schedule负责调度Pod到合适的Node上,如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定。 kubernetes目前提供了调度算法,同样也保留了接口。用户根据自己的需求定义自己的调度算法。

controller manager: 如果APIServer做的是前台的工作的话,那么controller manager就是负责后台的。每一个资源都对应一个控制器。而control manager就是负责管理这些控制器的,比如我们通过APIServer创建了一个Pod,当这个Pod创建成功后,APIServer的任务就算完成了。

etcd:etcd是一个高可用的键值存储系统,kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。

Node节点:


每个Node节点主要由三个模板组成:kublet, kube-proxy
kube-proxy: 该模块实现了kubernetes中的服务发现和反向代理功能。kube-proxy支持TCP和UDP连接转发,默认基Round Robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响,另外,kube-proxy还支持session affinity。
kublet:kublet是Master在每个Node节点上面的agent,是Node节点上面最重要的模块,它负责维护和管理该Node上的所有容器,但是如果容器不是通过kubernetes创建的,它并不会管理。本质上,它负责使Pod的运行状态与期望的状态一致。

K8S核心组件:

etcd保存了整个集群的状态;
apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy负责为Service提供cluster内部的服务发现和负载均衡。

实用的Add-ons:

kube-dns负责为整个集群提供DNS服务
Ingress Controller为服务提供外网入口
Heapster提供资源监控
Dashboard提供GUI
Federation提供跨可用区的集群
Fluentd-elasticsearch提供集群日志采集、存储与查询

2. kubeadm简介
kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,这不是一个单独的项目哦,我们在kubernetes源码里可以看到这个组件(kubernetes/cmd/kubeadm/)。kubeadm这个工具可以通过简单的kubeadm init和kubeadm join命令来创建一个kubernetes集群,kubeadm提供的其他命令都比较通俗易懂:

kubeadm init 启动一个master节点;
kubeadm join 启动一个node节点,加入master;
kubeadm upgrade 更新集群版本;
kubeadm config 从1.8.0版本开始已经用处不大,可以用来view一下配置;
kubeadm token 管理kubeadm join的token;
kubeadm reset 把kubeadm init或kubeadm join做的更改恢复原状;
kubeadm version打印版本信息;
kubeadm alpha预览一些alpha特性的命令。

3. 系统准备
我们先使用一台服务器安装,后面使用kubeadm join可以很轻松扩展。

3.1. 系统信息

内存:2G
CPU:2(K8S强制要求CPU核数大于2)
磁盘:32G

系统版本和内核版本:

cat /etc/redhat-release
#CentOS Linux release 7.7.1908 (Core)
uname -r
#3.10.0-1062.el7.x86_64

3.2. 配置selinux和firewalld

systemctl stop firewalld && systemctl disable firewalld
setenforce 0
vi /etc/selinux/config
SELINUX=disabled

3.3. 系统参数与内核模块

# 修改内核参数
cat <<EOF > /etc/sysctl.d/k8s.conf
>net.bridge.bridge-nf-call-ip6tables = 1
>net.bridge.bridge-nf-call-iptables = 1
>EOF
sysctl --system

# 加载内核模块
modprobe br_netfilter

3.4. 配置yum源

# base repo
cd /etc/yum.repos.d
mv CentOS-Base.repo CentOS-Base.repo.bak
curl -o CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
sed -i 's/gpgcheck=1/gpgcheck=0/g' /etc/yum.repos.d/CentOS-Base.repo

# docker repo
curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
​
# k8s repo
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
​
# 更新缓存
yum clean all  
yum makecache  
yum repolist

最终我们可以看到这些repo:

源标识 源名称 状态
!base/7/x86_64 CentOS-7 - Base - mirrors.aliyun.com 10,097
!docker-ce-stable/x86_64 Docker CE Stable - x86_64 59
!extras/7/x86_64 CentOS-7 - Extras - mirrors.aliyun.com 304
!kubernetes Kubernetes 409
!updates/7/x86_64 CentOS-7 - Updates - mirrors.aliyun.com 332

3.5. 禁用swap

swapoff -a && sysctl -w vm.swappiness=0
vi /etc/fstab
# 注释掉下面一行
# UUID=7bff6243-324c-4587-b550-55dc34018ebf swap                    swap    defaults        0 0

也可以不禁用,在初始化安装时添加忽略swap检查参数并修改K8S配置文件,启动时忽略SWAP检查:

vi /etc/sysconfig/kubelet
KUBELET_ EXTRA_ ARGS="--fail-swap-on=false"

4. 安装docker
先看一下有哪些docker版本可用:

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

这里我选择18.06.3,所以我用的命令是:

yum install docker-ce-18.06.3.ce

启动docker:

systemctl enable docker --now

修改docker的daemon配置,可以避免后续初始化时的警告:

cat > /etc/docker/daemon.json <<EOF
>{
>    "exec-opts": ["native.cgroupdriver=systemd"],
>    "log-driver": "json-file",
>    "log-opts": { "max-size": "100m" },
>    "storage-driver": "overlay2"
>}
>EOF
mkdir -p /etc/systemd/system/docker.service.d 
# 重启DOCKER
systemctl daemon-reload 
systemctl restart docker

查看服务状态:

systemctl status docker

5. 安装kubeadm、kubelet和kubectl

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

启动kubelet:

systemctl enable --now kubelet

6. 镜像准备
为了解决国内普遍访问不到k8s.gcr.io的问题,我们从阿里云定制自己的容器镜像库,然后从定制的容器镜像库下载image,再给下载的镜像打tag。不会的同学可以查看我另外一篇博客《超详细教程使用Github和阿里云加速拉取国外Docker镜像》:

docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/kube-apiserver:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/kube-controller-manager:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/kube-scheduler:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/kube-proxy:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/pause:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/etcd:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/coredns:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/flannel:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/dashboard:latest
docker pull registry.cn-shanghai.aliyuncs.com/xxxxx/metrics-scraper:latest
​
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/kube-apiserver:latest k8s.gcr.io/kube-apiserver:v1.16.1
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/kube-controller-manager:latest k8s.gcr.io/kube-controller-manager:v1.16.1
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/kube-scheduler:latest k8s.gcr.io/kube-scheduler:v1.16.1
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/kube-proxy:latest k8s.gcr.io/kube-proxy:v1.16.1
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/pause:latest k8s.gcr.io/pause:3.1
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/etcd:latest k8s.gcr.io/etcd:3.3.15-0
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/coredns:latest k8s.gcr.io/coredns:1.6.2
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/flannel:latest quay.io/coreos/flannel:v0.11.0-arm64
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/dashboard:latest kubernetesui/dashboard:v2.0.0-beta4
docker tag registry.cn-shanghai.aliyuncs.com/xxxxx/metrics-scraper:latest kubernetesui/metrics-scraper:v1.0.1


7. 安装k8s master

kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap

kubeadm init的参数说明:

--apiserver-advertise-address string API Server将要广播的监听地址。如指定为 `0.0.0.0` 将使用缺省的网卡地址。 
--apiserver-bind-port int32 缺省值: 6443 API Server绑定的端口 
--apiserver-cert-extra-sans stringSlice 可选的额外提供的证书主题别名(SANs)用于指定API Server的服务器证书。可以是IP地址也可以是DNS名称。 
--cert-dir string 缺省值: "/etc/kubernetes/pki" 证书的存储路径。 
--config string kubeadm配置文件的路径。警告:配置文件的功能是实验性的。 
--cri-socket string 缺省值: "/var/run/dockershim.sock" 指明要连接的CRI socket文件 
--dry-run 不会应用任何改变;只会输出将要执行的操作。 
--feature-gates string 键值对的集合,用来控制各种功能的开关。可选项有: Auditing=true|false (当前为ALPHA状态 - 缺省值=false) CoreDNS=true|false (缺省值=true) DynamicKubeletConfig=true|false (当前为BETA状态 - 缺省值=false) 
-h, --help 获取init命令的帮助信息 
--ignore-preflight-errors stringSlice 忽视检查项错误列表,•列表中的每一个检查项如发生错误将被展示输出为警告,而非错误。 例如: 'IsPrivilegedUser,Swap'. 如填写为 'all' 则将忽视所有的检查项错误。 
--kubernetes-version string 缺省值: "stable-1" 为control plane选择一个特定的Kubernetes版本。 
--node-name string 指定节点的名称。 
--pod-network-cidr string 指明pod网络可以使用的IP地址段。 如果设置了这个参数,control plane将会为每一个节点自动分配CIDRs。 
--service-cidr string 缺省值: "10.96.0.0/12" 为service的虚拟IP地址另外指定IP地址段 
--service-dns-domain string 缺省值: "cluster.local" 为services另外指定域名, 例如: "myorg.internal". 
--skip-token-print 不打印出由 `kubeadm init` 命令生成的默认令牌。 
--token string 这个令牌用于建立主从节点间的双向受信链接。格式为 [a-z0-9]{6}\.[a-z0-9]{16} - 示例: abcdef.0123456789abcdef 
--token-ttl duration 缺省值: 24h0m0s 令牌被自动删除前的可用时长 (示例: 1s, 2m, 3h). 如果设置为 '0', 令牌将永不过期。

如果遇到报错,对着错误信息修正一下,错误都报的很明白。比如:没有关闭swap;系统cpu不够;网络不通;镜像下载失败等等。执行完init命令后,会看到类似如下的输出:

Your Kubernetes master 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/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join 10.211.55.18:6443 --token di2xhw.d2578vsvbn2v8n4v  --discovery-token-ca-cert-hash \

        sha256:a3ed7b53f4041ecbbdd8fa5d460856a290751784d4debffdf57b71b064be998e

上面输出告诉我们还需要做一些工作:

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

稍等一会,应该可以看到node状态变成ready:

kubectl get node

如果没有ready可以查看一下pod是否正常,一般问题都是下载的镜像有问题。

kubectl get pod -n kube-system

全部ready以后,再看一下核心组件状态。

kubectl get cs

最后注意到dev1这个node上有一个Taint:

kubectl describe node dev1 | grep Taints
#Taints: node-role.kubernetes.io/master:NoSchedule

默认master节点是不跑业务pod的,我们暂时只有一个node,所以先去掉这个Taint:

kubectl taint node dev1 node-role.kubernetes.io/master-
#node/dev1 untainted
kubectl describe node kube-master | grep Taints
#Taints: <none>

8. 用kubeadm部署node,把其加入master,在各个node上执行上方生成的join命令。

kubeadm join 10.211.55.18:6443 --token di2xhw.d2578vsvbn2v8n4v  --discovery-token-ca-cert-hash sha256:a3ed7b53f4041ecbbdd8fa5d460856a290751784d4debffdf57b71b064be998e

9、安装网络插件
安装网络插件需要注意保证仓库中已经有相关的镜像,或者网络可以访问quay.io等国外网站。通过查找yml文件可以知道需要什么版本的镜像。我使用的Flannel:

kubectl create -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

10、安装Dashboard

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta4/aio/deploy/recommended.yaml
vi recommended.yaml
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort # 改成NodePort
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 31001 # 指定nodePort端口
  selector:
    k8s-app: kubernetes-dashboard
kubectl create -f recommended.yaml

如果忘记TOKEN,可以使用以下命令

kubectl describe secrets -n kubernetes-dashboard $(kubectl -n kubernetes-dashboard get secret | awk '/kubernetes-dashboard/{print $1}')

11、猜到的坑
dashboard登录

kubectl create serviceaccount cluster-admin-dashboard-sa
kubectl create clusterrolebinding cluster-admin-dashboard-sa \
  --clusterrole=cluster-admin \
  --serviceaccount=default:cluster-admin-dashboard-sa
kubectl get secret | grep cluster-admin-dashboard-sa
kubectl describe secret cluster-admin-dashboard-sa-token-6xm8l

删除 dev3 节点

kubectl drain dev3 --delete-local-data --force --ignore-daemonsets
kubectl delete node dev3


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值