3.2.2 K8S入门
3.2.2.1 K8S集群架构搭建及运行docker容器3.2.2.2 K8S基于二进制集群架构搭建13.2.2.3 K8S基于二进制集群架构搭建23.2.2.4 K8S基于二进制集群架构搭建3...
目录
3.2、在Kubernetes中,service对象的4个特征
5.2、设置master可以无密码登录所有节点的root账户
5.3、将可执行文件路径/opt/k8s/bin添加到PATH变量中
5.14、设置rsyslog和systemd journal
5.17、检查系统内核和模块是否适合运行docker(仅适用于linux系统)
5.18、分发集群环境变量定义脚本(扩容时不需要执行该步骤)
1.4、为各节点创建和分发etcd systemd unit文件
2.5、分发flanneld systemd unit文件到所有节点
3.2.2.1 K8S集群架构搭建及运行docker容器
1、Linux 操作系统原理
参考地址:https://product.pconline.com.cn/itbk/software/dnyw/1707/9626394.html
一个计算机系统是硬件、软件的共生体,它们互相依赖、不可分割。
1.1、计算机硬件
是由外围设备、处理器、内存、硬盘和其他电子设备组成的计算机发动机
1.2、操作系统
是控制硬件工作的,是用来和硬件打交道,为用户程序提供一个有限服务集的低级支撑软件。
1.3、Linux操作系统
在Linux中操作系统被称为“内核”,也称为“核心”。
Linux内核的主要模块(组件)分为以下7部分:
存储管理
CPU和进程管理
文件系统
设备管理和驱动
网络通信
系统的初始化(引导)
系统调用
Linux内核被设计为“单内核”(monolithic)结构
1.4、Linux系统的操作原理
1、一切都是文件
2、每个软件都有确定的用途
2、K8S 集群架构图
1、etcd:一个高可用的K/V键值对存储和服务发现系统
2、flannel:实现跨主机的容器网络的通信
3、kube-apiserver:提供kubernetes集群的API调用
4、kube-controller-manager:确保集群服务
5、kube-scheduler:调度容器,分配到Node
6、kubelet:在Node节点上按照配置文件中定义的容器规格 启动容器
7、kube-proxy:提供网络代理服务
3、K8S 集群部署架构
1个master + 2个node。存储集群etcd是单点集群(真实环境不推荐此做法,需要集群)。网络使用的是flannel虚拟二次网络。
3.1、Kubernetes的8个集群管理能力
1、多层次的安全防护和准入机制
2、多租户应用支撑能力
3、透明的服务注册和服务发现机制
4、内建智能负载均衡器
5、强大的故障发现和自我修复能力
6、服务滚动升级和在线扩容能力
7、可扩展的资源自动调度机制
8、以及多粒度的资源管理能力
3.2、在Kubernetes中,service对象的4个特征
1、拥有一个唯一指定的名字
eg:mysql-service
2、拥有一个虚拟IP和端口号
虚拟IP:Cluster IP、service IP、VIP
3、能够提供某种远程服务能力
4、被映射到提供这种服务能力的一组容器应用上
快速、在线体验kubernetes的功能:https://kubernetes.io/docs/tutorials/kubernetes-basics/
K8s官方下载地址:https://github.com/kubernetes
本文以下所有操作命令都参考老师的文档:E:\meWork\study\project\subject-3\subject-3-k8s\专题三-Kubernetes_学习文档-N.docx
4、集群环境配置说明
4.1、环境准备
节点 | ip 地址 | 操作系统 |
master |
| CentOS 7.8-x86_64 |
node1 |
| CentOS 7.8-x86_64 |
node2 |
| CentOS 7.8-x86_64 |
4.2、集群详情、组件版本
OS:CentOS Linux release 7.8.2003 (Core)
Kubernetes:1.12.3(最低的版本要求是1.6)
Docker:18.09.0-ce(建议使用 Docker CE)
Etcd:3.3.10
Flannel:v0.10.0 (vxlan或者host-gw 网络)
TLS 认证通信 (所有组件,如 etcd、kubernetes master 和 node)
RBAC 授权
kubelet TLS BootStrapping
插件:Coredns、dashboard、heapster(influxdb、grafana)、Metrics-Server、EFK(elasticsearch、fluentd、kibana)
镜像仓库:docker registry、harbor
私有docker镜像仓库harbor(harbor提供离线安装包,直接使用docker-compose启动即可)
私有docker镜像仓库harbor的参官文档:
安装文档:https://github.com/goharbor/harbor/blob/master/docs/install-config/installation-prereqs.md
配置 https访问:https://github.com/goharbor/harbor/blob/master/docs/install-config/configure-https.md
4.3、环境说明
Master:192.168.0.32
Node:192.168.0.33、192.168.0.34
注意:192.168.0.32 这台主机 master 和 node 复用。所有生成证书、执行 kubectl 命令的操作都在这台节点上执行。一旦 node 加入到 kubernetes 集群之后就不需要再登陆node节点了。
4.4、主要配置策略
kube-apiserver:
1、使用节点本地nginx4层透明代理实现高可用
2、关闭非安全端口8080和匿名访问
3、在安全端口6443接收https请求
4、严格的认证和授权策略(x509、token、RBAC)
5、开启bootstrap token认证,支持kubelet TLS bootstrapping
6、使用https访问kubelet、etcd,加密通信
kube-controller-manager:
1、3节点高可用
2、关闭非安全端口,在安全端口10252接收https请求
3、使用kubeconfig访问apiserver的安全端口
4、自动approve kubelet证书签名请求(CSR),证书过期后自动轮转
5、各controller使用自己的ServiceAccount访问apiserver
kube-scheduler:
1、3节点高可用
2、使用kubeconfig访问apiserver的安全端口
kubelet:
1、使用kubeadm动态创建bootstrap token,而不是在apiserver中静态配置
2、使用TLS bootstrap机制自动生成client和server证书,过期后自动轮转
3、在KubeletConfiguration类型的JSON文件配置主要参数
4、关闭只读端口,在安全端口10250接收https请求,对请求进行认证和授权,拒绝匿名访问和非授权访问
5、使用kubeconfig访问apiserver的安全端口
kube-proxy:
1、使用kubeconfig访问apiserver的安全端口
2、在KubeProxyConfiguration类型的JSON文件配置主要参数
3、使用ipvs代理模式
集群插件:
DNS:使用功能、性能更好的 coredns
Dashboard:支持登录认证
Metric:heapster、metrics-server,使用https访问kubelet安全端口
Log:Elasticsearch、Fluend、Kibana
Registry 镜像库:docker-registry、harbor
harbor私有镜像仓库:参考:https://github.com/goharbor/harbor
5、集群环境搭建安装(系统初始化和全局变量)
“5.3”到“5.17”的命令在master、node1、node2,3台机器上都需要执行
5.1、设置主机名、添加docker账户
设置永久主机名称,然后xshell重新连接,就可以看到名称变成新的名称了
1、将主机名改为master:hostnamectl set-hostname master
2、为支持DNS解析主机名称,修改/etc/hosts文件:
cat >> /etc/hosts <<EOF
192.168.0.32 master master
192.168.0.33 node1 node1
192.168.0.34 node2 node2
EOF
3、添加docker账户:useradd -m docker
5.2、设置master可以无密码登录所有节点的root账户
1、创建一个rsa的密钥:ssh-keygen -t rsa
2、将公钥文件放到master的root账户下:ssh-copy-id root@master
3、将公钥文件放到node1的root账户下:ssh-copy-id root@node1
4、将公钥文件放到node2的root账户下:ssh-copy-id root@node2
5、远程连接到node1上去:ssh root@node1
5.3、将可执行文件路径/opt/k8s/bin添加到PATH变量中
后面会将k8s可执行组件的二进制文件,全部放到/opt/k8s/bin目录下,以这个目录作为标准。
为了执行命令时不用写全路径,需要将这个路添加到PATH变量中
1、添加环境变量:echo 'PATH=/opt/k8s/bin:$PATH' >>/root/.bashrc
2、查看是否添加成功:cat /root/.bashrc
5.4、安装依赖包
在master、node1、node2都需要执行下面3个命令
1、安装依赖包1:yum install -y epel-release
2、安装依赖包2:yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
3、安装完毕后,检查ip_vs是否正常:/usr/sbin/modprobe ip_vs
5.5、关闭防火墙
从“4.4、主要配置策略”可以知道需要用到很多端口,为了方便(避免每一个端点都在防火墙中配置放行),避免少配置了端口,导致安装失败,所以需要关闭防火墙。
1、关闭防火墙:systemctl stop firewalld
2、取消防火墙的自启动:systemctl disable firewalld
3、清除防火墙的规则策略1:iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
清除防火墙的规则策略2:iptables -P FORWARD ACCEPT
5.6、关闭swap分区
如果开启了swap分区,kubelet会启动失败。
1、关闭swap分区:swapoff -a
2、注释/etc/fstab中swap的相应行:sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
5.7、关闭SELinux
SELinux是linux内核的保护,如果开启SELinux,执行某些受保护的命令就会报错:Permission denied
1、关闭SELinux的命令1:setenforce 0
2、关闭SELinux的命令2:sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
5.8、关闭dnsmasq(可选)
linux系统开启了dnsmasq后(eg:GUI环境),将系统DNS Server设置为 127.0.0.1,这会导致docker容器无法解析域名,需要关闭它:
systemctl stop dnsmasq
systemctl disable dnsmasq
5.9、加载内核模块(可选)
如果是比较老的版本,就需要执行这个命令,新的版本就不用执行
modprobe ip_vs_rr
modprobe br_netfilter
5.10、优化内核参数
这一步如果执行有一些报错不用理会,继续往下执行。(因为版本不一样,参数值有可能也不一样)
1、创建kubernetes.conf命令:
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
2、复制kubernetes.conf到/etc/sysctl.d下:cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
3、是/etc/sysctl.d/kubernetes.conf文件生效:sysctl -p /etc/sysctl.d/kubernetes.conf
5.11、设置系统时区
#1、调整系统TimeZone
timedatectl set-timezone Asia/Shanghai
#2、将当前的UTC时间写入硬件时钟
timedatectl set-local-rtc 0
#3、重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond
5.12、更新系统时间(可选)
ntpdate cn.pool.ntp.org
5.13、关闭无关的服务
systemctl stop postfix && systemctl disable postfix
5.14、设置rsyslog和systemd journal
systemd的journald 记录日志的3个优势:
1、可以记录到内存或文件系统(默认记录到内存,对应的位置为/run/log/jounal)
2、可以限制占用的磁盘空间、保证磁盘剩余空间
3、可以限制日志文件大小、保存的时间
由于journald默认将日志转发给rsyslog,这会导致:
1、日志写了多份
2、/var/log/messages中包含了太多无关日志,不方便后续查看
3、同时也影响系统性能
因为上面的问题,所以需要修改默认设置:
#1、持久化保存日志的目录
mkdir /var/log/journal
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
#2、持久化保存到磁盘
Storage=persistent
#3、压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
#4、最大占用空间10G
SystemMaxUse=10G
#5、单日志文件最大200M
SystemMaxFileSize=200M
#6、日志保存时间2周
MaxRetentionSec=2week
#7、不将日志转发到syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
5.15、创建相关目录
mkdir -p /opt/k8s/{bin,work} /opt/k8s/work/cert /etc/{kubernetes,etcd}/cert
5.16、升级内核、关闭 NUMA
系统内核是3.10以下版本需要才需要升级内核、关闭 NUMA
查看系统内核版本:uname -a
5.17、检查系统内核和模块是否适合运行docker(仅适用于linux系统)
1、下载check-config.sh文件:curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh
我下载不了,直接用的老师给的check-config.sh文件,上传到虚拟机中,直接执行bash ./check-config.sh命令,也可以
2、bash ./check-config.sh
5.18、分发集群环境变量定义脚本(扩容时不需要执行该步骤)
3个节点收执行这个命令,便于直接拖拽文件到xshell,上传到虚拟机对应目录。文件拖拽上传、下载的工具:
yum install -y lrzsz
后续的部署步骤将使用environment.sh文件中定义的全局环境变量;
老师提供的文件在:http://59.111.92.219/q1906-java/subject-3/blob/master/subject-3-k8s/environment.sh
下面的命令只在master节点执行
根据自己的机器情况修改文件内容,然后将文件复制到所有节点的/opt/k8s/bin目录
export IFACE的就是IP配置文件的DEVICE值(查看网络接口名称):vim /etc/sysconfig/network-scripts/ifcfg-enp0s3
变成可执行文件:chmod +x environment.sh
让环境变量文件生效:source environment.sh
读取环境变量文件,然后分发到其他节点:
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp /opt/k8s/bin/environment.sh root@${node_ip}:/opt/k8s/bin/
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done
6、HTTPS网络安全架构设计
6.1、对称加密
“明文”通过“密钥”加密成“密文”;拿到“密文”,需要通过“密钥”解密成“明文”。
常见的对称加密算法有:DES、3DES、AES、Blowfish、IDEA、RC5、RC6
6.2、非对称加密
用“公钥”对“明文”加密,用“私钥”对“明文”解密。
常见的非对称加密算法有:RSA、Elagmal、背包算法、Rabin。
应用场景:SSH、HTTPS、TLS、电子证书、电子签名、电子身份证......
6.3、数组证书
数字证书就是识别网站(服务器)
6.4、数组证书的4种格式
1、Java Keystore(JKS)格式
这是Java提供的密码库,通过Java Development Kit(JDK)工具包中的Keytool工具,生成Java Keystore(JKS)格式的证书文件。
使用这个格式的软件有:Tomcat、Weblogic、JBoss
2、PEM、KEY、CRT格式
这是OpenSSl工具提供的密码库,生成PEM、KEY、CRT等格式的证书文件
使用这个格式的软件有:Apache、Nginx
3、KDB格式
这是使用IBM产品自带的iKeyman工具,生成KDB格式的证书文件。
使用这个格式的软件是IBM的Web服务产品,eg:Websphere、IBM Http Server(IHS)
4、PFX格式
这是使用Windows自带的证书库生成PFX格式的证书
使用这个格式的服务有:微软Windows Server中的Internet Information Services(IIS)服务
只有经过CA签发后才能得到真正的证书,详细了解数字证书:https://www.jianshu.com/p/42bf7c4d6ab8
6.5、4种数组证书格式相互转换
6.6、SSL证书
SSL证书是数字证书的一种方式
SSL:Secure Socket Layer安全套接字协议,提供两个安全服务:鉴别、保密
HTTPS就是HTTP的安全版,HTTP下加入SSL层
HTTPS协议主要作用:
1、建立一个信息安全通道,来保证数据传输的安全
2、确认网站的真实性
SSL/TLS:安全套接字协议(SSL)是Web浏览器与Web服务器之间安全交换信息的协议。
用于网站HTTPS化的SSL数字证书有3种类型:DV SSL(个人)、OV SSL(组织、企业)、EV SSL(大型企业、金融机构)
SSL证书的优势:
1、简单快捷
只需要申请一张证书,部署在服务器上,就可以在有效期内不用做其他操作
2、显示直观
部署SSL证书后,通过https访问网站,能在地址栏或地址栏右侧直接看到加密锁标志。
3、身份认证
能在证书信息里看到网站所有者公司信息,进而确认网站的有效性和真实性。
6.7、Nginx集群环境SSL证书部署
证书部署在Nginx上,在nginx.conf配置文件中加入如下配置:
7、集群环境搭建安装(创建 CA 证书和秘钥)
为确保安全,kubernetes系统各组件需要使用x509证书对通信进行加密和认证。
CA(Certificate Authority)是自签名的根证书,用来签名后续创建的其它证书。
本文档使用CloudFlare的PKI工具集cfssl创建所有证书
cfssl的github地址:https://github.com/cloudflare/cfssl
7.1、安装cfssl工具
进入work目录:cd /opt/k8s/work
变成可执行文件:chmod +x /opt/k8s/bin/*
7.2、创建根证书(CA)
CA证书是集群所有节点共享的,只需要创建一个CA证书,后续创建的所有证书都由它签名。
第一步、创建配置文件CA配置文件:用于配置根证书的使用场景(profiles)和具体参数,后续在签名其它证书时需要指定特定场景。
具体参数有:usage,过期时间、服务端认证、客户端认证、加密等
signing:表示该证书可用于签名其它证书,生成的ca.pem证书中CA=TRUE;
server auth:表示client可以用该该证书对server提供的证书进行验证;
client auth:表示server可以用该该证书对client提供的证书进行验证;
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
第二步、创建证书签名请求文件
CN:Common Name,kube-apiserver从证书中提取该字段作为请求的用户名(User Name),浏览器使用该字段验证网站是否合法;
O:Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组(Group);
kube-apiserver将提取的User、Group作为RBAC授权的用户标识;
第三步、生成CA证书、私钥
7.3、分发证书文件
将生成的CA证书、秘钥文件、配置文件拷贝到所有节点的/etc/kubernetes/cert目录下:
source /opt/k8s/bin/environment.sh # 导入 NODE_IPS 环境变量
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/kubernetes/cert"
scp ca*.pem ca-config.json root@${node_ip}:/etc/kubernetes/cert
done
8、集群环境搭建安装(部署kubectl命令行工具)
8.1、下载和分发kubectl命令行工具
将如下文件拖拽上传到work目录
8.2、创建admin证书、私钥
kubectl是kubernetes集群的命令行管理工具。
kubectl与apiserver https安全端口通信,apiserver对提供的证书进行认证和授权。
kubectl作为集群的管理工具,需要被授予最高权限。这里创建具有最高权限的admin证书。
第一步、创建证书签名请求
cat > admin-csr.json <<EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "study163"
}
]
}
EOF
system:masters:kube-apiserver收到该证书后,将请求的Group设置为system:masters;
预定义的ClusterRoleBinding cluster-admin将Group system:masters与Role cluster-admin绑定,该Role授予所有API的权限;
该证书只会被kubectl当做client证书使用,所以hosts字段为空;
第二步、生成证书和私钥
cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
-ca-key=/opt/k8s/work/cert/ca-key.pem \
-config=/opt/k8s/work/cert/ca-config.json \
-profile=kubernetes admin-csr.json | cfssljson -bare admin
8.3、创建kubeconfig文件
kubeconfig为kubectl的配置文件,包含访问apiserver的所有信息,eg:apiserver地址、CA证书、自身使用的证书
命令如下:
source /opt/k8s/bin/environment.sh
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/k8s/work/cert/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kubectl.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials admin \
--client-certificate=/opt/k8s/work/cert/admin.pem \
--client-key=/opt/k8s/work/cert/admin-key.pem \
--embed-certs=true \
--kubeconfig=kubectl.kubeconfig
# 设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin \
--kubeconfig=kubectl.kubeconfig
# 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig
certificate-authority:验证kube-apiserver证书的根证书;
client-certificate、--client-key:刚生成的admin证书、私钥,连接kube-apiserver时使用;
embed-certs=true:将ca.pem和admin.pem证书内容嵌入到生成的kubectl.kubeconfig文件中(不加时,写入的是证书文件路径);
8.4、分发kubeconfig文件
分发到所有使用kubectl命令的节点:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p ~/.kube"
scp kubectl.kubeconfig root@${node_ip}:~/.kube/config
done
3.2.2.2 K8S基于二进制集群架构搭建1
1、部署etcd集群
etcd是基于Raft的分布式key-value存储系统,常用于:服务发现、共享配置、并发控制(leader选举、分布式锁)。
etcd集群各节点的名称和IP如下:
master:192.168.0.32
node1:192.168.0.33
node2:192.168.0.34
1.1、下载和分发etcd二进制文件
前面已经将etcd的包上传到work目录,不需要再下载了
分发二进制文件到集群所有节点:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp etcd-v3.3.10-linux-amd64/etcd* root@${node_ip}:/opt/k8s/bin
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done
1.2、创建etcd证书和私钥
第一步、创建证书签名请求
cd /opt/k8s/work/cert
cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.0.32",
"192.168.0.33",
"192.168.0.34"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "study163"
}
]
}
EOF
hosts:指定授权使用该证书的etcd节点IP或域名列表,这里将etcd集群的三个节点IP都列在其中
第二步、生成证书、私钥
cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
-ca-key=/opt/k8s/work/cert/ca-key.pem \
-config=/opt/k8s/work/cert/ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
第三步、分发生成的证书和私钥到各etcd节点
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/etcd/cert"
scp etcd*.pem root@${node_ip}:/etc/etcd/cert/
done
1.3、创建etcd的systemd unit模板文件
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > etcd.service.template <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=${ETCD_DATA_DIR}
ExecStart=/opt/k8s/bin/etcd \\
--data-dir=${ETCD_DATA_DIR} \\
--wal-dir=${ETCD_WAL_DIR} \\
--name=##NODE_NAME## \\
--cert-file=/etc/etcd/cert/etcd.pem \\
--key-file=/etc/etcd/cert/etcd-key.pem \\
--trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
--peer-cert-file=/etc/etcd/cert/etcd.pem \\
--peer-key-file=/etc/etcd/cert/etcd-key.pem \\
--peer-trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--listen-peer-urls=https://##NODE_IP##:2380 \\
--initial-advertise-peer-urls=https://##NODE_IP##:2380 \\
--listen-client-urls=https://##NODE_IP##:2379,http://127.0.0.1:2379 \\
--advertise-client-urls=https://##NODE_IP##:2379 \\
--initial-cluster-token=etcd-cluster-0 \\
--initial-cluster=${ETCD_NODES} \\
--initial-cluster-state=new \\
--auto-compaction-mode=periodic \\
--auto-compaction-retention=1 \\
--max-request-bytes=33554432 \\
--quota-backend-bytes=6442450944 \\
--heartbeat-interval=250 \\
--election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
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证书;
1.4、为各节点创建和分发etcd systemd unit文件
第一步、替换模板文件中的变量,为各节点创建systemd unit文件
NODE_NAMES和NODE_IPS为相同长度的bash数组,分别为节点名称和对应的IP
source /opt/k8s/bin/environment.sh
for (( i=0; i < 3; i++ ))
do
sed -e "s/##NODE_NAME##/${NODE_NAMES[i]}/" -e "s/##NODE_IP##/${NODE_IPS[i]}/" etcd.service.template > etcd-${NODE_IPS[i]}.service
done
第二步、分发生成的systemd unit文件
文件重命名为 etcd.service
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp etcd-${node_ip}.service root@${node_ip}:/usr/lib/systemd/system/etcd.service
done
1.5、启动etcd服务
1、必须创建etcd数据目录和工作目录;
2、etcd进程首次启动时会等待其它节点的etcd加入集群,命令systemctl start etcd会卡住一段时间,为正常现象
第一步、启动etcd服务
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p ${ETCD_DATA_DIR} ${ETCD_WAL_DIR}"
ssh root@${node_ip} "systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd " &
done
第二步、检查启动结果
新开一个xshell窗口,运行如下命令,如果都是active (running),就说明已经启动正常了,直接在启动的窗口回车即可。
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl status etcd|grep Active"
done
如果状态不是为active(running),就查看日志,确认原因:journalctl -u etcd
1.6、验证服务状态
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
--endpoints=https://${node_ip}:2379 \
--cacert=/opt/k8s/work/cert/ca.pem \
--cert=/etc/etcd/cert/etcd.pem \
--key=/etc/etcd/cert/etcd-key.pem endpoint health
done
1.7、查看当前的leader
source /opt/k8s/bin/environment.sh
ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
-w table --cacert=/opt/k8s/work/cert/ca.pem \
--cert=/etc/etcd/cert/etcd.pem \
--key=/etc/etcd/cert/etcd-key.pem \
--endpoints=${ETCD_ENDPOINTS} endpoint status
2、部署flannel网络
flannel是二次虚拟技术网络,在物理网络、docker网络进行了一次虚拟化,节点中的docker容器的Pod之间进行相互通信。
2.1、下载和分发flannel二进制文件
前面已经将flannel的包上传到work目录,不需要再下载了
1、创建flannel文件夹:mkdir flannel
2、解压flannel并放入flannel文件夹中:tar -xzvf flannel-v0.10.0-linux-amd64.tar.gz -C flannel
3、分发flannel二进制文件到集群所有节点
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp flannel/{flanneld,mk-docker-opts.sh} root@${node_ip}:/opt/k8s/bin/
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done
2.2、创建flannel证书和私钥
flannel从etcd集群存取网段分配信息,而etcd集群启用了双向x509证书认证,所以需要为flanneld生成证书和私钥。
第一步、创建证书签名请求
该证书只会被kubectl当做client证书使用,所以hosts字段为空(不需要做主机验证)
cd /opt/k8s/work/cert
cat > flanneld-csr.json <<EOF
{
"CN": "flanneld",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "study163"
}
]
}
EOF
第二步、生成证书和私钥
cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
-ca-key=/opt/k8s/work/cert/ca-key.pem \
-config=/opt/k8s/work/cert/ca-config.json \
-profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
ls flannel*pem
第三步、将生成的证书和私钥分发到所有节点
cd /opt/k8s/work/cert
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/flanneld/cert"
scp flanneld*.pem root@${node_ip}:/etc/flanneld/cert
done
2.3、向etcd写入集群Pod网段信息
注意:本步骤只需执行一次。
1、flannel当前版本(v0.10.0)不支持etcd v3,故使用etcd v2 API写入配置key和网段数据;
2、写入的Pod网段${CLUSTER_CIDR}地址段如/16必须小于SubnetLen,必须与kube-controller-manager的--cluster-cidr参数值一致;
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/opt/k8s/work/cert/ca.pem \
--cert-file=/opt/k8s/work/cert/flanneld.pem \
--key-file=/opt/k8s/work/cert/flanneld-key.pem \
set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}'
2.4、创建flannel的systemd unit文件
mk-docker-opts.sh:脚本将分配给flanneld的Pod子网网段信息写入/run/flannel/docker文件,
后续docker启动时使用这个文件中的环境变量配置docker0网桥;
flanneld:使用系统缺省路由所在的接口与其它节点通信,对于有多个网络接口(如内网和公网)的节点,
可以用-iface参数指定通信接口;
flanneld:运行时需要root权限;
-ip-masq: flanneld为访问Pod网络外的流量设置SNAT规则,同时将传递给Docker的变量--ip-masq(/run/flannel/docker 文件中)
设置为false,这样Docker将不再创建SNAT规则;Docker的--ip-masq为true时,
创建的SNAT规则比较“暴力”:将所有本节点Pod发起的、访问非docker0接口的请求做SNAT,
这样访问其他节点Pod的请求来源IP会被设置为flannel.1接口的IP,
导致目的Pod看不到真实的来源Pod IP。flanneld创建的SNAT规则比较温和,
只对访问非Pod网段的请求做SNAT。
cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > flanneld.service << EOF
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
ExecStart=/opt/k8s/bin/flanneld \\
-etcd-cafile=/etc/kubernetes/cert/ca.pem \\
-etcd-certfile=/etc/flanneld/cert/flanneld.pem \\
-etcd-keyfile=/etc/flanneld/cert/flanneld-key.pem \\
-etcd-endpoints=${ETCD_ENDPOINTS} \\
-etcd-prefix=${FLANNEL_ETCD_PREFIX} \\
-iface=${IFACE} \\
-ip-masq
ExecStartPost=/opt/k8s/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
2.5、分发flanneld systemd unit文件到所有节点
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp flanneld.service root@${node_ip}:/usr/lib/systemd/system/
done
2.6、启动flanneld服务
1、启动flanneld服务
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
done
2、检查启动结果
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "systemctl status flanneld|grep Active"
done
如果状态不是为active(running),就查看日志,确认原因:journalctl -u etcd
2.7、检查分配给各flanneld的Pod网段信息
1、查看集群Pod网段(/16):
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
get ${FLANNEL_ETCD_PREFIX}/config
2、查看已分配的Pod子网段列表(/24):
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
ls ${FLANNEL_ETCD_PREFIX}/subnets
3、查看某一Pod网段对应的节点IP和flannel接口地址:
source /opt/k8s/bin/environment.sh
etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--ca-file=/etc/kubernetes/cert/ca.pem \
--cert-file=/etc/flanneld/cert/flanneld.pem \
--key-file=/etc/flanneld/cert/flanneld-key.pem \
get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.16.0-21
从输出结果中可以看出:
1、172.30.16.0/21被分配给节点master(192.168.0.32);
2、VtepMAC为master节点的flannel.1网卡MAC地址
2.8、验证各节点能通过Pod网段互通
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
done
在各节点上ping所有flannel接口IP,确保能通:
下面的ip是“查看已分配的Pod子网段列表”中的ip
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh ${node_ip} "ping -c 1 172.30.16.0"
ssh ${node_ip} "ping -c 1 172.30.72.0"
ssh ${node_ip} "ping -c 1 172.30.232.0"
done
3.2.2.3 K8S基于二进制集群架构搭建2
待续
3.2.2.4 K8S基于二进制集群架构搭建3
更多推荐
所有评论(0)