k8s容器编排(使用kubeadm部署)
k8s容器编排
一。基础
kuberbete就是管理这些应用程序所在的小运行环境(container)而生,集群调度的最小单元就是一个pod,一个pod可以是一个容器,也可以是多个容器。k8s不是直接管理容器,而是管理pod。
1
一个K8S系统,通常称为一个K8S集群(Cluster)。kubectl 是k8s的客户端程序,也是k8s的命令行工具,提供的大量的子命令可以让用户可以和集群进行交互。
这个集群主要包括两个部分:
一个Master节点(主节点)
一群Node节点(计算节点)
2
Master节点包括API Server、Scheduler、Controller manager、etcd。
API Server是整个系统的对外接口,供客户端和其它组件调用,所有的指令请求都要经过apiserver 。
Scheduler使用调度算法,负责对集群内部的资源进行调度,把请求资源调度到某一个node节点,相当于“调度室”。
Controller manager维护k8s资源对象,负责管理控制器,控制平面,用于调度程序以及节点状态检测。
eted存储资源对象。
3
3.1
Node节点是实际部署容器运行的地方,包括Docker、kubelet、kube-proxy、Fluentd、kube-dns(可选),pods。
3.2
详细介绍:
Pod是Kubernetes最基本的操作单元。一个Pod代表着集群中运行的一个进程,它内部封装了一个或多个紧密相关的容器。
Service,一个Service可以看作一组提供相同服务的Pod的对外访问接口。
Docker,创建容器的。
Kubelet,在每一个node节点都存在一份,在node节点上的资源操作指令由kubelet来执行,主要负责监视指派到它所在Node上的Pod,包括创建、修改、监控、删除等。
Kube-proxy,主要负责为Pod对象提供代理,处理服务器间负载均衡。
Fluentd,主要负责日志收集、存储与查询。
3.3
Node包含的信息:
· Node地址:主机的IP地址,或Node ID。
· Node的运行状态:Pending、Running、Terminated三种状态。
· Node Condition:…
· Node系统容量:描述Node可用的系统资源,包括CPU、内存、最大可调度Pod数量等。
· 其他:内核版本号、Kubernetes版本等。
3.4
查看Node信息:
kubectl describe node
3.5
Pod的生命周期通过Replication Controller来管理;通过模板进行定义,然后分配到一个Node上运行,在Pod所包含容器运行结束后,Pod结束。
3.6
在Kubernetes的世界里,虽然每个Pod都会被分配一个单独的IP地址,但这个IP地址会随着Pod的销毁而消失,这就引出一个问题:如果有一组Pod组成一个集群来提供服务,那么如何来访问它呢?Service!
一个Service可以看作一组提供相同服务的Pod的对外访问接口,Service作用于哪些Pod是通过Label Selector来定义的。
· 拥有一个指定的名字(比如my-mysql-server);
· 拥有一个虚拟IP(ClusterIP、ServiceIP或VIP)和端口号,销毁之前不会改变,只能内网访问;
· 能够提供某种远程服务能力;
· 被映射到了提供这种服务能力的一组容器应用上;
如果Service要提供外网服务,需指定公共IP和NodePort,或外部负载均衡器;
4
二。目的
k8s是一个编排容器的工具,创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,故障自愈(一个服务器挂了,可以自动将这个服务器上的服务调度到另外一个主机上进行运行,无需进行人工干涉),更新的时候可以做到不用中断服务,服务器故障不用停机,从开发环境到测试环境到生产环境的迁移极其方便,一个配置文件搞定,一次生成image,到处运行
三。安装步骤
1
关闭防火墙和selinux(三)
sed -i ‘s/enforcing/disabled/’是将enforcing 替换为disabled
2
关闭swap分区(三)
因为K8s安装的时候会去检测swap分区有无关闭,如果开启了话可能会把pod放在虚拟内存运行,大大降低工作效率
模糊匹配swap注释掉该行sed -ri ‘s/.swap./#&/’ /etc/fstab
sed 中 -r标识regular expressions 正则表达式
sed中可以使用&符号,&可以理解为当前查找到的值(值为.swap.)
@符号标识sed命令的分割符,也可以使用# 或者/代替,看你写的语句如果包含不同符号的时候用另一种分割符号会规避与要操作的文本冲突避免转义的麻烦看着更简洁。
3
设置静态ip(三)
vim /etc/network-scripts/ip名称
添加:
BOOTPROTO=static
IPADDR=10.0.100.11
NETMASK=255.255.255.0
GATEWAY=10.0.100.8
DNS=8.8.8.8
4
修改主机名并且修改hosts文件(三)
设置完后可每台机器都运行如下命令,检测下是否能ping通
ping m
ping w1
ping w2
可以ping通
可以查看:
确认linux系统内核
kubernetes基础环境需要2核
6
待定
-
在命令行中输入modprobe br_netfilter ,使修改生效
禁止iptables对bridge数据进行处理(kubeadm初始化时会检测该选项)报错1:显示/proc/sys/net/bridge/bridge-nf-call-iptables:没有这个文件或者目录 modprobe br_netfilter 报错2:显示sysctl: cannot stat /proc/sys/net/netfilter/nf_conntrack_max: 没有那个文件或目录 modprobe ip_conntrack
7(三)
在/etc/sysctl.d/下,新建文件kubernetes.conf
开启bridge网桥模式,设置系统参数(三)
或者
第一次没有写到.conf文件,报错了。
cat > 写入该文件
<< EOF 代表写入完毕,退出
8(三)
时间同步
9(三)
安装docker
9.1
docker配置修改,设置cgroup驱动,这里用systemted ,配置修改
vim .etc/docker/daemon.json
加入以下内容:
驱动:exec-opts:[native.cgroupdriver-systemd]
配置镜像下载加速器(阿里云镜像加速器需要注册,单独分配一个地址):
registry-mirrors:[https://140o2406.mirror.aliyuncs.com]
说明:
cgroup用来管控资源分配的,本身可以有不同的driver,kubernetes在启动的时候会做一些检查,在启动kubelet的时候,去判断docker使用了哪一个cgroup driver,如果docker本身不是使用systemd,那么它就会默认报错不启动。
9.2
重启docker :systemctl restart docker
重启docker 失败,提示/etc/systemd/system/docker.service的配置native.cgroupdriver=systemd和/etc/docker/daemon.json有冲突
放弃/etc/docker/daemon.json的配置:native.cgroupdriver=systemd
10(三)
10.1
安装/kubeadm/kubelet/kubectl (三)
在/etc/yum.repo.d目录下创建kubernetes.repo文件。
配置安装源:/etc/yum.repo.d/kubernetes.repo
镜像源修改为国内的:
10.2
安装
yum install -y --setopt=obsoletes=0 kubelet-1.17.4-0 kubeadm-1.17.4-0 kubectl-1.17.4-0
必须制定–setopt=obsoletes=0,否则yum会自动安装更高版本
10.3
kubelet是与容器接口进行交互,而k8s通过kubeadm安装以后都是以pod方式存在,底层是以容器容器的方式运行,所以一定要开机自启,不然启动不了k8s集群。
设置kubelet自启动
systemctl enable kubelet
systemctl start kubelet
确认以下kubelet状态是否正常:systemctl status kubelet
11
docker和k8s设置同一个cgroup
kubelet,这边如果发现输出directory not exist,也说明没问题的,继续进行。
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf或者vim /etc/sysconfig/kubelet
编辑vim /etc/sysconfig/kubelet
ipvs是什么(暂时没有设置)
12(三)
在安装kubernetes集群之前,必须要提前准备好集群需要的镜像,所需镜像可以通过下面命令查看。
12.1
查看kubeadm使用的镜像:kubeadm config images list
试一下直接拉取:docker pull k8s.gcr.io/kube-apiserver:v1.17.17
连接被拒绝
12.2
针对部分国外镜像仓库无法访问问题,国内阿里云或dockerhub可能有转存镜像可用,拉取后需自行修改tag:
#示例:
docker pull k8s.gcr.io/pause:3.2
#改为:
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
12.3
任意位置创建kubeadm.sh脚本,该脚本作用是:
拉取阿里云对应镜像
打tag,将拉取的镜像改名为k8s开头的名称
删除原有镜像
12.4
脚本内容如下:
12.5
运行脚本和查看镜像
以下表示成功(tag版本跟自己的kubeadm依赖有关系)。
9
部署k8s-master【master执行】
9.1 kubeadm部署【master节点 】
kubernetes-version和ignore-preflight-errors是否必须要配置。
–apiserver-advertise-address 集群通告地址,在 Master执行(apiserver-advertise-address的值为master的ip)。
(不需要配置)–image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。默认值:"k8s.gcr.io"选择用于拉取控制平面镜像的容器仓库 由于已经把镜像加载到本地了,所以不需要配置, 优先取本地的镜像。
–kubernetes-version K8s版本,与上面安装的一致
–service-cidr 集群内部虚拟网络,Pod统一访问入口
–pod-network-cidr Pod网络,与下面部署的CNI网络组件yaml中保持一致,10.244.0.0、16是kube-flannel.yml文件配置的默认网段,如果pod-network-cidr默认使用的是192.168.0.0/16,而当集群节点的IP段也为192.168.0.0/16时,必然导致IP段冲突 当Pod子网和主机网络出现冲突的情况下就会出现问题。
初始化之后,会输出一个join命令,先复制出来,node节点加入master会使用。
记得保存好最后kubeadm init 生成的token 和 discovery-token-ca-cert-hash
kubeadm join的信息。
注:
查看token
kubeadm token list
超过24小时过期。kubeadm token create --print-join-command
删除token :kubeadm token delete abcdef.0123456789abcdef
#创建永久的token:kubeadm token create --ttl=0
提示错误也没关系
#获取token_hash值 :openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der |openssl dgst -sha256 -hex
9.2【master结点】
根据日志提示,创建相关目录以及授权,拷贝k8s认证文件
将当前用户配置为集群管理员(如果不配置,下次连接时会无法使用kubectl)
mkdir -p $HOME/.kube意思在~目录下创建一个.kube文件。
执行后ls -a可以查看.kube文件。
chown
(
i
d
−
u
)
:
(id -u):
(id−u):(id -g) config 意思切换config的所属用户
10
查看pod工作节点是否运行成功。
kubectl get nodes 或者kubectl get nodes -n kube-system
原因:
kubectl是命令行管理工具,get获取pod状态,-n是指定名称空间为kube-system。因为所有的系统组件都被安装在kube-system
报错一:执行后状态不对notready
主机中k8s的master启动顺序为:systemd > kubelet > 容器组件 > kubernetes
查看kubelet 状态(可以先跳过):systemctl status kubelet
查看docker 状态:systemctl status docker
应该是版本问题。
使用kubectl version 命令,输出的信息会显示client和server的版本信息,client代表kubectl版本信息,server代表的是master节点的k8s版本信息
kubectl version获取的client版本和server版本数据来自:
client版本是kubectl执行文件的版本.
server版本是kube-apiserver执行文件的版本.
报错一:
kube-controller-manager-master和Kube-scheduler-master 状态是 crashloopbackoff
原因:如果容器无法启动,则Kubernetes将显示错误状态为:CrashLoopBackOff。
注意:
kubectl语句不管执行什么都报拒绝连接,大概率是接口调用有问题
正在运行的容器:docker ps
找到kube-apiserver重启:docker restart 05d412caabf8
重启后正常
或者是因为虚拟机内存不足,可以free执行一下看,添加一下内存
11
重新安装了一遍k8s获取pod工作节点正常(我是因为电脑故障重新安装了)
kubectl get pod -n kube-system
发现像etc,controller,scheduler等组件都以pod的方式安装成功了,但是可以发现coredns没有启动,因为需要安装网络插件,插件有很多种,本次搭建选用calico。
12
部署calico网络插件(在master节点服务器上运行)
健康检查:curl -k https://localhost:6443/healthz
Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的网络方案。
12.1
(1)
在k8s中安装calico(不建议这种)
kubectl apply -f https://docs.projectcalico.org/v3.20/manifests/calico.yaml
v3.20 v3.21 v3.22是网页版的报错 v3.19 V3.18 V3.17 V3.16
k1.14 v3.9
k1.23 v3.14
用v3.14
安装报错,提示连接被拒绝dial tcp localhost:6443 connect: connection refused
这种报错是因为calico的网络接口配置和kubernete不一致,换成v3.14版本的就可以了(各个kubernete版本不一致,可以一个个改版本号试试kubectl apply -f https://docs.projectcalico.org/v3.20/manifests/calico.yaml)
成功后,执行kubectl get pod -n kube-system 可以一直执行,因为它是一直更新着的。
其他的都正常了,只有执行kubectl get nodes 时master 是notready和 calico-node-vgsl6有问题
查看日志:journalctl -u kubelet | tail -n 200
kubectl get cs查看组件状态controller-manager 显示unhealthy
这两个pod的非安全端口没有开启,健康检查时报错,但是由于本身服务是正常的,只是健康检查的端口没启,所以不影响正常使用。
解决方法:
查找kubelet的配置文件位置 systemctl cat kubelet
找到kublet的配置文件
添加如下红笔标注内容:–pod-manifests-path=/etc/kubernetes/manifests
重新加载启动kubelet
[root@cka-node01 ~]# systemctl daemon-reload
[root@cka-node01 ~]# systemctl restart kubelet
再次获取状态就是health
再次执行kubectl get nodes 状态已经正常
(2)先下载,提示颁发的证书已经过期
wget https://docs.projectcalico.org/manifests/calico.yaml
执行命令“yum install -y ca-certificates”更新下证书。
再下载就正常了。
(3)
设置为ipip模式
下载完后还需要修改里面定义Pod网络(CALICO_IPV4POOL_CIDR),与前面kubeadm init的 --pod-network-cidr指定的一样。
下载calico.yaml存放地址:/etc/kubernetes/manifests/
在DaemonSet部分 calico-node的pod的变量中,修改CALICO_IPV4POOL_IPIP值为Always
修改pod的网段
修改CALICO_IPV4POOL_CIDR为k8s集群的pod网段
同样也在DaemonSet 中, calico-node的pod的变量里,修改如下:
(4)
创建calico网络
kubectl create -f calico.yaml
(5)
kubectl apply 和create区别
kubectl create
是祈使式命令,明确告诉k8s要创建的资源或者对象
首先删除集群中现有的资源,然后重新根据yaml文件生成新的资源对象
yaml文件必须是完整的配置
yaml文件中的所有字段都会被create
在没有改动yaml文件时,使用同一个yaml文件执行命令kubectl replace,将不会成功(fail掉),因为缺少相关改动信息。
kubectl apply
是声明式命令,apply不告诉k8s具体要干什么,而是kubectl根据yaml文件自动探测要做哪些操作,如果不存在则create,如果存在则对比差异,进行更新。
根据yaml文件中包含的字段,直接升级集群中的现有资源对象
yaml文件可以不完整,只写需要修改的字段
只有要改动的字段才会被apply
在只改动了yaml文件中的某些声明时,而不是全部改动,你可以使用kubectl apply
12.3
确认一下calico是否安装成功(时间比较久,coredns和calico为running状态后再进行后面的操作)
kubectl get pods --all-namespaces -w
(1)
coredns和calico为pending
可以使用netstat -r 查看路由表
使用kubectl describe 命令查看原因:kubectl describe pod calico-kube-controllers-55… -n kube-system
然后找到原因对应的去解决就可以了
(2)
查看calico的默认ip池
calicoctl get ipPool -o yaml
kubernetes 集群在初始化完成后就会创建一个 kubernetes service,该 service 是 kube-apiserver 创建并进行维护的
kubectl get svc
(3)
查看容器的信息,查找容器名称
(4)
查看/etc/cni/net.d/10-calico.conflist,nodename字段确实是szx-xxxxxx。这个文件是由install-cni这个容器初始化的
(5)
查看
kubectl get pod -o yaml
-o指定具体的格式,可以是yaml或者json格式
apiVersion:Kubernetes API版本;
kind:Kubernetes对象资源类型;
metadata:包括名称、命名空间、标签和关于该容器的其他信息;
(6)
kubectl logs kubia-manual -c kubia
以上表示查询Pod为kubia-manual中的容器kubia的日志(因为一个pod中可以包含多个容器)
(7)
查看docker 状态报错,以下是journalctl -xe日志报错截图
部署k8s报错:unknown container “/system.slice/kubelet.service”
*原因:kubernetes和docker版本兼容性问题(有可能是k8s版本太高,docker版本太低的问题)
修改配置:vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=“–runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice”
(8)
kubectl edit ds calico-node -n kube-system
可以编辑calico的配置文件
(9)
常用命令:kubectl cluster-info查看集群信息
查看所有configmaps信息 kubectl get cm -A
编辑查找的configmaps:kubectl edit cm cluser-info
查看指定pod的日志 kubectl logs -f --tail 500 -n kube-system kube-apiserver-k8s-master
(10)
目前情况
docker和kubelet都正常
kubectl describe pod calico-kube-controlle -n kube-system
calico.yaml的配置
(11)
查看所需的镜像: grep image calico.yaml
第一种方法
在所有节点(包括master)上把这些镜像下载下来:
for i in docker.io/node:v3.24.4 ; do docker pull $i ; done
下载完成后(master和节点都要有)
安装calico网络
kubectl apply -f calico.yaml
第二种方法:
下载calico.yaml文件后
修改calico.yaml文件
由于默认的Calico清单文件中所使用的镜像来源于docker.io国外镜像源,上面我们配置了Docker镜像加速,应删除docker.io前缀以使镜像从国内镜像加速站点下载。
(12)
如果主机系统使用NetworkManager来管理网络的话,则需要配置NetworkManager,以允许Calico管理接口。
NetworkManger操作默认网络命名空间接口的路由表,这可能会干扰Calico代理正确路由的能力。在所有主机上操作:
创建以下配置文件以防止 网络管理器干扰接口:/etc/NetworkManager/conf.d/calico.conf
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico
解决kubectl apply -f calico.yaml执行时报的错
sterrole.rbac.authorization.k8s.io/calico configured
kubelet apply should be used on resource created by either kubectl create --save-config or kubectl apply
(13)
解决kubectl apply -f calico.yaml执行时报的错
calico.yaml error converting yaml to json line 205 did not find expected ‘-’ indicator
配置文件的内容:
(14)
Calico同时支持Kubernetes API数据存储(kdd)和etcd数据存储
IPIP与BGP两种网络模式对比
IPIP
适用于互相访问的Pod不在同一个网段中,跨网段访问的场景,外层封装的IP能够解决跨网段的路由问题
BGP
使用路由信息导向流量,效率高
kubectl -n kube-system get po -owide
13
node节点kubelet 报错
flag–cgroup驱动程序已被弃用,应通过kubelet的–config标志指定的配置文件设置此参数。
命令未能解析kubelet标志:未知标志:–网络插件
(1)
rpm -qa | grep kube
各个版本不一致
需要降级:yum downgrade kubelet-1.17.4-0.x86_64
依旧报错
(2)
systemctl show --property=Environment kubelet \ cat
node节点加入k8s集群就正常了。
14
node节点加入k8s集群报错:
warning : joincontrolpane.controlplane settings will be ignored when control-plane flag is not set.
[preflight] running pre-flight checks
error execution phase preflight: couldn’t validate the identity of the api server :abort conneting to api server after timeout of
to see the stack trace of this error execute with --v=5 or higher
配置k8s的node节点【node节点操作】
10.1【node节点】
在其余工作节点 执行主节点的安装日志中的加入命令即可
向集群添加新节点,执行在kubeadm init输出的kubeadm join命令
10.2
默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,可以直接使用命令快捷生成(master节点):
kubeadm token create --print-join-command
可能会失效。建议创建永久token
10.3
#创建永久的token:kubeadm token create --ttl=0
#获取token_hash值 :openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der |openssl dgst -sha256 -hex
node节点执行以下命令后可以在master节点查看:
master节点
执行全部完成后,node节点的kubelet也运行起来了。
注:不确定加入k8s集群成功是不是因为执行了kubectl apply calico.yaml
等Calico Pod都Running后,节点也会准备就绪。
注:以后所有yaml文件都只在Master节点执行。
安装目录:/etc/kubernetes/
组件配置文件目录:/etc/kubernetes/manifests/
10
部署Dashboard
(1)
Dashboard是官方提供的一个UI,可用于基本管理K8s资源。
每个dashboard 与k8s 的匹配度不一样,可以在以下连接中查看版本
https://github.com/kubernetes/dashboard/releases?page=2
(2)
我的k8s是v1.17版本,所以
YAML下载地址(/etc/kubernetes/):
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc7/aio/deploy/recommended.yaml
之后执行kubelet apply -f recommended.yaml
(3)
查看是否安装成功
kubectl get pod -n kubernetes-dashboard
(4)
默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
修改后
(5)
查看dashboard外网访问端口查看
kubectl get svc -A | grep kubenetes-dashboard
(6)
服务器上部署dashboard,防火墙或者安全组要开放相关端口,例如小编需要释放32431端口;
浏览器输入https://Node节点IP:32431进入登录页面;
(7)
创建dashboard-account.yaml文件
vim dashboard-account.yaml
创建service account并绑定默认cluster-admin管理员集群角色:
主要内容是创建admin-user账户,并授予集群管理权限;
kubectl apply -f dash-user.yaml
(8)
获取账户token
命令kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath=“{.secrets[0].name}”) -o go-template=“{{.data.token | base64decode}}”
kubectl -n kubernetes-dashboard get secret
kubectl -n kubernetes-dashboard get sa/admin-user
kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath=“{.secrets[0].name}”
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath=“{.secrets[0].name}”)
可以将输出的token >>输出到日志中,复制到本地
使用输出的token登录Dashboard,就可以管理pod
注:查看各个组件证书过期时间,使用kubeadm会用证书过期的问题,一般一年左右
kubeadm certs check-expiration
更多推荐
所有评论(0)