第二章 Kubernetes进阶之使用二进制包部署集群
1.官方提供的三种部署方式
minikube
Minikube是一个工具,可以在本地快速运行一个单点Kubernetes,仅用于尝试Kubernetes或日常开发以后使用
kubeadm
Kubeadm也是一个工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群
init初始化master
join使node加入集群
目前属于测试阶段不适用于生产环境
二进制包
推荐部署方式,从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群
2.Kubernetes平台环境规划
软件 | 版本 |
Linux操作系统 | CentOS7.5_X64 |
Kubbernetes | 1.12 |
Docker | 18.xx.ce |
Etcd | 3.x |
Flannel | 0.10 |
角色 | IP | 组件 | 推荐配置 |
master01 | 192.168.1.63 |
kube-apiserver kube-controller-manager kube-scheduler etcd |
CPU:2C+ 内存:4G+
|
master02 | 192.168.1.64 |
kube-apiserver kube-controller-manager kube-scheduler |
|
node01 | 192.168.1.65 |
kubelet kube-proxy docker flannel etcd |
|
node02 | 192.168.1.66 |
kubelet kube-proxy docker flannel etcd |
|
Load Balancer (Master) |
192.168.1.61 192.168.1.60(VIP) |
Nginx L4 | |
Load Balancer (Backup) |
192.168.1.62 | Nginx L4 | |
Registry | 192.168.1.66 | Harbor |
单节点master构架图
3.自签SSL证书
部署之前关闭防火墙和selinux
修改主机名
IP | 主机名 |
192.168.1.61 | |
192.168.1.62 | |
192.168.1.63 | k8s-master01 |
192.168.1.64 | k8s-master02 |
192.168.1.65 | k8s-node01 |
192.168.1.66 | k8s-node02 |
自签SSL证书
组件 | 适用的证书 |
etcd | ca.pem server.pem server-key.pem |
flannel | ca.pem server.pem server-key.pem |
kube-apiserver | ca.pem server.pem server-key.pem |
kubelet | ca.pem ca-key.pem |
kube-proxy | ca.pem kube-proxy.pem kube-proxy.pem |
kubeclt | ca.pem admin.pem admin-key.pem |
4.Etcd数据库集群部署
下载cfssl工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64 mv cfssl_linux-amd64 /usr/local/bin/cfssl mv cfssljson_linux-amd64 /usr/local/bin/cfssljson mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
生产json文件
cat > ca-config.json <<EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "www": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } } EOF
cat > ca-csr.json <<EOF { "CN": "etcd CA", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing" } ] } EOF
生产ca证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
会在当前目录生成一下两个证书
生成etcd域名证书,没有域名使用IP代替这里部署etcd的三台服务器的IP分别为192.168.1.63 192.168.1.65 192.168.1.66
cat > server-csr.json <<EOF { "CN": "etcd", "hosts": [ "192.168.1.63", "192.168.1.65", "192.168.1.66" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing" } ] } EOF
生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
生成以下两个证书
两次生成证书的命令生成以下证书
部署etcd
以下操作在etcd的三个节点63 65 66均执行一遍,三个节点不同的地方是配置文件的ip不同
下载二进制包,下载地址是https://github.com/etcd-io/etcd/releases/tag/
本次部署下载包为etcd-v3.3.10-linux-amd64.tar.gz
创建etcd执行文件配置文件及ssl证书目录
mkdir /opt/etcd/{bin,cfg,ssl} -p
解压压缩包
tar -xf etcd-v3.3.10-linux-amd64.tar.gz
复制可执行文件
cp etcd-v3.3.10-linux-amd64/etcd etcd-v3.3.10-linux-amd64/etcdctl /opt/etcd/bin/
创建etcd配置文件
/opt/etcd/cfg/etcd
内容如下
# cat /opt/etcd/cfg/etcd #[Member] ETCD_NAME="etcd01" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.1.63:2380" ETCD_LISTEN_CLIENT_URLS="https://192.168.1.63:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.1.63:2380" ETCD_ADVERTISE_CLIENT_URLS="https://192.168.1.63:2379" ETCD_INITIAL_CLUSTER="etcd01=https://192.168.1.63:2380,etcd02=https://192.168.1.65:2380,etcd03=https://192.168.1.66:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"
变量说明
ETCD_NAME 节点名称 ETCD_DATA_DIR 数据目录 ETCD_LISTEN_PEER_URLS 集群通信监听地址 ETCD_LISTEN_CLIENT_URLS 客户端访问监听地址 ETCD_INITIAL_ADVERTISE_PEER_URLS 集群通告地址 ETCD_ADVERTISE_CLIENT_URLS 客户端通告地址 ETCD_INITIAL_CLUSTER 集群节点地址 ETCD_INITIAL_CLUSTER_TOKEN 集群Token ETCD_INITIAL_CLUSTER_STATE 加入集群的当前状态,new是新集群,existing表示加入已有集群
创建systemd管理etcd文件
/usr/lib/systemd/system/etcd.service
内容如下
[Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify EnvironmentFile=/opt/etcd/cfg/etcd ExecStart=/opt/etcd/bin/etcd \ --name=${ETCD_NAME} \ --data-dir=${ETCD_DATA_DIR} \ --listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \ --listen-client-urls=${ETCD_LISTEN_CLIENT_URLS},http://127.0.0.1:2379 \ --advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \ --initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \ --initial-cluster=${ETCD_INITIAL_CLUSTER} \ --initial-cluster-token=${ETCD_INITIAL_CLUSTER_TOKEN} \ --initial-cluster-state=new \ --cert-file=/opt/etcd/ssl/server.pem \ --key-file=/opt/etcd/ssl/server-key.pem \ --peer-cert-file=/opt/etcd/ssl/server.pem \ --peer-key-file=/opt/etcd/ssl/server-key.pem \ --trusted-ca-file=/opt/etcd/ssl/ca.pem \ --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem Restart=on-failure LimitNOFILE=65536
2024-05-13补充
使用Rocky系统安装后enable etcd出现以下错误
# systemctl daemon-reload systemctl start etcd systemctl enable etcd The unit files have no installation config (WantedBy=, RequiredBy=, Also=, Alias= settings in the [Install] section, and DefaultInstance= for template units). This means they are not meant to be enabled or disabled using systemctl. Possible reasons for having this kind of units are: • A unit may be statically enabled by being symlinked from another unit's .wants/ or .requires/ directory. • A unit's purpose may be to act as a helper for some other unit which has a requirement dependency on it. • A unit may be started when needed via activation (socket, path, timer, D-Bus, udev, scripted systemctl call, ...). • In case of template units, the unit is meant to be enabled with some instance name specified.
解决方法
修改文件添加以下内容
/usr/lib/systemd/system/etcd.service
添加内容如下
[Install] WantedBy=multi-user.target
补充结束
把证书拷贝至配置文件中的证书位置
cp *.pem /opt/etcd/ssl/
可以在第一个节点192.168.1.63配置好后使用scp命令把文件夹及文件拷贝至另外两台etcd服务器192.168.1.65 192.168.1.66
scp -r /opt/etcd/ root@192.168.1.65:/opt/ scp -r /opt/etcd/ root@192.168.1.66:/opt/ scp /usr/lib/systemd/system/etcd.service root@192.168.1.65:/usr/lib/systemd/system scp /usr/lib/systemd/system/etcd.service root@192.168.1.66:/usr/lib/systemd/system
192.168.1.65 192.168.1.66其他文件不变,只修改配置文件
/opt/etcd/cfg/etcd
192.168.1.65
# cat /opt/etcd/cfg/etcd #[Member] ETCD_NAME="etcd02" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.1.65:2380" ETCD_LISTEN_CLIENT_URLS="https://192.168.1.65:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.1.65:2380" ETCD_ADVERTISE_CLIENT_URLS="https://192.168.1.65:2379" ETCD_INITIAL_CLUSTER="etcd01=https://192.168.1.63:2380,etcd02=https://192.168.1.65:2380,etcd03=https://192.168.1.66:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"
192.168.1.66
# cat /opt/etcd/cfg/etcd #[Member] ETCD_NAME="etcd03" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.1.66:2380" ETCD_LISTEN_CLIENT_URLS="https://192.168.1.66:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.1.66:2380" ETCD_ADVERTISE_CLIENT_URLS="https://192.168.1.66:2379" ETCD_INITIAL_CLUSTER="etcd01=https://192.168.1.63:2380,etcd02=https://192.168.1.65:2380,etcd03=https://192.168.1.66:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"
部署完etcd启动并设置开机自启动,三台etcd主机都操作
systemctl daemon-reload systemctl start etcd systemctl enable etcd
启动完以后检查etcd集群状态,因为是自建证书需要指定证书路径进行检查
cd /opt/etcd/ssl/ /opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.1.63:2379,https://192.168.1.65:2379,https://192.168.1.66:2379" cluster-health
出现以下提示代表etcd正常
member 472edcb0986774fe is healthy: got healthy result from https://192.168.1.65:2379 member 89e49aedde68fee4 is healthy: got healthy result from https://192.168.1.66:2379 member ddaf91a76208ea00 is healthy: got healthy result from https://192.168.1.63:2379
如果启动失败查看日志/var/log/message
拍错
如果日出现提示
has already been bootstrapped
删除etcd数据目录文件夹并新建再重启etcd
rm -rf /var/lib/etcd/ mkdir /var/lib/etcd
5.Node安装Docker
在node安装docker,使用国内阿里源安装,安装参考https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.3e221b117i6d6B
# step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 更新并安装Docker-CE sudo yum makecache fast sudo yum -y install docker-ce # Step 4: 开启Docker服务 sudo service docker start # Step 5:设置开机启动 systemctl enable docker
6.Flannel容器集群网络部署
Kubernetes网络模型设计基本要求
- 一个pod一个IP
- 每个Pod独立IP
- 所有容器都可以与其他容器通信
- 所有节点都可以与所有容器通信
flannel工作原理图
Overlay Network
覆盖网络,在基础网络上叠加一种虚拟网络技术模式,该网络中的主机通过虚拟链路连接起来。
Flannel是Overlay网络的一种,也是将源数据包封装在另一种网络包里进行路由转发和通信,目前支持UDP,VXLAN,Host-GW,AWS VPC和GCE路由等数据转发方式。
Falnnel要用etcd存储一个子网信息,所以要保证能成功连接etcd,写入预定义子网段
在master01 192.168.1.63上操作
#进入证书目录 cd /opt/etcd/ssl #设置 /opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.1.63:2379,https://192.168.1.65:2379,https://192.168.1.66:2379" set /coreos.com/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'
出现以下提示代表设置正常 设置以后创建docker容器的网段即为172.17.0.0/16
把以上命名的set改成get就能获取到设置信息
/opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.1.63:2379,https://192.168.1.65:2379,https://192.168.1.66:2379" get /coreos.com/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'
注意:设置的网段信息不要和宿主机网段信息一致,否则可能出现启动docker后无法获取到docker网段的信息
以下配置在node节点192.168.1.65 192.168.1.66配置
下载二进制包
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz #解压 tar -xf flannel-v0.11.0-linux-amd64.tar.gz #创建Kubernetes目录 mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} #把解压后的flanneld文件复制到对应目录 cp flanneld mk-docker-opts.sh /opt/kubernetes/bin
配置flannel配置文件
/opt/kubernetes/cfg/flanneld
内容如下
FLANNEL_OPTIONS="--etcd-endpoints=https://192.168.1.63:2379,https://192.168.1.65:2379,https://192.168.1.66:2379 -etcd-cafile=/opt/etcd/ssl/ca.pem -etcd-certfile=/opt/etcd/ssl/server.pem -etcd-keyfile=/opt/etcd/ssl/server-key.pem"
需要把etcd对应的证书拷贝到这个配置文件指定的目录opt/etcd/ssl下
配置system管理flanneld
/usr/lib/systemd/system/flanneld.service
内容如下
# cat /usr/lib/systemd/system/flanneld.service [Unit] Description=Flanneld overlay address etcd agent After=network-online.target network.target Before=docker.service [Service] Type=notify EnvironmentFile=/opt/kubernetes/cfg/flanneld ExecStart=/opt/kubernetes/bin/flanneld --ip-masq $FLANNEL_OPTIONS ExecStartPost=/opt/kubernetes/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env Restart=on-failure [Install] WantedBy=multi-user.target
启动flanneld以后可以查看文件/run/flannel/subnet.env查看子网信息
配置docker使用子网信息
/usr/lib/systemd/system/docker.service
内容如下
# cat /usr/lib/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify EnvironmentFile=/run/flannel/subnet.env ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target
重启docker和flanneld
systemctl daemon-reload systemctl restart flanneld
systemctl restart docker
注意:因为docker需要使用到flanneld子网信息所以以上启动顺序为先启动flanneld再启动docker
检查是否生效
# ps -ef|grep docker root 15817 1 2 09:52 ? 00:00:00 /usr/bin/dockerd --bip=172.17.82.1/24 --ip-masq=false --mtu=1450 root 15824 15817 0 09:52 ? 00:00:00 containerd --config /var/run/docker/containerd/containerd.toml --log-level info
确保flannel和docker0在同一网段
# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:50:56:b7:26:a4 brd ff:ff:ff:ff:ff:ff inet 192.168.1.65/24 brd 192.168.1.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever 3: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default link/ether 1e:87:55:50:7f:31 brd ff:ff:ff:ff:ff:ff inet 172.17.82.0/32 scope global flannel.1 valid_lft forever preferred_lft forever 4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:c0:26:ad:3d brd ff:ff:ff:ff:ff:ff inet 172.17.82.1/24 brd 172.17.82.255 scope global docker0 valid_lft forever preferred_lft forever
同样的操作在node02 192.168.1.66操作一遍
在node2上查看ip
# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:50:56:b7:bf:2f brd ff:ff:ff:ff:ff:ff inet 192.168.1.66/24 brd 192.168.1.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever 3: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default link/ether de:df:37:b7:be:5c brd ff:ff:ff:ff:ff:ff inet 172.17.30.0/32 scope global flannel.1 valid_lft forever preferred_lft forever 4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:38:91:f2:c4 brd ff:ff:ff:ff:ff:ff inet 172.17.30.1/24 brd 172.17.30.255 scope global docker0 valid_lft forever preferred_lft forever
测试不同node节点互通
如果能通说明Flannel部署成功。如果不通检查下日志:journalctl -u flannel
两个node启动一个容器ping测试
docker run -it busybox
7.部署Master组件
在部署Kubernetes之前一定要确保etcd、flannel、docker是正常工作的,否则先解决问题再继续。
在master01 192.168.1.63上操作
创建CA证书
cd /root/k8s/k8s-cert # cat ca-config.json { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } } # cat ca-csr.json { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing", "O": "k8s", "OU": "System" } ] } cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
生成以下两个证书
创建apiserver证书
# cat server-csr.json { "CN": "kubernetes", "hosts": [ "10.0.0.1", "127.0.0.1", "192.168.1.60", "192.168.1.61", "192.168.1.62", "192.168.1.63", "192.168.1.64", "192.168.1.65", "192.168.1.66", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "k8s", "OU": "System" } ] }
为了不遗漏这里把所有ip都填上
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
生成以下两个证书
创建kube-proxy证书
# cat kube-proxy-csr.json { "CN": "system:kube-proxy", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "k8s", "OU": "System" } ] }
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
生成以下证书
最终生成6个证书
# ls *.pem ca-key.pem ca.pem kube-proxy-key.pem kube-proxy.pem server-key.pem server.pem
部署apiserver组件
下载二进制包下载地址https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.13.md#server-binaries-8
本次下载v1.13.4包
创建Kubernetes目录
mkdir /opt/kubernetes/{bin,cfg,ssl,logs} -p
解压并且把可执行文件放置在对应目录
tar -xf kubernetes-server-linux-amd64.tar.gz cd kubernetes/server/bin /usr/bin/cp kube-apiserver kube-scheduler kube-controller-manager kubectl /opt/kubernetes/bin/
创建token文件
export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ') cat > token.csv <<EOF ${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap" EOF cp token.csv /opt/kubernetes/cfg/
token文件内容如下
# cat /opt/kubernetes/cfg/token.csv 9015cf068f594553a06fc70e4367c3a4,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
第一列:随机字符串,自己可生成
第二列:用户名
第三列:UID
第四列:用户组
创建apiserver配置文件
# cat /opt/kubernetes/cfg/kube-apiserver KUBE_APISERVER_OPTS="--logtostderr=false \ --log-dir=/opt/kubernetes/logs \ --v=4 \ --etcd-servers=https://192.168.1.63:2379,https://192.168.1.65:2379,https://192.168.1.66:2379 \ --insecure-bind-address=127.0.0.1 \ --bind-address=192.168.1.63 \ --insecure-port=8080 \ --secure-port=6443 \ --advertise-address=192.168.1.63 \ --allow-privileged=true \ --service-cluster-ip-range=10.0.0.0/24 \ #--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction --authorization-mode=RBAC,Node \ --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \ --kubelet-https=true \ --enable-bootstrap-token-auth \ --token-auth-file=/opt/kubernetes/cfg/token.csv \ --service-node-port-range=30000-50000 \ --tls-cert-file=/opt/kubernetes/ssl/server.pem \ --tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \ --client-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \ --etcd-cafile=/opt/etcd/ssl/ca.pem \ --etcd-certfile=/opt/etcd/ssl/server.pem \ --etcd-keyfile=/opt/etcd/ssl/server-key.pem"
配置好前面生成的证书,确保能连接etcd
参数说明
--logtostderr 启用日志 ---v 日志等级 --etcd-servers etcd集群地址 --bind-address 监听地址 --secure-port https安全端口 --advertise-address 集群通告地址 --allow-privileged 启用授权 --service-cluster-ip-range Service虚拟IP地址段 --enable-admission-plugins 准入控制模块 --authorization-mode 认证授权,启用RBAC授权和节点自管理 --enable-bootstrap-token-auth 启用TLS bootstrap功能,后面会讲到 --token-auth-file token文件 --service-node-port-range Service Node类型默认分配端口范围
配置system管理apiserver
# cat /usr/lib/systemd/system/kube-apiserver.service [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=-/opt/kubernetes/cfg/kube-apiserver ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target
启动
systemctl daemon-reload systemctl enable kube-apiserver systemctl restart kube-apiserver
部署scheduler组件
创建schduler配置文件
# cat /opt/kubernetes/cfg/kube-scheduler KUBE_SCHEDULER_OPTS="--logtostderr=true \ --v=4 \ --master=127.0.0.1:8080 \ --leader-elect"
参数说明
--master 连接本地apiserver --leader-elect 当该组件启动多个时,自动选举(HA)
创建system管理schduler组件
# cat /usr/lib/systemd/system/kube-scheduler.service [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=-/opt/kubernetes/cfg/kube-scheduler ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target
启动
# systemctl daemon-reload # systemctl enable kube-scheduler # systemctl restart kube-scheduler
部署controllers-manager组件
创建controllers-manager配置文件
# cat /opt/kubernetes/cfg/kube-controller-manager KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \ --v=4 \ --master=127.0.0.1:8080 \ --leader-elect=true \ --address=127.0.0.1 \ --service-cluster-ip-range=10.0.0.0/24 \ #--service-cluster-ip-range=172.17.0.0/16 \ --cluster-name=kubernetes \ --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \ --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \ --root-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \ --experimental-cluster-signing-duration=87600h0m0s"
PS:这里master配置必须是127.0.0.1而不能是192.168.1.63否则会出现连接拒绝的报错信息
system管理controllers-manager
# cat /usr/lib/systemd/system/kube-controller-manager.service [Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=-/opt/kubernetes/cfg/kube-controller-manager ExecStart=/opt/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target
启动
# systemctl daemon-reload # systemctl enable kube-controller-manager # systemctl restart kube-controller-manager
所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态:
/opt/kubernetes/bin/kubectl get cs NAME STATUS MESSAGE ERROR controller-manager Healthy ok scheduler Healthy ok etcd-1 Healthy {"health":"true"} etcd-2 Healthy {"health":"true"} etcd-0 Healthy {"health":"true"}
8.部署Node组件
Master apiserver启用TLS认证后,Node节点kubelet组件想要加入集群,必须使用CA签发的有效证书才能与apiserver通信,当Node节点很多时,签署证书是一件很繁琐的事情,因此有了TLS Bootstrapping机制,kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。
认证大致工作流程如图所示:
在master01上操作,将kubelet-bootstrap用户绑定到系统集群角色
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
查看
kubectl get clusterrolebinding
创建kubeconfig文件
在kubernetes证书目录/opt/kubernetes/ssl下执行以下命令生成kubeconfig文件
#创建kubelet bootstrapping kubeconfig #该token需要与配置文件中/opt/kubernetes/cfg/token.csv一致 BOOTSTRAP_TOKEN=9015cf068f594553a06fc70e4367c3a4 KUBE_APISERVER="https://192.168.1.63:6443" # 设置集群参数 kubectl config set-cluster kubernetes \ --certificate-authority=./ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=bootstrap.kubeconfig # 设置客户端认证参数 kubectl config set-credentials kubelet-bootstrap \ --token=${BOOTSTRAP_TOKEN} \ --kubeconfig=bootstrap.kubeconfig # 设置上下文参数 kubectl config set-context default \ --cluster=kubernetes \ --user=kubelet-bootstrap \ --kubeconfig=bootstrap.kubeconfig # 设置默认上下文 kubectl config use-context default --kubeconfig=bootstrap.kubeconfig #---------------------- # 创建kube-proxy kubeconfig文件 kubectl config set-cluster kubernetes \ --certificate-authority=./ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=kube-proxy.kubeconfig kubectl config set-credentials kube-proxy \ --client-certificate=./kube-proxy.pem \ --client-key=./kube-proxy-key.pem \ --embed-certs=true \ --kubeconfig=kube-proxy.kubeconfig kubectl config set-context default \ --cluster=kubernetes \ --user=kube-proxy \ --kubeconfig=kube-proxy.kubeconfig kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
生成以下两个配置文件
将这两个文件拷贝至node的目录/opt/kubernetes/cfg下
在两个node192.168.1.65 192.168.1.66部署kubelet组件
将前面下载的二进制包中的kubelet和kube-proxy拷贝到/opt/kubernetes/bin目录下
创建kubelet配置文件
# cat /opt/kubernetes/cfg/kubelet KUBELET_OPTS="--logtostderr=true \ --v=4 \ --hostname-override=192.168.1.65 \ --kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \ --bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \ --config=/opt/kubernetes/cfg/kubelet.config \ --cert-dir=/opt/kubernetes/ssl \ --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
参数说明
--hostname-override 在集群中显示的主机名 --kubeconfig 指定kubeconfig文件位置,会自动生成 --bootstrap-kubeconfig 指定刚才生成的bootstrap.kubeconfig文件 --cert-dir 颁发证书存放位置 --pod-infra-container-image 管理Pod网络的镜像
其中/opt/kubernetes/cfg/kubelet.config配置文件如下:
kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 192.168.1.65 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs clusterDNS: ["10.0.0.2"] clusterDomain: cluster.local. failSwapOn: false authentication: anonymous: enabled: true
system管理kubelet
# cat /usr/lib/systemd/system/kubelet.service [Unit] Description=Kubernetes Kubelet After=docker.service Requires=docker.service [Service] EnvironmentFile=/opt/kubernetes/cfg/kubelet ExecStart=/opt/kubernetes/bin/kubelet $KUBELET_OPTS Restart=on-failure KillMode=process [Install] WantedBy=multi-user.target
启动
# systemctl daemon-reload # systemctl enable kubelet # systemctl restart kubelet
启动后会在目录下自动生成证书
# pwd /opt/kubernetes/ssl [root@k8s-node01 ssl]# ls kubelet-client.key.tmp kubelet.crt kubelet.key
注意:如果启动kubelet失败则检查docker和网络服务flanneld是否启动
如果虚拟机是从其他node克隆而来在修改配置以后启动需要先删除ssl下所有证书,否则启动会报以下错误
node "192.168.1.67" not found
启动后没有加入到集群,需要在master手动添加
# kubectl get csr NAME AGE REQUESTOR CONDITION node-csr-hL-XazsjjMvWzkrdg7ePgmu9IRd5SBIFtqLkvqwxEc4 41m kubelet-bootstrap Approved,Issued node-csr-uM16cNRQFg5S6UHeiMFprfO3dNBQp5udk74CvbSqv5E 48m kubelet-bootstrap Approved,Issued #kubectl certificate approve node-csr-hL-XazsjjMvWzkrdg7ePgmu9IRd5SBIFtqLkvqwxEc4
添加完查看node是否加入集群
# kubectl get node NAME STATUS ROLES AGE VERSION 192.168.1.65 Ready <none> 22m v1.12.10 192.168.1.66 Ready <none> 22m v1.12.10
部署kube-proxy组件
创建kube-proxy配置文件
# cat /opt/kubernetes/cfg/kube-proxy KUBE_PROXY_OPTS="--logtostderr=true \ --v=4 \ --hostname-override=192.168.1.65 \ --cluster-cidr=10.0.0.0/24 \ --kubeconfig=/opt/kubernetes/cfg/kube-proxy.kubeconfig"
system管理kube-proxy
# cat /usr/lib/systemd/system/kube-proxy.service [Unit] Description=Kubernetes Proxy After=network.target [Service] EnvironmentFile=-/opt/kubernetes/cfg/kube-proxy ExecStart=/opt/kubernetes/bin/kube-proxy $KUBE_PROXY_OPTS Restart=on-failure [Install] WantedBy=multi-user.target
启动
# systemctl daemon-reload # systemctl enable kube-proxy # systemctl restart kube-proxy
node2 192.168.1.66上面部署方式一样
集群部署完成,在master 192.168.1.63查看集群状态
# kubectl get node NAME STATUS ROLES AGE VERSION 192.168.1.65 Ready <none> 122m v1.13.4 192.168.1.66 Ready <none> 118m v1.13.4 [root@localhost ~]# kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {"health":"true"} etcd-2 Healthy {"health":"true"} etcd-1 Healthy {"health":"true"}
9.部署一个测试示例
Kubernetes集群部署完毕,在master上面部署一个nginx测试
#创建一个deployment名称为nginx使用镜像为nginx kubectl create deployment nginx --image=nginx #创建一个service对应的deloyment为nginx 集群内部端口为80对外使用NodePort暴露端口 kubectl expose deployment nginx --port=80 --type=NodePort #查看pod和svc kubectl get pod,svc
删除deployment和svc
kubectl delete deployment nginx kubectl delete svc nginx
注意:创建deployment之前确保node节点的kube-proxy服务已经部署正常,否则创建了svc后不对外映射对应的随机端口,并且没有报错信息
通过web访问访问方式为node ip加对应端口192.168.1.65:47679
10.部署Web UI(Dashboard)
部署UI的配置文件可以在以下地址下载https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dashboard
下载部署配置文件
# cat dashboard-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: labels: k8s-app: kubernetes-dashboard # Allows editing resource and makes sure it is created first. addonmanager.kubernetes.io/mode: EnsureExists name: kubernetes-dashboard-settings namespace: kube-system
# cat dashboard-rbac.yaml kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: k8s-app: kubernetes-dashboard addonmanager.kubernetes.io/mode: Reconcile name: kubernetes-dashboard-minimal namespace: kube-system rules: # Allow Dashboard to get, update and delete Dashboard exclusive secrets. - apiGroups: [""] resources: ["secrets"] resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"] verbs: ["get", "update", "delete"] # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map. - apiGroups: [""] resources: ["configmaps"] resourceNames: ["kubernetes-dashboard-settings"] verbs: ["get", "update"] # Allow Dashboard to get metrics from heapster. - apiGroups: [""] resources: ["services"] resourceNames: ["heapster"] verbs: ["proxy"] - apiGroups: [""] resources: ["services/proxy"] resourceNames: ["heapster", "http:heapster:", "https:heapster:"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: kubernetes-dashboard-minimal namespace: kube-system labels: k8s-app: kubernetes-dashboard addonmanager.kubernetes.io/mode: Reconcile roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kubernetes-dashboard-minimal subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kube-system
# cat dashboard-secret.yaml apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard # Allows editing resource and makes sure it is created first. addonmanager.kubernetes.io/mode: EnsureExists name: kubernetes-dashboard-certs namespace: kube-system type: Opaque --- apiVersion: v1 kind: Secret metadata: labels: k8s-app: kubernetes-dashboard # Allows editing resource and makes sure it is created first. addonmanager.kubernetes.io/mode: EnsureExists name: kubernetes-dashboard-key-holder namespace: kube-system type: Opaque
修改镜像地址为国内地址
# cat dashboard-deployment.yaml apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard addonmanager.kubernetes.io/mode: Reconcile name: kubernetes-dashboard namespace: kube-system --- apiVersion: apps/v1 kind: Deployment metadata: name: kubernetes-dashboard namespace: kube-system labels: k8s-app: kubernetes-dashboard addonmanager.kubernetes.io/mode: Reconcile spec: selector: matchLabels: k8s-app: kubernetes-dashboard template: metadata: labels: k8s-app: kubernetes-dashboard annotations: seccomp.security.alpha.kubernetes.io/pod: 'docker/default' spec: priorityClassName: system-cluster-critical containers: - name: kubernetes-dashboard image: lizhenliang/kubernetes-dashboard-amd64:v1.10.1 #image: huanwei/kubernetes-dashboard-amd64 resources: limits: cpu: 100m memory: 300Mi requests: cpu: 50m memory: 100Mi ports: - containerPort: 8443 protocol: TCP args: # PLATFORM-SPECIFIC ARGS HERE - --auto-generate-certificates volumeMounts: - name: kubernetes-dashboard-certs mountPath: /certs - name: tmp-volume mountPath: /tmp livenessProbe: httpGet: scheme: HTTPS path: / port: 8443 initialDelaySeconds: 30 timeoutSeconds: 30 volumes: - name: kubernetes-dashboard-certs secret: secretName: kubernetes-dashboard-certs - name: tmp-volume emptyDir: {} serviceAccountName: kubernetes-dashboard #nodeSelector: # "kubernetes.io/os": linux tolerations: - key: "CriticalAddonsOnly" operator: "Exists"
设置NodePort端口为3001
# cat dashboard-service.yaml apiVersion: v1 kind: Service metadata: name: kubernetes-dashboard namespace: kube-system labels: k8s-app: kubernetes-dashboard kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile spec: selector: k8s-app: kubernetes-dashboard type: NodePort ports: - port: 443 targetPort: 8443 nodePort: 30001
应用 本次一次性应用目录下所有配置文件
# kubectl apply -f . configmap/kubernetes-dashboard-settings created serviceaccount/kubernetes-dashboard created deployment.apps/kubernetes-dashboard created role.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created secret/kubernetes-dashboard-certs created secret/kubernetes-dashboard-key-holder created service/kubernetes-dashboard created
查看
# kubectl get pod,svc -n kube-system NAME READY STATUS RESTARTS AGE pod/kubernetes-dashboard-88ffb5bfc-7sjw4 1/1 Running 0 2m9s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes-dashboard NodePort 10.0.0.114 <none> 443:30001/TCP 6m50s
创建面向应用的用户
kubectl create serviceaccount dashboard-admin -n kube-system
集群角色绑定,设置最高的管理员权限
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
获取登录的token令牌
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
web页面登录https://nodeip:30001需要使用https登录 输入刚刚获取的token
11.部署多master
学习及测试部署单master即可满足需要,生产需要部署多master
从master01 192.168.1.63拷贝配置文件至master02
scp -r /opt/kubernetes/ root@192.168.1.64:/opt/ scp /usr/lib/systemd/system/kube-apiserver.service root@192.168.1.64:/usr/lib/systemd/system scp /usr/lib/systemd/system/kube-controller-manager.service root@192.168.1.64:/usr/lib/systemd/system scp /usr/lib/systemd/system/kube-scheduler.service root@192.168.1.64:/usr/lib/systemd/system #etcd文件也需要拷贝,需要etcd的ssl证书 scp -r /opt/etcd/ root@192.168.1.64:/opt/
修改配置文件
# cat kube-apiserver KUBE_APISERVER_OPTS="--logtostderr=false \ --log-dir=/opt/kubernetes/logs \ --v=4 \ --etcd-servers=https://192.168.1.63:2379,https://192.168.1.65:2379,https://192.168.1.66:2379 \ --insecure-bind-address=127.0.0.1 \ --bind-address=192.168.1.64 \ --insecure-port=8080 \ --secure-port=6443 \ --advertise-address=192.168.1.64 \ --allow-privileged=true \ --service-cluster-ip-range=10.10.10.0/24 \ --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction --authorization-mode=RBAC,Node \ --kubelet-https=true \ --enable-bootstrap-token-auth \ --token-auth-file=/opt/kubernetes/cfg/token.csv \ --service-node-port-range=30000-50000 \ --tls-cert-file=/opt/kubernetes/ssl/server.pem \ --tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \ --client-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \ --etcd-cafile=/opt/etcd/ssl/ca.pem \ --etcd-certfile=/opt/etcd/ssl/server.pem \ --etcd-keyfile=/opt/etcd/ssl/server-key.pem"
需要修改--bind-address 和--advertise-address对应ip地址,其他配置文件使用本机ip 127.0.0.1无需修改
启动
systemctl status kube-apiserver systemctl restart kube-controller-manager systemctl restart kube-scheduler systemctl enable kube-apiserver systemctl enable kube-controller-manager systemctl enable kube-scheduler
部署load balaner本次使用nginx
在192.168.1.61操作
yum安装nginx
yum -y install nginx
查看编译信息,默认包负载均衡参数--with-stream
四层负载均衡参考https://www.cnblogs.com/minseo/p/10288379.html
nginx -V
修改配置文件,增加四层负载均衡配置
# cat /etc/nginx/nginx.conf # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } stream { upstream k8s-apiserver{ server 192.168.1.63:6443; server 192.168.1.64:6443; } server { listen 192.168.1.61:6443; proxy_pass k8s-apiserver; } } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } # Settings for a TLS enabled server. # # server { # listen 443 ssl http2 default_server; # listen [::]:443 ssl http2 default_server; # server_name _; # root /usr/share/nginx/html; # # ssl_certificate "/etc/pki/nginx/server.crt"; # ssl_certificate_key "/etc/pki/nginx/private/server.key"; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 10m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # # # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; # # location / { # } # # error_page 404 /404.html; # location = /40x.html { # } # # error_page 500 502 503 504 /50x.html; # location = /50x.html { # } # } }
重启使配置生效
systemctl restart nginx
查看
# netstat -antp|grep 6443 tcp 0 0 192.168.1.61:6443 0.0.0.0:* LISTEN 29759/nginx: master
已经在nginx代理了两个后端服务器的6443端口,然后在node01 node02上面修改配置文件
/opt/kubernetes/cfg/bootstrap.kubeconfig
/opt/kubernetes/cfg/kubelet.kubeconfig
/opt/kubernetes/cfg/kube-proxy.kubeconfig
重启
systemctl restart kubelet
systemctl restart kube-proxy
node02 192.168.1.66进行同样修改操作后重启
为了查看负载均衡日志,修改nginx配置文件在stream增加两行记录日志
log_format main "$remote_addr $upstream_addr - $time_local $status"; access_log /var/log/nginx/k8s-access.log main;
重启nginx
systemctl restart nginx
重启node的kubelet查看日志
systemctl restart kubelet
192.168.1.61 查看日志
# tail -f /var/log/nginx/k8s-access.log 192.168.1.65 192.168.1.63:6443 - 02/Mar/2020:11:36:46 +0800 200 192.168.1.65 192.168.1.64:6443 - 02/Mar/2020:11:36:46 +0800 200
在master上面查看node状态是正常的及代表负载均衡通信正常
kubectl get node
在负载均衡backup 192.168.1.62同样安装nginx修改配置文件,启动nginx
使用keepalived创建一个虚拟ip实现高可用 keepalived+nginx高可用参考https://www.cnblogs.com/minseo/p/9216499.html
在nginx master 192.168.1.61 和 nginx backup 192.168.1.62安装keepalived
yum -y install keepalived
nginx master修改配置文件
global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr #vrrp_strict #需要注释否则VIP不通 vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state MASTER #master节点 interface eth0 #绑定的网口是eth0 virtual_router_id 51#ip 需要唯一主备一致 priority 150 #优先级,优先级越高越优秀占用VIP advert_int 1 authentication { auth_type PASS #认证 auth_pass 1111 #认证密码需要相同 } virtual_ipaddress { 192.168.1.60/24 dev eth0 label eth0:1 #设置VIP } }
backup配置文件
global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr #vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state BACKEND interface eth0 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.60/24 dev eth0 label eth0:1 } }
有如下不同 state为BACKEND
优先级低于master
启动keepalived
systemctl start keepalived systemctl enable keepalived
在master上面查看是否生成了VIP 192.168.1.60
backup
停止master的keepalived VIP会跳至backup
重启maste的keepalived则VIP会漂移至master,实现了故障迁移
如果是主的nginx出现故障,但是keepalived并不会把vip漂移,需要写脚本检测nginx宕则主动停止keepalived实现VIP漂移
check_nginx.sh
#!/bin/bash while true do if [ `nmap 127.0.0.1 -p 80|sed -n "6p"|grep open|wc -l` -lt 1 ];then systemctl stop keepalived fi sleep 5 done
后台运行并设置成开机启动即可实现如果是nginx出现故障也能实现VIP漂移
sh check_nginx.sh &
修改两个node192.168.1.65 192.168.1.66的配置文件
bootstrap.kubeconfig kubelet.kubeconfig kube-proxy.kubeconfig
把对应的IP修改成192.168.1.60重启kubelet kube-proxy即可
配置完毕在k8s-master01 192.168.1.63查看k8s集群状态
# kubectl get node NAME STATUS ROLES AGE VERSION 192.168.1.65 Ready <none> 3d3h v1.13.4 192.168.1.66 Ready <none> 3d3h v1.13.4
k8s多master配置完毕