天天看点

kubernetes二进制部署单master节点

在开始之前,部署kubernetes集群机器需要满足以下几个条件:

三台机器,操作系统 centos7.7(mini)

硬件配置:2gbram,2vcpu+,硬盘30gb+

集群中所有机器之间网络互通,且可访问外网。

采用nat网络模型(依自己情况而定)

角色

ip

master

192.168.50.128

node0

node1

192.168.50.131

node2

192.168.50.132

软件

版本

docker

19.03.12

kubernetes

1.18.6

etcd

3.4.9

主机

安装组件

kube-apiserver,kube-controller-manager,kube-scheduler,etcd

kubelet,kube-proxy,etcd

master节点设置:

node1从节点设置:

node2从节点设置:

根据自己的节点命名情况来设置即可。

所有的节点都要添加hosts解析记录

在master1节点生成密钥对,并分发给其他的所有主机。

分发公钥

通过下载kernel image的rpm包进行安装。

centos7:<code>http://elrepo.org/linux/kernel/el7/x86_64/rpms/</code>

kubernetes二进制部署单master节点

编写shell脚本升级内核

注意:一定要重启机器

验证内核版本

第一条是临时关闭,当然也可以使用第二条永久关闭,后者手动在<code>/etc/fstab</code>文件中将<code>swap</code>挂载所在的行注释掉即可。

使其立即生效

所有的节点均采用阿里云官网的base和epel源

将上面的第5-8步骤写成shell脚本自动化快速完成

在其他的节点执行此脚本跑一下即可。

​ <code>etcd</code> 是一个分布式键值存储系统,kubernetes使用<code>etcd</code>进行状态和数据存储,因此我们需要提前准备好<code>etcd</code>,不过为解决<code>etcd</code>单点故障问题,应采用集群方式部署,这里使用3台组建集群。

​ 为了节约资源利用,我这里复用了两个node节点,这样子这三台主机便可组建一个集群。当然,建议是独立于k8s集群之外部署,毕竟数据很重要。

etcd节点名称

etcd-01

etcd-02

etcd-03

​ 在kubernetes中,使用<code>openssl</code>生成证书会及其麻烦,如果我们可以把预先的证书机构、使用期等时间写在json文件里面会更加高效和自动化。而<code>cfssl</code>就是这样的一款工具,<code>cfssl</code>采用go语言编写,是一个开源的证书管理工具,cfssljson用来从cfssl程序获取json输出,并将证书,密钥,csr和bundle写入文件中。

在master节点操作:

授权并重命名:

移动到环境变量<code>/usr/local/bin</code>目录下

由于kubernetes各组件需要使用x509证书对通信进行加密和认证,所以需要创建一套ca(certificate autority),是自签名的根证书,用来签名后续需要创建的其它证书;

这里创建的ca是一个私有的内部认证中心,这个认证中心也需要一个ca证书和相应的ca私钥,ca私钥需要妥善保管,任何拥有它的人,都可以充当ca颁发证书。

再次强调一下,ca证书的请求json文件是集群所有节点共享的,只需要创建一个,它后续创建的所有其它子ca证书的基础,子ca证书都会根据这里config中的<code>profile</code>段来生成证书的相关信息;

ca-config.json 这个配置文件只是告诉我们颁发有什么功能的证书,它用于配置证书的使用场景(profile)和具体参数(usage、过期时间、服务端认证、客户端认证、加密等)。 default是默认策略,指定证书默认有效期是10年; profiles是定义使用场景,这里只是kubernetes,其实可以定义多个场景,分别指定不同的过期时间,使用场景等参数,后续签名证书时使用某个profile; signing: 表示该证书可用于签名其它证书,生成的ca.pem证书中的ca=true; server auth: 表示client 可以用该ca 对server 提供的证书进行校验; client auth: 表示server 可以用该ca 对client 提供的证书进行验证。
gencert:生成新的key(密钥)和签名证书 --initca:初始化一个新ca
<code>hosts</code>字段中ip为所有etcd节点的集群内部通信ip,有几个etcd节点,就写多少个ip。当然,为方便后期扩容可以多些几个预留的ip。
<code>gencert</code>: 生成新的key(密钥)和签名证书 <code>-initca</code>:初始化一个新ca <code>-ca</code>:指明ca的证书 <code>-ca-key</code>:指明ca的私钥文件 -<code>config</code>:指明请求证书的json文件 <code>-profile</code>:与<code>config</code>中的<code>profile</code>对应,是指根据<code>config</code>中的<code>profile</code>段来生成证书的相关信息

将前面两步创建的证书都分发给其他etcd节点。

写一个shell脚本,先在目标主机创建存放etcd证书的目录,接着复制证书

补充:事实上只需要分发<code>ca.pem</code>公钥即可,<code>ca-key.pem</code>是私钥,很多组件不需要,除非你确保使用它,你才分发到服务器上面,以免造成私钥泄露。不过我们不需要考虑太多,所以把私钥也分发到了服务器上面。

以下在节点1操作,部署完成后,将节点1生成的所有的文件拷贝到节点2和节点3

这里解释一下配置

配置选项

选项说明

<code>etcd_name</code>

节点名称,如果<code>etcd_initial_cluster_state="new"</code>这个值为<code>new</code>,哪么<code>etcd_name</code>的参数值必须位于<code>etcd_initial_cluster</code>列表中

<code>etcd_data_dir</code>

指定节点的数据存储目录(包括:节点id、集群id、集群初始化配置、snapshot文件等),如果未指定,会写在当前目录

<code>etcd_listen_peer_urls</code>

与集群其它成员之间的通信地址

<code>etcd_listen_client_urls</code>

监听本地端口,对外提供服务的地址

<code>etcd_initial_advertise_peer_urls</code>

通告给集群其它节点,本地的对等url地址

<code>etcd_advertise_client_urls</code>

客户端url,用于通告集群的其余部分信息

<code>etcd_initial_cluster</code>

集群中的所有信息节点

<code>etcd_initial_cluster_token</code>

集群的token,整个集群中保持一致

<code>etcd_initial_cluster_state</code>

初始化集群状态,默认为<code>new</code>

说明一下etcd服务启动几个选项的意义:

<code>--cert-file</code>

客户端与服务器之间tls证书文件的路径

<code>--key-file</code>

客户端与服务器之间tls密钥文件的路径

<code>--peer-cert-file</code>

对等服务器tls证书文件的路径

--peer-key-file`

对等服务器tls密钥文件的路径

<code>--trusted-ca-file</code>

签名client证书的ca证书,用于验证client证书

<code>--peer-trusted-ca-file</code>

签名对等服务器证书的ca证书。

节点1的配置文件和systemd启动脚本都设置好了,所以现在传输一下节点2和节点3的服务配置

其他另外节点2和节点3分别修改etcd.conf配置文件中的节点名称和当前服务器ip

节点2的etcd配置文件

节点3的etcd配置文件

在master节点执行一个脚本来。

查看集群状态

如果打印的每个etcd节点显示都为<code>healthy</code>,说明集群部署成功。如有问题就查messages日志

查看集群成员

所有node节点都部署docker服务

方法:浏览器打开<code>mirrors.aliyun.com</code>网站,找到docker-ce,即可看到镜像仓库yum源

kubernetes二进制部署单master节点

写个脚本执行方便

列出所有可以安装的版本

这里我们安装18.09版本的docker-ce

查看版本号,检测docker是否安装成功

上面的这种查看docker client的版本的。建议使用下面这种方法查看docker-ce版本号,这种方法把docker的client端和server端的版本号查看的一清二楚。

默认的镜像仓库地址是docker官方的,国内访问异常缓慢,因此更换为个人阿里云的源。

由于重新加载docker仓库源,所以需要重启docker

我们操作的流程是

制作集群证书

部署<code>kube-apiserver</code>组件

部署<code>kube-controller-manager</code>组件

部署<code>kube-scheduler</code>组件

现在我们创建一套kubernetes集群的根ca证书。用于签发所有的k8s组件。

将上面临时目录生成的证书都复制在kubernetes的证书目录下:

kubernetes现托管在github上面,我们可以看到kubernetes任何版本的更新、下载等信息

kubernetes二进制部署单master节点

点击右侧的<code>releases</code>按钮,即可看到k8s版本,可以看到目前已经发布了671次版本。

kubernetes二进制部署单master节点

目前最新的文档版本是1.18.5。不过这节课我演示的是1.18.4版本。

只需要下载一个server包就够了,包含了master和worker node二进制文件

详情介绍:<code>https://github.com/kubernetes/kubernetes/blob/master/changelog/changelog-1.18.md</code>

下载链接:<code>https://dl.k8s.io/v1.18.4/kubernetes-server-linux-amd64.tar.gz</code>

考虑到科学上网问题,因此给大家介绍一个链接:<code>https://storage.googleapis.com/kubernetes-release/release/v1.18.4/kubernetes-server-linux-amd64.tar.gz</code>

kubernetes证书路径是<code>/etc/kubernetes/ssl</code> 配置文件路径是<code>/etc/kubernetes/cfg</code> 二进制可执行程序包直接放在环境变量<code>/usr/local/bin</code> 日志路径是<code>/var/log/kubernetes</code>

创建<code>kube-apiserver</code>配置文件

为了使用eof保留换行符,所以要写两个<code>\\</code>

配置文件详细解释如下:

<code>--logtostderr=false</code>

输出日志到文件中(文件路径由<code>--log-dir</code>指定),不输出到标准错误控制台

<code>--v=2</code>

指定输出日志的级别

<code>--advertise-address</code>

向集群成员通知 apiserver 消息的 ip 地址,这个地址必须能够被集群中其他成员访问,如果 ip 地址为空,将会使用 <code>--bind-address</code>,如果未指定<code>--bind-address</code>,将会使用主机的默认接口地址

<code>--etcd-servers</code>

连接的 etcd 服务器列表 , 形式为(<code>scheme://ip:port</code>),使用逗号分隔

<code>--etcd-cafile</code>

用于etcd 通信的 ssl ca 文件

<code>--etcd-certfile</code>

用于 etcd 通信的的 ssl 证书文件

<code>--etcd-keyfile</code>

用于 etcd 通信的 ssl 密钥文件

<code>--service-cluster-ip-range</code>

service网络地址分配 ,cidr 表示的 ip 范围,服务的 cluster ip 将从中分配, 一定不要和分配给 nodes 和 pods 的 ip 范围产生重叠

<code>--bind-address</code>

监听 --seure-port 的 ip 地址,被关联的接口必须能够被集群其它节点和 cli/web 客户端访问,如果为空,则将使用所有接口(<code>0.0.0.0</code>)

<code>--secure-port=6443</code>

用于监听具有认证授权功能的 https 协议的端口,默认值是6443

<code>--allow-privileged</code>

是否启用授权功能

--service-node-port-range

service使用的端口范围

<code>--default-not-ready-toleration-seconds</code>

表示 notready状态的容忍度秒数

<code>--default-unreachable-toleration-seconds</code>

表示 unreachable状态的容忍度秒数:

<code>--max-mutating-requests-inflight=2000</code>

在给定时间内进行中可变请求的最大数量,当超过该值时,服务将拒绝所有请求,0 值表示没有限制(默认值 200)

<code>--default-watch-cache-size=200</code>

默认监视缓存大小,0 表示对于没有设置默认监视大小的资源,将禁用监视缓存

<code>--delete-collection-workers=2</code>

用于 deletecollection 调用的工作者数量,这被用于加速 namespace 的清理( 默认值 1)

<code>--enable-admission-plugins</code>

资源限制的相关配置

<code>--authorization-mode</code>

在安全端口上进行权限验证的插件的顺序列表,以逗号分隔的列表,包括:alwaysallow,alwaysdeny,abac,webhook,rbac,node.(默认值 "alwaysallow")

<code>--enable-bootstrap-token-auth</code>

启用此选项以允许 'kube-system' 命名空间中的<code>'bootstrap.kubernetes.io/token'</code> 类型密钥可以被用于 tls 的启动认证

<code>--token-auth-file</code>

声明bootstrap token文件

<code>--kubelet-certificate-authority</code>

证书 authority 的文件路径

<code>--kubelet-client-certificate</code>

用于 tls 的客户端证书文件路径

<code>--kubelet-client-key</code>

用于 tls 的客户端证书密钥文件路径

<code>--tls-private-key-file</code>

包含匹配<code>--tls-cert-file</code>的 x509 证书私钥的文件

--service-account-key-file

包含 pem 加密的 x509 rsa 或 ecdsa 私钥或公钥的文件,用于验证 serviceaccount 令牌,如果设置该值,--tls-private-key-file 将会被使用,指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用

<code>--audit-log-maxage</code>

基于文件名中的时间戳,旧审计日志文件的最长保留天数

<code>--audit-log-maxbackup</code>

旧审计日志文件的最大保留个数

<code>--audit-log-maxsize</code>

审计日志被轮转前的最大兆字节数

<code>--audit-log-path</code>

如果设置,表示所有到apiserver的请求都会记录到这个文件中,‘-’表示写入标准输出

当集群开启了 tls 认证后,每个节点的 kubelet 组件都要使用由 apiserver 使用的 ca 签发的有效证书才能与 apiserver 通讯;此时如果节点多起来,为每个节点单独签署证书将是一件非常繁琐的事情; tls bootstrapping 功能就是让 node节点上的kubelet组件先使用一个预定的低权限用户连接到 apiserver,然后向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署;

把上面的token值拿下来,后面的照着写就行。

上面的变量引用符号<code>$</code>前面加上转义符<code>\</code>,这是在使用eof写入文件需要注意的地方。
kube-controller-manager(k8s控制器管理器)是一个守护进程,它通过kube-apiserver监视集群的共享状态(kube-apiserver收集或监视到的一些集群资源状态,供kube-controller-manager或其它客户端watch), 控制器管理器并尝试将当前的状态向所定义的状态迁移(移动、靠近),它本身是有状态的,会修改集群状态信息,如果多个控制器管理器同时生效,则会有一致性问题,所以kube-controller-manager的高可用,只能是主备模式,而kubernetes集群是采用租赁锁实现leader选举,需要在启动参数中加入 <code>--leader-elect=true</code>。

选项意义

<code>--leader-elect</code>

高可用时启用选举功能。这里只有一个controller-manager,所以不需要启用选举功能

<code>--master</code>

通过本地非安全本地端口8080连接apiserver

监控地址

<code>--allocate-node-cidrs</code>

是否应在node节点上分配和设置pod的cidr

<code>--cluster-cidr</code>

controller manager在启动时如果设置了--cluster-cidr参数,那么为每个没有设置spec.podcidr的node节点生成一个cidr地址,并用该cidr地址设置节点的spec.podcidr属性,防止不同的节点的cidr地址发生冲突

集群services 的cidr范围

<code>--cluster-signing-cert-file</code>

指定用于集群签发的所有集群范围内证书文件(根证书文件)

<code>--cluster-signing-key-file</code>

指定集群签发证书的key

<code>--root-ca-file</code>

如果设置,该根证书权限将包含service acount的toker secret,这必须是一个有效的pem编码ca 包

<code>--service-account-private-key-file</code>

包含用于签署service account token的pem编码rsa或者ecdsa私钥的文件名

<code>--experimental-cluster-signing-duration</code>

证书签发时间

调度器的职责主要是为新创建的pod在集群中寻找最合适的node,并将pod调度到node上,scheduler调度器运行在master节点,它的核心功能是监听apiserver来获取节点上为空的pod,然后为pod创建一个binding指示pod应该调度到哪个节点上,调度结果写入apiserver。

所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态:

看到第二列的状态值都是<code>healthy</code>,说明master节点组件运行正常。

对于我们这里的二进制部署的一主多从,在企业中适合测试环境,因此为了更多的复用机器资源,主master节点也应该作为node节点跑pod。

下面依然在master这个节点上操作,让其再成为节点

复制二进制包

将kubernetes解压的二进制包程序<code>kubelet,kube-proxy</code>复制到本地环境变量路径下。

配置文件解释说明

<code>--hostname-override</code>

用来配置该节点在集群中显示的主机名,kubelet设置了<code>-–hostname-override</code>参数后,<code>kube-proxy</code>也需要设置,否则会出现找不到node的情况

<code>--container-runtime</code>

指定容器运行时引擎

<code>--network-plugin</code>

启用cni网络插件

<code>--kubeconfig</code>

kubelet作为客户端使用的kubeconfig认证文件,此文件是由kube-controller-mananger生成的

<code>--bootstrap-kubeconfig</code>

指定令牌认证文件

<code>--config</code>

指定kubelet配置文件

<code>--cert-dir</code>

设置<code>kube-controller-manager</code>生成证书和私钥的目录

<code>--image-pull-progress-deadline</code>

镜像拉取进度最大时间,如果在这段时间拉取镜像没有任何进展,将取消拉取,默认:1m0s

<code>--pod-infra-container-image</code>

每个pod中的<code>network/ipc</code>名称空间容器将使用的镜像

简单说几个比较重要的选项配置意义

<code>address</code>

kubelet 服务监听的地址

<code>port: 10250</code>

kubelet 服务的端口,默认 <code>10250</code>

<code>readonlyport</code>

没有认证/授权的只读 kubelet 服务端口 ,设置为 0 表示禁用,默认 `10255

<code>clusterdns</code>

dns 服务器的ip地址列表

<code>clusterdomain</code>

集群域名, kubelet 将配置所有容器除了主机搜索域还将搜索当前域

生成 kubelet bootstrap kubeconfig 配置文件

拷贝到配置文件路径<code>/etc/kubernetes/cfg</code>

cni,全名叫做:容器网络接口。是cncf旗下的一个项目,由一组用于配置容器的网络接口的规范和库组成。cni主要用于解决容器网络互联的配置并支持多种网络模型。

此命令可以看到所有请求,所有为<code>pending</code>状态,则是需要批准的。

把上面的命令的<code>name</code>字段的值拿过来。

查看节点

注意:这里的<code>status</code>状态值还是<code>notready</code>,是因为网络插件还没有部署好。接着往下即可。
kube-proxy是什么,这里就不得不提前说下service,service是一组pod的抽象集合,它相当于一组pod的负载均衡器,负责将请求分发到对应的pod,kube-proxy就是负责service的实现的,当请求到达service时,它通过label关联到后端并转发到某个pod;kube-proxy提供了三种负载均衡模式:用户空间、iptables、ipvs,我们采用的是iptables负载均衡模式。

简单说一下上面配置的选项意义

选项配置

clientconnection

与kube-apiserver交互时的参数设置

burst: 200

临时允许该事件记录值超过qps设定值

kubeconfig

kube-proxy 客户端连接 kube-apiserver 的 kubeconfig 文件路径设置

qps: 100

与kube-apiserver交互时的qps,默认值5

bindaddress

kube-proxy监听地址

healthzbindaddress

用于检查服务的ip地址和端口

metricsbindaddress

metrics服务的ip地址和端口。默认:127.0.0.1:10249

clustercidr

kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 kube-proxy 才会对访问 service ip 的请求做 snat

hostnameoverride

参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 node,从而不会创建任何 ipvs 规则;

创建证书请求文件

生成证书

kube-proxy是作为kube-apiserver的客户端,由于我们启用了tls,所以需要认证访问,这里我们需要使用到之前生成的证书。

拷贝到配置文件指定的路径下:

在执行kubectl exec、run、logs 等命令时,apiserver会转发到kubelet。这里定义 rbac规则,授权apiserver调用kubelet api"

​ flannel是 coreos 团队针对 kubernetes 设计的一个覆盖网络(overlay network)工具,其目的在于帮助每一个使用 kuberentes 的 coreos 主机拥有一个完整的子网。 flannel通过给每台宿主机分配一个子网的方式为容器提供虚拟网络,它基于<code>linux tun/tap</code>,使用udp封装ip包来创建overlay网络,并借助etcd维护网络的分配情况
事实上很多用户都不能成功,因为国内网络受限,所以可以这样子来做。 修改hosts文件,加上如下解析记录

编辑镜像源,默认的镜像地址我们修改一下。把yaml文件中所有的<code>quay.io</code>修改为 <code>quay-mirror.qiniu.com</code>

此时保存保存退出。在master节点执行此命令。

这样子就可以成功拉取flannel镜像了。当然你也可以直接使用我提供给大家的<code>kube-flannel.yml</code>文件

查看flannel是否正常

如果你想查看flannel这些pod运行是否正常,使用如下命令:

注意:稍等1-3分钟后,如果第三字段<code>status</code>不是处于<code>running</code>状态的话,并且<code>status</code>字段数值一直在渐渐变大,说明flannel是异常的,需要排查问题所在。

目前节点状态是<code>ready</code>,表示集群节点现在是可用的。

如果有以下报错:

或者是

上面的这些都表示是网络问题不能拉取镜像,我这里给大家提前准备了flannel的镜像。导入一下就可以了。

coredns用于集群中pod解析service的名字,kubernetes基于coredns用于服务发现功能。

安装coredns1.6.7(目前较新版本)。如果之前修改了podip的网段,那么这里需要自行修改此文件的clusterip参数。其他可保持不变

查看pod状态

只要能出结果,解析就是没有问题的。

在master节点操作,把文件远程复制给node节点

在node1节点上操作

修改为<code>--hostname-override-=node1</code>

修改为<code>hostnameoverride: node1</code>

下面的是在<code>master</code>节点操作的

上面的<code>condition</code>为<code>pending</code>状态的表示将要被加入集群的节点。所以记录前面的<code>name</code>字段

稍等两分钟

按照上面的前五步继续执行即可。做完之后如下所示:

至此,二进制单节点集群部署已经完成,接下来我们可以测试一下集群是否可用。

现在我们在kubernetes集群中创建一个nginx的pod,验证是否能正常运行。

在master节点执行一下步骤:

现在我们查看pod和service

kubernetes二进制部署单master节点

打印的结果中,前半部分是pod相关信息,后半部分是service相关信息。我们看<code>service/nginx</code>这一行可以看出service暴漏给集群的端口是<code>30249</code>。记住这个端口。

然后从pod的详细信息可以看出此时pod在<code>node2</code>节点之上。node2节点的ip地址是<code>192.168.50.132</code>

那现在我们访问一下。打开浏览器(建议火狐浏览器),访问地址就是:http://192.168.50.132:30249

kubernetes二进制部署单master节点

先把dashboard的配置文件下载下来。由于我们之前已经添加了hosts解析,因此可以下载。

默认dashboard只能集群内部访问,修改service为nodeport类型,暴露到外部:

大概在此文件的32-44行之间,修改为如下:

运行此yaml文件

主要是看<code>status</code>这一列的值,如果是<code>running</code>,并且<code>restarts</code>字段的值为0(只要这个值不是一直在渐渐变大),就是正常的,目前来看是没有问题的。我们可以继续下一步。

查看此dashboard的pod运行所在的节点

kubernetes二进制部署单master节点

从上面可以看出,<code>kubernetes-dashboard-9774cc786-ccvcf</code>运行所在的节点是<code>node2</code>上面,并且暴漏出来的端口是<code>30001</code>,所以访问地址是: https://192.168.50.132:30001

用火狐浏览器访问,访问的时候会让输入token,从此处可以查看到token的值。

kubernetes二进制部署单master节点

把上面的token值输入进去即可进去dashboard界面。

kubernetes二进制部署单master节点

不过现在我们虽然可以登陆上去,但是我们权限不够还查看不了集群信息,因为我们还没有绑定集群角色,同学们可以先按照上面的尝试一下,再来做下面的步骤

再次使用输出的token登陆dashboard即可。

kubernetes二进制部署单master节点
kubernetes二进制部署单master节点
k8s

继续阅读