k8s17.3二进制部署-test
K8s简介
Kubernetes(简称k8s)是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了资源调度、部署管理、服务发现、扩容缩容、监控,维护等一整套功能。,努力成为跨主机集群的自动部署、扩展以及运行应用程序容器的平台。 它支持一系列容器工具, 包括Docker等。
# kubernetes
注意 本文所有操作均在所有节点执行
本文环境
名称 | 配置 |
---|---|
Kubernetes版本 | v1.17.3 |
Cluster Pod CIDR | 10.244.0.0/16 |
Cluster Service CIDR | 10.250.0.0/24 |
kubernetes service | 10.250.0.1 |
dns service | 10.250.0.10 |
本文档主要介绍在裸机环境下以二进制的方式安装部署kubernetes
本次文档主要是对于kubernetes 1.17.3版本
内容主要有环境准备安装配置docker 升级内核 调整系统参数
环境准备
主机名 | IP | 组件 | 配置 |
---|---|---|---|
k8s-master1 | 192.168.220.101 | apiserver、controller-manager、schedule、docker-ce | 2核 4G |
k8s-master2 | 192.168.220.102 | apiserver、controller-manager、schedule、docker-ce | 2核 4G |
k8s-node1 | 192.168.220.103 | kube-proxy、kubelet、docker-ce,etcd | 2核 4G |
k8s-node1 | 192.168.220.104 | kube-proxy、kubelet、docker-ce,etcd | 2核 4G |
k8s-node1 | 192.168.220.105 | kube-proxy、kubelet、docker-ce,etcd | 2核 4G |
以下操作除非具体说明的步骤 其他的均在所有节点执行
环境变量
此环境变量为主节点(控制节点)的主机名和IP地址
1 | export VIP=192.168.220.100 |
SSH免密/时间同步/主机名修改
· SSH免密
· NTP时间同步
· 主机名修改
· 环境变量生成
· Host 解析
这里需要说一下,所有的密钥分发以及后期拷贝等都在master1上操作,因为master1做免密了
k8s集群所有的机器都需要进行host解析
1 | cat >> /etc/hosts << EOF |
批量免密
# 做免密前请修改好主机名对应的host
1 | yum -y install expect |
切记所有机器需要自行设定ntp,否则不只HA下apiserver通信有问题,各种千奇百怪的问题。
1 | yum -y install ntp |
测试通信
1 | for i in k8s-master1 k8s-master2 k8s-node1 k8s-node2 k8s-node3; do ssh root@$i "hostname";done |
升级内核
安装内核语言编译器(内核是用perl语言编写的)
1 | yum -y install perl |
下载密钥和yum源
导入密钥
1 | rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org |
安装7版本的yum源文件
1 | yum -y install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm |
安装 ml版本 5版本的内核名字叫ml
1 | yum --enablerepo="elrepo-kernel" -y install kernel-ml.x86_64 |
附:4.4版本内核安装方法
1 | yum --enablerepo="elrepo-kernel" -y install kernel-lt.x86_64 |
然后配置从新的内核启动
1 | grub2-set-default 0 |
然后重新生成grub2.cfg 使虚拟机使用新内核启动
1 | grub2-mkconfig -o /boot/grub2/grub.cfg |
调整系统内核参数
1 | cat > /etc/sysctl.conf <<EOF |
然后执行sysctl -p 使配置的内核响应参数生效
1 | sysctl -p |
关闭防火墙、selinux、swap、NetworkManager
1 | systemctl stop firewalld |
修改资源限制
1 | echo "* soft nofile 65536" >> /etc/security/limits.conf |
常用软件安装
1 | yum -y install bridge-utils chrony ipvsadm ipset sysstat conntrack libseccomp wget tcpdump screen vim nfs-utils bind-utils wget socat telnet sshpass net-tools sysstat lrzsz yum-utils device-mapper-persistent-data lvm2 tree nc lsof strace nmon iptraf iftop rpcbind mlocate ipvsadm |
加载内核ipvs模块
1 | cat > /etc/sysconfig/modules/ipvs.modules <<EOF |
安装docker-ce:
添加yun源
1 | tee /etc/yum.repos.d/docker-ce.repo <<-'EOF' |
安装docker-ce
1 | yum -y install docker-ce |
重启docker并设置为开机自启
1 | systemctl daemon-reload |
然后重启系统 验证内核是否升级成功
下载命令
下载cfssl以及cfssljson命令
此举目的是下载创建证书以及配置文件需要的命令
PKI基础概念
什么是PKI?
公开密钥基础建设(英语:Public Key Infrastructure,缩写:PKI),又称公开密钥基础架构、公钥基础建设、公钥基础设施、公开密码匙基础建设或公钥基础架构,是一组由硬件、软件、参与者、管理政策与流程组成的基础架构,其目的在于创造、管理、分配、使用、存储以及撤销数字证书。(节选维基百科)
PKI是借助CA(权威数字证书颁发/认证机构)将用户的个人身份跟公开密钥链接在一起,它能够确保每个用户身份的唯一性,这种链接关系是通过注册和发布过程实现,并且根据担保级别,链接关系可能由CA和各种软件或在人为监督下完成。PKI用来确定链接关系的这一角色称为RA(Registration Authority, 注册管理中心),RA能够确保公开密钥和个人身份链接,可以防抵赖,防篡改。在微软的公钥基础建设下,RA又被称为CA,目前大多数称为CA。
PKI组成要素
从上面可以得知PKI的几个主要组成要素,用户(使用PKI的人或机构),认证机构(CA,颁发证书的人或机构),仓库(保存证书的数据库)等。
非对称加密
本文提到的密钥均为非对称加密,有公钥和私钥之分,并且他们总是成对出现,它们的特点就是其中一个加密的数据,只能使用另一个解密,即使它本身也无法解密,也就是说公钥加密的,私钥可以解密,私钥加密的,公钥可以解密。
证书签名请求CSR
它是向CA机构申请数字证书时使用的请求文件,这里的CSR不是证书,而向权威证书颁发机构获得签名证书的申请,当CA机构颁发的证书过期时,你可以使用相同的CSR来申请新的证书,此时key不变。
数字签名
数字签名就是“非对称加密+摘要算法”,其目的不是为了加密,而是为了防抵赖或者他们篡改数据。其核心思想是:比如A要给B发送数据,A先用摘要算法得到数据的指纹,然后用A的私钥加密指纹,加密后的指纹就是A的签名,B收到数据和A的签名后,也用同样的摘要算法计算指纹,然后用A公开的公钥解密签名,比较两个指纹,如果相同,说明数据没有被篡改,确实是A发过来的数据。假设C想改A发给B的数据来欺骗B,因为篡改数据后指纹会变,要想跟A的签名里面的指纹一致,就得改签名,但由于没有A的私钥,所以改不了,如果C用自己的私钥生成一个新的签名,B收到数据后用A的公钥根本就解不开。(来源于网络)
数字证书格式
数字证书格式有很多,比如.pem,.cer或者.crt等。
PKI工作流程
下图来源于网络,上半部分最右边就是CA机构,可以颁发证书。证书订阅人,首先去申请一个证书,为了申请这个证书,需要去登记,告诉它,我是谁,我属于哪个组织,到了登记机构,再通过CSR,发送给CA中心,CA中心通过验证通过之后 ,会颁发一对公钥和私钥,并且公钥会在CA中心存一份;证书订阅人拿到证书以后,部署在服务器;
当用户访问我们的web服务器时,它会请求我们的证书,服务器会把公钥发送给我们的客户端,客户端会去验证我们证书的合法性,客户端是如何验证证书是否有效呢?CA中心会把过期证书放在CRL服务器上面 ,这个CRL服务会把所有过期的证书形成一条链条,所以他的性能非常的差,所以又推出了OCSP程序,OCSP可以就一个证书进行查询,它是否过期,浏览器可以直接去查询OCSP响应程序,但OCSP响应程序效率还不是很高,最终往往我们会把web服务器如nginx有一个ocsp开关,当我们打开这个开关以后,会有nginx服务器主动的去ocsp服务器去查询,这样大量的客户端直接从web服务器就可以直接获取到证书是否有效。
CFSSL介绍
CFSSL是什么?
cfssl是使用go编写,由CloudFlare开源的一款PKI/TLS工具。主要程序有cfssl,是CFSSL的命令行工具,cfssljson用来从cfssl程序获取JSON输出,并将证书,密钥,CSR和bundle写入文件中。
安装CFSSL
安装 cfssl 工具集
1 | sudo mkdir -p /opt/k8s/{work,bin,cert} && cd /opt/k8s/work |
生成证书
注意 本文所有操作均在master1节点执行
创建配置文件
CA 配置文件用于配置根证书的使用场景 (profile) 和具体参数 (usage,过期时间、服务端认证、客户端认证、加密等):
1 | cat > ca-config.json << EOF |
- signing :表示该证书可用于签名其它证书(生成的 ca.pem 证书中CA=TRUE );
- server auth :表示 client 可以用该该证书对 server 提供的证书进行验证;
- client auth :表示 server 可以用该该证书对 client 提供的证书进行验证;
- “expiry”: “876000h” :证书有效期设置为 100 年;
创建证书签名请求文件
1 | cd /opt/k8s/work |
- CN:Common Name :kube-apiserver 从证书中提取该字段作为请求的用户名(User Name),浏览器使用该字段验证网站是否合法;
- O:Organization :kube-apiserver 从证书中提取该字段作为请求用户所属的组(Group);
- kube-apiserver 将提取的 User、Group 作为 RBAC 授权的用户标识;
注意:
- 不同证书 csr 文件的 CN、C、ST、L、O、OU 组合必须不同,否则可能出现PEER’S CERTIFICATE HAS AN INVALID SIGNATURE 错误;
- 后续创建证书的 csr 文件时,CN 都不相同(C、ST、L、O、OU 相同),以达到区分的目的;
生成 CA 证书和私钥
1 | cd /opt/k8s/work |
分发证书文件
1 | cd /opt/k8s/work |
安装和配置 kubectl
本文档只需要部署一次,生成的 kubeconfig 文件是通用的,可以拷贝到需要执行kubectl 命令的机器的 ~/.kube/config 位置;
下载和分发 kubectl 二进制文件
1 | #一次性下载 |
分发到所有使用 kubectl 工具的节点:(master)
将命令分发到master节点/opt/k8s/bin
下,并添加PATH export PATH=/opt/k8s/bin:$PATH
创建 admin 证书和私钥
kubectl 使用 https 协议与 kube-apiserver 进行安全通信,kube-apiserver 对 kubectl 请求包含的证书进行认证和授权。
kubectl 后续用于集群管理,所以这里创建具有最高权限的 admin 证书。
创建证书签名请求:
1 | cd /opt/k8s/cert |
- O: system:masters :kube-apiserver 收到使用该证书的客户端请求后,为请求添加组(Group)认证标识 system:masters ;
- 预定义的 ClusterRoleBinding cluster-admin 将 Group system:masters 与Role cluster-admin 绑定,该 Role 授予操作集群所需的最高权限;
- 该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;
生成证书和私钥:
1 | cd /opt/k8s/cert |
- 忽略警告消息 [WARNING] This certificate lacks a “hosts” field. ;
创建 kubeconfig 文件
kubectl 使用 kubeconfig 文件访问 apiserver,该文件包含 kube-apiserver 的地址和认证信息(CA 证书和客户端证书):
1 | cd /opt/k8s/work |
- –certificate-authority :验证 kube-apiserver 证书的根证书;
- –client-certificate 、 –client-key :刚生成的 admin 证书和私钥,与kube-apiserver https 通信时使用;
- –embed-certs=true :将 ca.pem 和 admin.pem 证书内容嵌入到生成的kubectl.kubeconfig 文件中(否则,写入的是证书文件路径,后续拷贝 kubeconfig 到其它机器时,还需要单独拷贝证书文件,不方便。);
- –server :指定 kube-apiserver 的地址,这里指向第一个节点上的服务;
分发 kubeconfig 文件
1 | mkdir -p ~/.kube |
部署 etcd 集群
etcd 是基于 Raft 的分布式 KV 存储系统,由 CoreOS 开发,常用于服务发现、共享配置以及并发控制(如 leader 选举、分布式锁等)。
kubernetes 使用 etcd 集群持久化存储所有 API 对象、运行数据。
本文档介绍部署一个三节点高可用 etcd 集群的步骤:
- 下载和分发 etcd 二进制文件;
- 创建 etcd 集群各节点的 x509 证书,用于加密客户端(如 etcdctl) 与 etcd 集群、etcd 集群之间的通信;
- 创建 etcd 的 systemd unit 文件,配置服务参数;
- 检查集群工作状态;
etcd 集群节点名称和 IP 如下:
1 | k8s-01:192.168.220.100 |
注意:
- 如果没有特殊指明,本文档的所有操作均在k8s-01 节点上执行;
- flanneld 与本文档安装的 etcd v3.4.x 不兼容,如果要安装 flanneld(本文档使用calio),则需要将 etcd 降级到 v3.3.x 版本;
下载和分发 etcd 二进制文件
到 etcd 的 release 页面 下载最新版本的发布包:
1 | cd /opt/k8s/work |
分发二进制文件到集群所有节点:
1 | cd /opt/k8s/work |
创建 etcd 证书和私钥
创建证书签名请求:
1 | cd /opt/k8s/work |
- hosts :指定授权使用该证书的 etcd 节点 IP 列表,需要将 etcd 集群所有节点 IP都列在其中;
生成证书和私钥:
1 | cd /opt/k8s/work |
分发生成的证书和私钥到各 etcd 节点:
1 | cd /opt/k8s/work |
创建 etcd 的 systemd unit 模板文件
1 | cd /opt/k8s/work |
- WorkingDirectory 、 –data-dir :指定工作目录和数据目录为${ETCD_DATA_DIR} ,需在启动服务前创建这个目录;
- –wal-dir :指定 wal 目录,为了提高性能,一般使用 SSD 或者和 –data-dir 不同的磁盘;
- –name :指定节点名称,当 –initial-cluster-state 值为 new 时, –name 的参数值必须位于 –initial-cluster 列表中;
- –cert-file 、 –key-file :etcd server 与 client 通信时使用的证书和私钥;
- –trusted-ca-file :签名 client 证书的 CA 证书,用于验证 client 证书;
- –peer-cert-file 、 –peer-key-file :etcd 与 peer 通信使用的证书和私钥;
- –peer-trusted-ca-file :签名 peer 证书的 CA 证书,用于验证 peer 证书;
为各节点创建和分发 etcd systemd unit 文件
替换模板文件中的变量,为各节点创建 systemd unit 文件:
1 | cd /opt/k8s/work |
- NODE_NAMES 和 NODE_IPS 为相同长度的 bash 数组,分别为节点名称和对应的 IP;
分发生成的 systemd unit 文件:
1 | cd /opt/k8s/work |
启动 etcd 服务
1 | cd /opt/k8s/work |
- 必须先创建 etcd 数据目录和工作目录;
- etcd 进程首次启动时会等待其它节点的 etcd 加入集群,命令 systemctl startetcd 会卡住一段时间,为正常现象;
检查启动结果
1 | cd /opt/k8s/work |
确保状态为 active (running) ,否则查看日志,确认原因:
1 | journalctl -u etcd |
验证服务状态
部署完 etcd 集群后,在任一 etcd 节点上执行如下命令:
1 | cd /opt/k8s/work |
- 3.4.3 版本的 etcd/etcdctl 默认启用了 V3 API,所以执行 etcdctl 命令时不需要再指定环境变量 ETCDCTL_API=3 ;
- 从 K8S 1.13 开始,不再支持 v2 版本的 etcd;
预期输出:
输出均为 healthy 时表示集群服务正常。
查看当前的 leader
1 | source /opt/k8s/bin/environment.sh |
输出:
- 可见,当前的 leader 为192.168.220.100。