kubeadm 部署 kubernetes(1.15.2版)---带你绕坑
K8S这么火,网上教程不少,但是无奈官方更新太快,很多部署教程都已落后,并有无数的坑点,对于初学者来说,不是每个人都有能力爬出来。对于,每个想进步的同学来说,部署K8S就是一座大山,能清晰的部署出来,那么已经对各种组件和功能略知一二,所以今天这篇笔记式教程能在自己和同学前进的路上铺上一层厚实的奠基石,无论您因为什么原因看到这篇文章,那么,说明你在探索的路上是想进步的,那么,...
K8S这么火,网上教程不少,但是无奈官方更新太快,很多部署教程都已落后,并有无数的坑点,对于初学者来说,不是每个人都有能力爬出来。
对于,每个想进步的同学来说,部署K8S就是一座大山,能清晰的部署出来,那么已经对各种组件和功能略知一二,所以今天这篇笔记式教程能在自己和同学前进的路上铺上一层厚实的奠基石,无论您因为什么原因看到这篇文章,那么,说明你在探索的路上是想进步的,那么, 既然有人想求知,那么,就没有道理不分享自己的小小的心得。
注明:感谢bokeyuan的小水滴,我只是站在巨人的肩膀上更进一步,很多内容也修改自他的文章。
docker : kubernetes依赖的容器运行时 kubelet: kubernetes最核心的agent组件,每个节点都会启动一个,负责像pods及节点的生命周期等管理 kubectl: kubernetes的命令行控制工具,只可以在master上使用. kubeadm: 用来bootstrap kubernetes. 初始化一个k8s集群.
一、所有节点环境准备
1、软件版本
软件 | 版本 |
---|---|
kubernetes | v1.15.2 |
CentOS | Minimal 7.6.1809 (ESXi 虚拟机) |
Docker | v18.09 |
flannel | v0.10.0-amd64 |
2、节点规划
IP | 角色 | 主机名 |
---|---|---|
192.168.3.10 | k8s master | master |
192.168.3.11 | k8s node01 | slaver1 |
192.168.3.12 | k8s node02 | slaver2 |
这里我就不贴网络架构图了,并且假设你已经部准备好虚拟机并关闭防火墙和selinux,并且将三个节点添加好了hosts文件,并修改好了hostname,并保证网络通畅,
对于需要代理或加速docker镜像拉取,为了简化本教程,这里一律都假设你处于自由网路世界可拉取任意文件(需要的请自己参考其他教程或者手动拉取镜像);
我的测试主机位于香港,所以无需配置代理或者加速:
iptables对bridge的数据进行处理:
创建/etc/sysctl.d/k8s.conf文件,添加如下内容:
net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1
执行命令使修改生效。
modprobe br_netfilter sysctl -p /etc/sysctl.d/k8s.conf
关闭系统Swap
Kubernetes 1.8开始要求关闭系统的Swap,如果不关闭,默认配置下kubelet将无法启动。方法一,通过kubelet的启动参数–fail-swap-on=false更改这个限制。方法二,关闭系统的Swap。
swapoff -a
修改/etc/fstab文件,注释掉SWAP的自动挂载,使用free -m确认swap已经关闭。
#注释掉swap分区 [root@localhost /]# sed -i 's/.*swap.*/#&/' /etc/fstab [root@localhost /]# free -m total used free shared buff/cache available Mem: 962 154 446 6 361 612 Swap: 0 0 0
永久禁用swap
echo "vm.swappiness = 0">> /etc/sysctl.conf
在所有的Kubernetes节点node1和node2上执行以下脚本:
cat > /etc/sysconfig/modules/ipvs.modules <<EOF #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
安装docker
docker的版本对于K8S的成功至关重要,不少朋友会掉进去(有的身处坑中而不自知),K8S 1.15.2支持的最高docker版本为18.09,那我们就装这个版本中的最高小版本18.09.8。
按照docker的官方安装教程:
先清理centos自带所有docker程序:
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
添加最新的docker yum仓库:
yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
官方给出的安装命令:
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
查看仓库提供的各种版本信息并按照版本从高到底排序:
yum list docker-ce.x86_64 --showduplicates |sort -r
这里我们安装18.09.8:
yum install docker-ce-18.09.8 docker-ce-cli-18.09.8 containerd.io -y
启动:
systemctl start docker ; systemctl enable docker
修改docker cgroup driver为systemd
对于使用systemd作为init system的Linux的发行版,使用systemd作为docker的cgroup driver可以确保服务器节点在资源紧张的情况更加稳定,因此这里修改各个节点上docker的cgroup driver为systemd。
创建或修改/etc/docker/daemon.json
:
{ "exec-opts": ["native.cgroupdriver=systemd"] }
重启docker:
systemctl restart docker docker info | grep Cgroup Cgroup Driver: systemd
安装kubeadm和kubelet
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF
安装:
yum install -y kubelet kubeadm kubectl
上面命令会默认安装最新版的程序,目前都为1.15.2
安装kubeadm init初始化集群所需docker镜像
开始初始化集群之前可以使用kubeadm config images pull
预先在各个节点上拉取所k8s需要的docker镜像
[root@localhost /]# kubeadm config images list k8s.gcr.io/kube-apiserver:v1.15.2 k8s.gcr.io/kube-controller-manager:v1.15.2 k8s.gcr.io/kube-scheduler:v1.15.2 k8s.gcr.io/kube-proxy:v1.15.2 k8s.gcr.io/pause:3.1 k8s.gcr.io/etcd:3.3.10 k8s.gcr.io/coredns:1.3.1
逐个手动拉取,先来个小技巧,在每行前面加个docker pull ,免得写脚本或手工输入麻烦:
kubeadm config images list |awk '{print "docker pull " $0}' docker pull k8s.gcr.io/kube-apiserver:v1.15.2 docker pull k8s.gcr.io/kube-controller-manager:v1.15.2 docker pull k8s.gcr.io/kube-scheduler:v1.15.2 docker pull k8s.gcr.io/kube-proxy:v1.15.2 docker pull k8s.gcr.io/pause:3.1 docker pull k8s.gcr.io/etcd:3.3.10 docker pull k8s.gcr.io/coredns:1.3.1
直接复制运行即可。
kubeadm初始化集群
使用kubeadm初始化集群,在master上执行下面的命令:
kubeadm init --kubernetes-version=v1.15.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12
部署成功后,重点在这里:
按照提示配置必要的环境路径:
mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
查看一下集群状态,确认个组件都处于healthy状态:
[root@master /]# kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {"health":"true"}
因为还没有部署pod网络,所以coredns被延时等待启动。
给pod配置网络
pod网络插件是必要安装,以便pod可以相互通信。在部署应用和启动kube-dns之前,需要部署网络,kubeadm仅支持CNI的网络。
pod支持的网络插件有很多,如Calico
,Canal
,Flannel
,Romana
,Weave Net
等,因为之前我们初始化使用了参数--pod-network-cidr=10.244.0.0/16
,所以我们使用插件flannel
。
安装:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
配置完后,通过命令可以清晰的看到随着flannel被安装成功并初始化后coredns渐渐被调度起来的过程:
kube-proxy 启动 ipvs
我假设你前面已经按照步骤在每个节点都加载好了ipvs内核,并设置了开机启动
kubectl edit configmap kube-proxy -n kube-system
找到如下部分。
kind: KubeProxyConfiguration metricsBindAddress: 127.0.0.1:10249 mode: "ipvs" nodePortAddresses: null oomScoreAdj: -999
其中mode原来是空,默认为iptables模式,改为ipvs。scheduler默认是空,默认负载均衡算法为轮训。
查找并删除所有kube-proxy的pod
kubectl get pod -n kube-system -o wide |grep kube-proxy kubectl delete pod kube-proxy-xxx -n kube-system
查看kube-proxy的pod日志
kubectl logs kube-proxy-XXX -n kube-system
或者后面部署了DashBoard直接web页面查看。
安装ipvsadm
使用ipvsadm查看ipvs相关规则,如果没有这个命令可以直接yum安装
yum install -y ipvsadm
[root@master ~]# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 127.0.0.1:31896 rr -> 10.244.0.7:3000 Masq 1 0 0 TCP 172.17.0.1:31896 rr -> 10.244.0.7:3000 Masq 1 0 0 TCP 172.17.0.1:32238 rr -> 10.244.0.9:8443 Masq 1 0 0 TCP 192.168.3.10:31896 rr -> 10.244.0.7:3000 Masq 1 0 0 TCP 192.168.3.10:32238 rr -> 10.244.0.9:8443 Masq 1 0 0 TCP 10.96.0.1:443 rr -> 192.168.3.10:6443 Masq 1 0 0 TCP 10.96.0.10:53 rr -> 10.244.0.2:53 Masq 1 0 0 -> 10.244.0.3:53 Masq 1 0 0
不要着急添加节点,先把master配置到底:
部署完了,就开始部署dashboard,有命令行没有web,感觉差点什么;
安装 Kubernetes Dashboard
k8s dashboard 的 docker镜像是
k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
先准备好dashboard镜像,没办法,就是这么随意,国内得绕弯去别处找并打标签:
docker pull k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
安装,这个是目前最新的编排文件地址,网上很多坑就是因为这个文件路径都已变更:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
修改NodePort:
因为Service 是ClusterIP 类型,为了方便使用,我们可通过下面命令修改成NodePort 类型。
kubectl patch svc kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}' -n kube-system
查看端口
[root@master ~]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 6h kubernetes-dashboard NodePort 10.107.238.193 <none> 443:32238/TCP 167m
登录web端:https://192.168.3.10:32238
配置登录权限
Dashboard 支持 Kubeconfig 和 Token 两种认证方式,为了简化配置,我们通过配置文件 dashboard-admin.yaml 为 Dashboard 默认用户赋予 admin 权限。
[root@ken ~]# cat dashboard-admin.yml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard labels: k8s-app: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kube-system
这里的重点是创建了一个ServiceAccountName为kubernetes-dashboard的系统服务账号,我们要记住它,有大用。
应用并且获取token:
kubectl apply -f dashboard-admin.yaml kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep kubernetes-dashboard| awk '{print $1}')
类似于下面这一段,把 token 填入确定即可。
Name: admin-user-token-xln5d Namespace: kube-system Labels: <none>Annotations: kubernetes.io/service-account.name: admin-user kubernetes.io/service-account.uid: 54801c01-01e2-11e9-857e-00505689640f Type: kubernetes.io/service-account-token Data====ca.crt: 1025 bytes namespace: 11 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJ lLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLXhsbjVkIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3V udC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI1NDgwMWMwMS0wMWUyLTE xZTktODU3ZS0wMDUwNTY4OTY0MGYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.MbGeROnjA9f1AhBO8v2GuHC1ihVk1UcxpM8lYk IC_P9Mx9jVZcM56zr4jcxjSnIuZPZxIznLJIIo7TRY94Ya2VujzF2lpDxlNYF2hWY3Ss9d5LqRtP3JsJNZVLmxvYIGnmnGyVCEikCM6W44WPu-S
基本就登录成功了,但是还没完,想要直观的看到每个pod和容器的资源使用情况,得安装K8S原生支持的基本可视化监控插件,这里说的就是:heapster+influxdb+grafana组合;
Heapster 本身是一个 Kubernetes 应用,部署方法很简单,但是它不像dashboard那样apply下就起来,因为它不是K8S默认系统应用,所以master默认是不允许直接调度到master节点上运行,所以,为了将heapster部署到master节点,必须首先放开这个限制:
kubectl taint node master node-role.kubernetes.io/master-
为了保险起见,还是先手动把需要的镜像拉取过来吧,不然服务一直处于延时等待启动状态:
docker pull k8s.gcr.io/heapster-amd64:v1.5.4 docker pull k8s.gcr.io/heapster-grafana-amd64:v5.0.4 docker pull k8s.gcr.io/heapster-influxdb-amd64:v1.5.2
这样这三剑客就这么来了,
上官方克隆heapster并安装:
git clone https://github.com/kubernetes/heapster.git kubectl apply -f heapster/deploy/kube-config/influxdb/ kubectl apply -f heapster/deploy/kube-config/rbac/heapster-rbac.yaml
部署完了就恢复Master Only状态,禁止调度其他pod到master节点:
kubectl taint node master node-role.kubernetes.io/master=:NoSchedule
运行命令查看部署情况:
kubectl get pod -n kube-system |grep -e heapster -e monitor kubectl get deploy -n kube-system |grep -e heapster -e monitor kubectl get svc -n kube-system |grep -e heapster -e monitor
修改NodePort,将grafana暴露到公网访问:
kubectl patch svc monitoring-grafana -p '{"spec":{"type":"NodePort"}}' -n kube-system
好,这就算部署完了,你以为基本的master就这么简单的部署完了,更多的坑在向你招手;
在web页面等了半天怎么刷新发现可视化监控图表都没有出来,我们打开heapster容器的日志发现api接口被拒问题,于是修改heapster的部署文件:
# heapster.yaml文件中的 - --source=kubernetes:https://kubernetes.default # 修改为 - --source=kubernetes:kubernetes:https://kubernetes.default?useServiceAccount=true&kubeletHttps=true&kubeletPort=10250&insecure=true
并修改这个地方,前面部署token的时候让你记住有大用,这里就是用了这个账号:
这里是使用dashboard的web编辑器,当然有点反人类,好好的yaml语法就这样被破坏了,所以,你也可以直接命令行搞定:
kubectl edit deployment heapster -n kube-system
更新后,K8S销毁原来的容器,又自动重新创建了一个新容器,现象就出来了:
最后, token登录dashboard的超时设置,又是默认的一个坑,官方的默认是900S也就是15分钟,这对于搞实验的同学简直是一痛苦,
参数名 默认值 说明 token-ttl 15 minutes Expiration time (in seconds) of JWE tokens generated by dashboard. Default: 15 min. 0 - never expires.
直接修改kubernetes-dashboard的部署文件,Dashboard的Token失效时间可以通过 token-ttl 参数来设置,
ports: - containerPort: 8443 protocol: TCP args: - --auto-generate-certificates - --token-ttl=43200
如果你的docker 和docker-CLI版本不太对,那么你可能入另外一个坑,无法shell登录容器,
kubectl exec -it 容器名称 -n kube-system sh (/bin/sh , /bin/bash, bash )无论哪种都说没有这个路径无法执行,查看yaml文件又发现已经设置加载了/bin/sh,暂时无解。
后面,你将发现容器日志的时间又是UTC时区格式,又是一个坑,慢慢爬吧。
grafana有兴趣去官网下载K8S模板,直接导入,慢慢玩吧!
更多推荐
所有评论(0)