k8s 高可用2个核心 apiserver master 和 etcd
- etcd:(需高可用)集群的数据中心,用于存放集群的配置以及状态信息,非常重要,如果数据丢失那么集群将无法恢复;因此高可用集群部署首先就是etcd是高可用集群;
- Apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制。整个集群中其他角色只有通过Apiserver才能访问etcd。CLI工具kubectl也是通过apiserver来对整体集群进行访问控制。
- Controller-manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。一组k8s master上同一时间只有一个controller-manager角色进行工作,因为要避免控制冲突。
- Scheduler:负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上。一组k8s master上同一时间只有一个scheduler角色进行工作,同样因为要避免控制冲突。
- Kubelet:负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理。为支持k8s master的高可用,由kubelet提供稳定的容器运行功能(static pod),通过运行容器的方式启动
- kube-proxy: 每个node上一个,负责service vip到endpoint pod的流量转发,老版本主要通过设置iptables规则实现,新版1.9基于kube-proxy-lvs 实现
集群网络结构:
网络名称 |
网络范围 |
SVC网络 |
172.20.0.0/16 |
集群网络 |
172.21.0.0/16 |
物理网络 |
192.168.10.0/24 |
节点构造如下 :
节点ip |
节点角色 |
hostname |
192.168.10.7 |
node |
node1 |
192.168.10.8 |
node |
node2 |
192.168.10.9 |
master01+etcd |
master1 |
192.168.10.10 |
master02+etcd |
master2 |
192.168.10.11 |
master03+etcd |
master3 |
由所有master节点提供一组VIP:192.168.10.6用来高可用
环境初始化
1.安装之前关闭防火墙和selinux
systemctl stop firewalld
systemctl disable firewalld
[[email protected] ~]# getenforce
Disabled
2.所有节点需要设定/etc/sysctl.d/k8s.conf的系统参数。
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl -p
安装docker
yum install -y yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools wget vim ntpdate libseccomp libtool-ltdl
yum -y install docker
systemctl enable docker && systemctl start docker
1.创建etcd高可用集群:
kuberntes 系统使用 etcd 存储所有数据,本文档介绍部署一个三节点高可用 etcd 集群的步骤,这三个节点复用 kubernetes master 机器
搭建etcd集群需要注意的是etcd最少需要三台才能发挥其高可用的功能,因为etcd集群内部使用的是选举制度,通过内部选举一台Leader,而如果当集群内部主机少于三台时,etcd的Leader选举功能就出现问题,导致Leader选举失败,从而etcd不能正常与外界通讯
yum -y install etcd
vim /etc/etcd/etcd.conf
#[Member]
ETCD_NAME="etcd1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://当前服务器IP:2380"
ETCD_LISTEN_CLIENT_URLS="http://当前服务器IP:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://当前服务器IP:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://当前服务器IP:2379"
ETCD_INITIAL_CLUSTER="etcd1=http://192.168.10.9:2380,etcd2=http://192.168.10.10:2380,etcd3=http://192.168.10.11:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
vim /usr/lib/systemd/system/etcd.service //修改etcd启动文件
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
? 指定 etcd 的工作目录为 /var/lib/etcd,数据目录为 /var/lib/etcd,需在启动服务前创建这两个目录;
? 注意三台etcd的配置文件中ETCD_NAME的配置,这里三台分别设置的是etcd1、etcd2、etcd3。
启动etcd服务:
待三台etcd都搭建完成之后,可依次启动(在etcd集群中如果只单独启动一台etcd会出现报错)
[[email protected] ~]# systemctl daemon-reload
[[email protected] ~]# systemctl start etcd
[[email protected] ~]# systemctl enable etcd
验证集群服务:
[[email protected] ~]# etcdctl --endpoints=http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379 cluster-health
member 8c632555af4d958d is healthy: got healthy result from http://192.168.10.10:2379
member bc34c6bd673bdf9f is healthy: got healthy result from http://192.168.10.11:2379
member ec065b41856af137 is healthy: got healthy result from http://192.168.10.9:2379
cluster is healthy
[[email protected] ~]#集群启动正常
2.搭建k8s_master高可用集群
集群HA方案,我们可以用lvs或者nginx做4层lb负载
安装ipvsadm管理工具
yum -y install ipvsadm
systemctl enable ipvsadm
配置LVS负载均衡服务
步骤1:在eth0网卡绑定VIP地址(虚拟ip)要能和本地通信,所以在同一网络/24位
第一种方式:(重启服务器失效,多用于临时测试)
ip add add/del 192.168.10.6/24 dev ens33
第二种:修改配置文件(重启也生效)
cp ifcfg-ens33 ifcfg-ens33:0
vim ifcfg-ens33:0
DEVICE=eth0:0 //虚拟网络接口
ONBOOT=yes //系统启动时激活
BOOTPROTO=static //使用静态ip地址
IPADDR=192.168.10.6 //该虚拟网络接口的ip
NETMASK=255.255.255.0 //子网掩码,对应ip别名
GATEWAY=192.168.10.1 //网关,对应ip别名
HWADDR=00:10:5A:5E:B1:E4 //网卡MAC地址,无需更改
USERCTL=no //是否给予非root用户设备管理权限
配置完成重启网卡即可:
systemctl restart network
步骤2:清除当前所有LVS规则(-C)
ipvsadm -C
步骤3:设置tcp、tcpfin、udp链接超时时间(--set)
ipvsadm --set 30 5 60
表示tcp空闲等待时间为30 秒
客户端关闭链接等待时间为5秒
udp空闲等待为60秒
步骤4:添加虚拟服务(-A),-t指定虚拟服务的IP端口,-s 指定调度算法wrr 权重轮询 -p 指定会话保持时间
ipvsadm -A -t 192.168.10.6:8080 -s wrr -p 300(默认300s)
步骤5:将虚拟服务关联到真实服务上(-a) -t 说明是tcp服务 -r指定真实服务的IP端口 -g LVS的DR模式 -w 指定权重
ipvsadm -a -t 192.168.10.6:8080 -r 192.168.10.9:8080 -g -w 1
ipvsadm -a -t 192.168.10.6:8080 -r 192.168.10.10:8080 -g -w 1
ipvsadm -a -t 192.168.10.6:8080 -r 192.168.10.11:8080 -g -w 1
保存配置:服务启动的时候会读取/etc/sysconfig/ipvsadm里面的内容,并且逐行执行,否则启动ipvsadm失败。
ipvsadm-save > /etc/sysconfig/ipvsadm
systemctl restart ipvsadm
步骤6:查看配置结果(-ln)
ipvsadm -ln
[[email protected] ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.10.6:8080 wrr persistent 300
-> 192.168.10.9:8080 Route 3 0 0
-> 192.168.10.10:8080 Route 3 6 0
-> 192.168.10.11:8080 Route 3 7 0
[[email protected] ~]#
Master安装:
下载最新的二进制版本并解压缩。安装包下载:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.10.md#server-binaries
找到./kubernetes/server/kubernetes-server-linux-amd64.tar.gz并解压缩那个。然后在解压缩文件中,找到./kubernetes/server/bin包含所有必需的二进制文件的文件。
部署k8s遇到的问题:http://time-track.cn/deploy-kubernetes-in-ubuntu-14-04.html
我们也可以根据名称直接从git上下载服务端所需要的组件(推荐)
用https协议下载会报错,以不安全的方式连接至 dl.k8s.io,使用“--no-check-certificate”
mkdir /opt/soft
cd /opt/soft
wget https://dl.k8s.io/v1.10.3/kubernetes-server-linux-amd64.tar.gz --no-check-certificate
tar -zxf kubernetes-server-linux-amd64.tar.gz
cd /opt/soft/kubernetes/server/bin
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/bin/
开始创建master端主配置文件
配置文件参数详解:https://blog.csdn.net/levy_cui/article/details/70229818
mkdir -p /etc/kubernetes
cd /etc/kubernetes/
vim config
#/etc/kubernetes/config文件同时被kube-apiserver,kube-controller-manager,kube-scheduler,kubelet,kube-proxy使用,在master主机上的config配置文件中的KUBE_MASTER需要填写本机的IP地址,而node端的则需要填写负载均衡的VIP。
KUBE_LOGTOSTDERR="--logtostderr=true" #日志默认存储方式,默认存储在系统的journal服务中,设置为true后日志不输出到文件
KUBE_LOG_LEVEL="--v=0" #日志等级
KUBE_ALLOW_PRIV="--allow-privileged=false" #如果设置为true,则k8s将允许在pod中运行拥有系统特权的容器应用,与docker run --privileged的功效相同
KUBE_MASTER="--master=http://192.168.10.9:8080" #kubernetes Master的apiserver地址和端口
vim apiserver:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
KUBE_API_ADDRESS="--address=0.0.0.0" #aipServer的监听地址,默认为127.0.0.1,若要配置集群,则要设置为0.0.0.0才能被其他主机找到
#KUBE_API_PORT="--port=8080" #apiserver的监听端口,默认8080是用于接收http请求,6443用于接收https请求。可以不用写
#KUBELET_PORT="--kubelet_port=10250" # kubelet的监听端口,若只作为Master节点则可以不配置
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=172.20.0.0/16" # service的地址范围,用于创建service的时候自动生成或指定serviceIP使用
KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379" #etcd地址
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota" #为了避免做用户认证,取消掉了ServiceAccount参数
KUBE_API_ARGS="--service-node-port-range=1-65535 --apiserver-count=3 --audit-log-maxage=30 --audit-log-maxbackup=3 --audit-log-maxsize=400 --audit-log-path=/var/lib/audit.log --event-ttl=1h" #此处可以添加其他配置
vim controller-manager:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/
KUBE_CONTROLLER_MANAGER_ARGS="--leader-elect=true --address=127.0.0.1"
? --address 值必须为 127.0.0.1,因为当前 kube-apiserver 期望 scheduler 和 controller-manager 在同一台机器;
vim scheduler:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/
KUBE_SCHEDULER_ARGS="--leader-elect=true --address=127.0.0.1"
? --address 值必须为 127.0.0.1,因为当前 kube-apiserver 期望 scheduler 和 controller-manager 在同一台机器;
创建kube-apiserver的启动配置文件:vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
After=etcd.service
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_ETCD_SERVERS \
$KUBE_API_ADDRESS \
$KUBE_API_PORT \
$KUBE_ALLOW_PRIV \
$KUBE_SERVICE_ADDRESSES \
$KUBE_ADMISSION_CONTROL \
$KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
创建kube-controller-manager的启动配置文件:vim /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/controller-manager
ExecStart=/usr/bin/kube-controller-manager \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
创建kube-scheduler的启动配置文件:vim /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler Plugin
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-scheduler \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
启动服务(三台服务都搭建完成之后先启动etcd然后在启动其他服务):
[[email protected] ~]# systemctl daemon-reload
[[email protected] ~]# systemctl start etcd kube-apiserver kube-controller-manager kube-scheduler
[[email protected] ~]# systemctl enable etcd kube-apiserver kube-controller-manager kube-scheduler
至此,kubernetes master端的组件已经搭建完成,我们在三台master主机上重复以上搭建步骤,注意配置文件中需要修改IP地址的地方,以及需要先启动etcd,然后依次启动kube-apiserver,kube-controller-manager,kube-scheduler。
验证master节点功能:kubectl get cs
[[email protected] ~]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}
etcd-1 Healthy {"health": "true"}
etcd-2 Healthy {"health": "true"}
Node安装:
每一台都搭建flanneld、docker、kubelet、kube-proxy这四个组件及服务
kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、 Pod挂载数据卷、下载secret、获取容器和节点状态等工作。 kubelet将每个Pod转换成一组容器。
kube-proxy在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作。
scp kubelet kube-proxy [email protected]:/usr/bin/
scp kubelet kube-proxy [email protected]:/usr/bin/
yum -y install docker flannel
vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379" #flannel从etcd中读取配置
FLANNEL_ETCD_PREFIX="/coreos.com/network" #/coreos.com/network 是master端etcd网络授权的文件,这个需要在启动flanneld之前在master端手动生成
FLANNEL_OPTIONS="-iface=ens33"
在master端生成网络授权文件/coreos.com/network:
etcdctl --endpoints=http://192.168.10.9:2379,http://192.168.10.10:2379,http://192.168.10.11:2379 mk /coreos.com/network/config '{"Network":"172.21.0.0/16"}'
查看是否添加成功
etcdctl get /coreos.com/network/config
如果etcd不是集群可以用下面的命令:
创建node端主配置文件:
mkdir /etc/kubernetes
vim /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://192.168.10.6:8080" #这里的master地址是负载均衡的VIP地址
创建kubelet服务配置文件:
vim /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=192.168.10.7"
KUBELET_HOSTNAME="--hostname-override=192.168.10.7"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS="--fail-swap-on=false --cgroup-driver=systemd --enable-server=true --enable-debugging-handlers=true --kubeconfig=/var/lib/kubelet/kubeconfig --cluster-dns=172.20.0.100 --cluster-domain=cluster.local. --hairpin-mode promiscuous-bridge --serialize-image-pulls=false"
Kubernetes v1.8+ 要求关闭系统 Swap,若不关闭则需要修改kubelet 设定参数--fail-swap-on=false
然后还要添加一个配置文件,因为1.9.0在kubelet里不再使用KUBELET_API_SERVER来跟API通信,而是通过别一个yaml的配置来实现, 描述了kubelet访问apiserver的方式。
参考:https://www.58jb.com/html/180.html
mkdir -p /var/lib/kubelet
vim /var/lib/kubelet/kubeconfig
apiVersion: v1
kind: Config
users:
- name: kubelet
clusters:
- name: kubernetes
cluster:
server: http://192.168.10.6:8080
contexts:
- context:
cluster: kubernetes
user: kubelet
name: service-account-context
current-context: service-account-context
创建kubelet启动service配置文件:
vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBELET_API_SERVER \
$KUBELET_ADDRESS \
$KUBELET_PORT \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_POD_INFRA_CONTAINER \
$KUBELET_ARGS
Restart=on-failure
[Install]
WantedBy=multi-user.target
创建kube-proxy服务配置文件:
vim /etc/kubernetes/proxy
KUBE_PROXY_ARGS="--proxy-mode=userspace --bind-address=0.0.0.0 --hostname-override=192.168.10.7"
创建kube-proxy启动service配置文件
vim /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/proxy
ExecStart=/usr/bin/kube-proxy \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
启动服务
systemctl daemon-reload
systemctl start flanneld kubelet kube-proxy docker
systemctl enable flanneld kubelet kube-proxy docker
查看节点是否获取到
[[email protected] ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 16h
[[email protected] ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
192.168.10.7 Ready <none> 16h v1.10.3
192.168.10.8 Ready <none> 16h v1.10.3
[[email protected] ~]#
OK!
原文地址:http://blog.51cto.com/7072753/2121408