kubernetes 集群部署之ETCD数据库部署、flannel网络组件安装
注意:本人使用二进制包来搭建k8s集群,比较耗费CPU内存,笔记本电脑的运行内存至少是32G,后期我会更新搭建多master节点的 高可用 k8s集群博客,大家可以关注我的博客后续。
搭建k8s集群所使用的安装包:(这是我是用的安装包版本)
搭建节点服务器:(三个节点)
服务器 | 需要安装的软件 |
master(192.168.100.128) | kube-apiserver、kube-controller-manager、kube-scheduler、etcd |
node01(192.168.100.131) | kubelet、kube-proxy、docker 、flannel 、etcd |
node02(192.168.100.136) | kubelet、kube-proxy、docker 、flannel 、etcd |
1、每个虚拟机配置相对应的静态IP地址
vi /etc/sysconfig/network-scripts/ifcfg-ens33
2、防止重启虚拟机IP地址变化
systemctl stop NetworkManager
systemctl enable NetworkManager
service network restart #重启网络
ping www.baidu.com #要实现网络通信
3、防火墙不要关闭。
systemctl start firewalld #开启防火墙
iptables -F #清空防火墙规则
setenforce 0 #关闭核心防护
三、部署ETCD集群
- ETCD之间通信都是经过加密的,所以要创建CA证书使用TLS加密通讯。
master节点:
[root@localhost ~]# mkdir k8s
[root@localhost ~]# cd k8s/
//编写cfssl.sh脚本,从官网下载制作证书的工具cfssl,直接放在/usr/local/bin目录下,方便系统识别,最后给工具加执行权限
[root@localhost k8s]# vi cfssl.sh
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson /usr/local/bin/cfssl-certinfo
[root@localhost k8s]# bash cfssl.sh #执行脚本等待安装下载软件
[root@localhost k8s]# ls /usr/local/bin/ #可以看到三个制作证书的工具
cfssl cfssl-certinfo cfssljson
#cfssl:生成证书工具
#cfssl-certinfo:查看证书信息
#cfssljson:通过传入json文件生成证书
[root@localhost k8s]# mkdir etcd-cert
[root@localhost k8s]# cd etcd-cert/
1、创建生成ca证书的配置文件
[root@localhost etcd-cert]# cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
2、创建ca证书的签名证书
[root@localhost etcd-cert]# cat > ca-csr.json <<EOF
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
3、用ca签名证书生成ca证书,得到ca-key.pem ca.pem
[root@localhost etcd-cert]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
4、指定etcd三个节点之间的通信验证—需要服务器签名证书 server-csr.json
[root@localhost etcd-cert]# cat > server-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"192.168.100.128", #修改成自己的节点IP地址
"192.168.100.131",
"192.168.100.136"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
5、用ca-key.pem、ca.pem、服务器签名证书 生成ETCD证书 ----server-key.pem、server.pem
[root@localhost etcd-cert]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
上传一个生成ETCD配置文件的脚本etcd.sh到 /root/k8s 目录下,脚本内容如下:
[root@localhost k8s]# vi /root/k8s/etcd.sh
#!/bin/bash
# example: ./etcd.sh etcd01 192.168.100.128 etcd02=https://192.168.100.131:2380,etcd03=https://192.168.100.136:2380
ETCD_NAME=$1
ETCD_IP=$2
ETCD_CLUSTER=$3
WORK_DIR=/opt/etcd
#创建节点的配置文件模板
cat <<EOF >$WORK_DIR/cfg/etcd
#[Member]
ETCD_NAME="${ETCD_NAME}"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_LISTEN_CLIENT_URLS="https://${ETCD_IP}:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://${ETCD_IP}:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://${ETCD_IP}:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://${ETCD_IP}:2380,${ETCD_CLUSTER}"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
#创建节点的启动脚本模板
cat <<EOF >/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=${WORK_DIR}/cfg/etcd
ExecStart=${WORK_DIR}/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=${WORK_DIR}/ssl/server.pem \
--key-file=${WORK_DIR}/ssl/server-key.pem \
--peer-cert-file=${WORK_DIR}/ssl/server.pem \
--peer-key-file=${WORK_DIR}/ssl/server-key.pem \
--trusted-ca-file=${WORK_DIR}/ssl/ca.pem \
--peer-trusted-ca-file=${WORK_DIR}/ssl/ca.pem
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
#重启服务,并设置开机自启
systemctl daemon-reload
systemctl enable etcd
systemctl restart etcd
把下载好的三个软件上传到k8s目录下
先解压 etcd软件包到当前目录下,再创建etcd集群的工作目录
[root@localhost k8s]# tar zxvf etcd-v3.3.10-linux-amd64.tar.gz
[root@localhost k8s]# ls etcd-v3.3.10-linux-amd64
Documentation etcd etcdctl README-etcdctl.md README.md READMEv2-etcdctl.md
#稍后使用源码包中的etcd、etcdctl 应用程序命令
[root@localhost k8s]# mkdir -p /opt/etcd/{cfg,bin,ssl}
[root@localhost k8s]# ls /opt/etcd/
bin cfg ssl
1、把etcd、etcdctl 执行文件放在/opt/etcd/bin/
[root@localhost k8s]# mv etcd-v3.3.10-linux-amd64/etcd etcd-v3.3.10-linux-amd64/etcdctl /opt/etcd/bin/
2、拷贝证书到/opt/etcd/ssl/目录下
[root@localhost k8s]# cp etcd-cert/*.pem /opt/etcd/ssl/
[root@localhost k8s]# ls /opt/etcd/ssl/
ca-key.pem ca.pem server-key.pem server.pem
执行 etcd.sh 脚本产生etcd集群的配置脚本和服务启动脚本,进入卡住状态等待其他节点加入
#注意:修改成自己的ip地址
[root@localhost k8s]# bash etcd.sh etcd01 192.168.100.128 etcd02=https://192.168.100.131:2380,etcd03=https://192.168.100.136:2380
//使用另外一个会话窗口,会发现etcd进程己经开启
[root@localhost k8s]# ps -ef | grep etcd
3.4、node节点加入ETCD集群(实现内部通信)
1、在master节点上拷贝证书去其他node节点
[root@localhost k8s]# scp -r /opt/etcd/ root@192.168.100.131:/opt/
[root@localhost k8s]# scp -r /opt/etcd/ root@192.168.100.136:/opt/
2、把master节点的启动脚本拷贝其他节点
[root@localhost k8s]# scp /usr/lib/systemd/system/etcd.service root@192.168.100.131:/usr/lib/systemd/system/
root@192.168.100.131's password:
etcd.service 100% 923 105.2KB/s 00:00
[root@localhost k8s]# scp /usr/lib/systemd/system/etcd.service root@192.168.100.136:/usr/lib/systemd/system/
root@192.168.100.136's password:
etcd.service 100% 923 830.1KB/s 00:00
[root@localhost k8s]#
3、在node01 节点上修改配置文件
[root@localhost ~]# vi /opt/etcd/cfg/etcd
4、在node02 节点上修改配置文件
[root@localhost ~]# vi /opt/etcd/cfg/etcd
5、在master节点输入bash等待node节点加入集群
[root@localhost k8s]# bash etcd.sh etcd01 192.168.100.128 etcd02=https://192.168.100.131:2380,etcd03=https://192.168.100.136:2380
6、同时快速启动 node01、node02节点
[root@localhost ~]# systemctl start etcd
[root@localhost ~]# systemctl status etcd
在master节点上执行,注意:要在ca.pem文件的路径/opt/etcd/ssl/下执行检查集群的命令
[root@localhost k8s]# cd /opt/etcd/ssl/
[root@localhost ssl]# /opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.100.128:2379,https://192.168.100.131:2379,https://192.168.100.136:2379" cluster-health
- 所有node节点必须要部署docker引擎,docker安装部署可以参考我之前的博客:Docker部署与镜像加速、网络优化
1、在master节点上,将分配的子网段写入到ETCD中,供flannel使用
注意:必须在证书存放的路径/root/k8s/etcd-cert下执行此命令。
[root@localhost etcd-cert]# /opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.100.128:2379,https://192.168.100.131:2379,https://192.168.100.136:2379" set /coreos.com/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'
查看写入的信息
[root@localhost etcd-cert]# /opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.100.128:2379,https://192.168.100.131:2379,https://192.168.100.136:2379" get /coreos.com/network/config
{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}
2、两个node节点:上传软件包flannel并解压到宿主目录下 。
[root@localhost ~]# tar zxvf flannel-v0.10.0-linux-amd64.tar.gz
3、在两个node节点上创建k8s工作目录
[root@localhost ~]# mkdir -p /opt/kubernetes/{cfg,bin,ssl}
[root@localhost ~]# mv mk-docker-opts.sh flanneld /opt/kubernetes/bin/
[root@localhost ~]# ls /opt/kubernetes/bin/
上传可以生成配置文件和启动文件的脚本flannel.sh。
//脚本内容:
[root@localhost ~]# vi flannel.sh
#!/bin/bash
ETCD_ENDPOINTS=${1:-"http://127.0.0.1:2379"}
cat <<EOF >/opt/kubernetes/cfg/flanneld
FLANNEL_OPTIONS="--etcd-endpoints=${ETCD_ENDPOINTS} \
-etcd-cafile=/opt/etcd/ssl/ca.pem \
-etcd-certfile=/opt/etcd/ssl/server.pem \
-etcd-keyfile=/opt/etcd/ssl/server-key.pem"
EOF
cat <<EOF >/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
EOF
systemctl daemon-reload
systemctl enable flanneld
systemctl restart flanneld
4、两个node节点开启flannel网络功能
[root@localhost ~]# bash flannel.sh https://192.168.100.128:2379,https://192.168.100.131:2379,https://192.168.100.136:2379
查看网络状态是否运行
[root@localhost ~]# systemctl status flanneld
两个node节点:修改docker的配置文件
[root@localhost ~]# vi /usr/lib/systemd/system/docker.service
//修改添加两处:
EnvironmentFile=/run/flannel/subnet.env
$DOCKER_NETWORK_OPTIONS
查看 flanne网络分配的子网段
[root@localhost ~]# cat /run/flannel/subnet.env
可以看到node1节点是172.17.14.0网段,node2节点是172.17.32.0网段。
重启docker服务
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
1、两个node节点分别创建并自动进入centos:7容器。
[root@localhost ~]# docker run -it centos:7 /bin/bash
Unable to find image 'centos:7' locally
7: Pulling from library/centos
ab5ef0e58194: Pull complete
Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c
Status: Downloaded newer image for centos:7
[root@690ec8bdaa81 /]# yum install -y net-tools #安装后可以使用ifconfig命令
2、ifconfig查看IP地址,用ping命令检测网络是否互通
经验证,可以互通,flannel网络搭建完成!!
kubernetes二进制集群部署--------单master集群(步骤非常详细,适合初学者)
一、集群环境
在上篇博客介绍过了,我的搭建部署也是在上一篇的基础上做的。
博客链接:kubernetes 集群部署之ETCD数据库部署、flannel网络组件安装
二、部署master节点组件
在 Master 上要部署以下三大核心组件:
- kube-apiserver:是集群的统一入口,各组件协调者,所有对象资源的增删改查和监听操作都交给 APIServer 处理后再提交给 Etcd 存储;
- kube-controller-manager:处理群集中常规后台任务,一个资源对应一个控制器,而 controller-manager 就是负责管理这些控制器的;
- kube-scheduler:根据调度算法为新创建的 Pod 选择一个 Node 节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同节点上。
- 操作流程:配置文件 -----> systemd 管理组件 -----> 启动
先把master压缩包放在k8s目录下
[root@localhost k8s]# unzip master.zip
解压出来的三个组件脚本我自己编写的,具体内容在下面的操作中展示。
[root@localhost k8s]# chmod +x controller-manager.sh #给controll脚本加上权限
[root@localhost k8s]# mkdir -p /opt/kubernetes/{cfg,ssl,bin}
2.1、部署 apiserver
2.1.1、制作api-server证书
1、创建api-server证书目录
[root@localhost k8s]# mkdir k8s-cert
[root@localhost k8s]# cd k8s-cert/
2、编写证书生成脚本
[root@localhost k8s-cert]# vi k8s-cert.sh
#编写ca证书的配置文件
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
#编写ca签名证书文件
cat > ca-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
#使用签名证书生成ca.pem、ca-key.pem文件
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
#编写apiserver的签名证书
注意:master2节点和LB节点的IP地址是 为了之后的多master节点部署添加的
cat > server-csr.json <<EOF
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"192.168.100.128", #master1节点
"192.168.100.132", #master2节点
"192.168.100.100", #VIP地址
"192.168.100.133", #负载调度器(master节点)
"192.168.100.129", #负载调度器(backup节点)
"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"
}
]
}
EOF
#使用之前的文件生成server证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
#编写用户证书
cat > admin-csr.json <<EOF
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
# 编写 kube-proxy 证书
cat > kube-proxy-csr.json <<EOF
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
3、执行脚本,并把通信证书拷贝到 /opt/kubernetes/ssl目录下
[root@localhost k8s-cert]# bash k8s-cert.sh
[root@localhost k8s-cert]# cp ca*pem server*pem /opt/kubernetes/ssl/
2.1.2、解压二进制文件
1、解压k8s安装包
[root@localhost k8s]# tar zxvf kubernetes-server-linux-amd64.tar.gz
2、复制关键的命令文件到/opt/kubernetes/bin/
[root@localhost ~]# cd /root/k8s/kubernetes/server/bin/
[root@localhost bin]# cp kube-apiserver kubectl kube-controller-manager kube-scheduler /opt/kubernetes/bin/
2.1.3、制作token令牌
[root@localhost ~]# cd /root/k8s/
//使用下面的 head命令 随机生成序列号
[root@localhost k8s]# head -c 16 /dev/urandom | od -An -t x | tr -d ' '
84cf410ca1d9dd456dbba668de2c1aca #复制序列号写入 token.csv 中
[root@localhost k8s]# vi /opt/kubernetes/cfg/token.csv
#写入内容:序列号,用户名,id,角色
84cf410ca1d9dd456dbba668de2c1aca,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
2.1.4、开启 apiserver
1、二进制文件、token令牌、证书都准备好了,开启apiserver,指向ETCD集群,把信息保存到ETCD中。
[root@localhost k8s]# bash apiserver.sh
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-apiserver.service to /usr/lib/systemd/system/kube-apiserver.service.
apiserver.sh脚本:
#!/bin/bash
MASTER_ADDRESS=$1
ETCD_SERVERS=$2
#在k8s工作目录里生成kube-apiserver 配置文件
cat <<EOF >/opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \\
--v=4 \\
--etcd-servers=${ETCD_SERVERS} \\
--bind-address=${MASTER_ADDRESS} \\
--secure-port=6443 \\
--advertise-address=${MASTER_ADDRESS} \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,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"
EOF
#生成启动脚本
cat <<EOF >/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
EOF
#启动apiserver组件
systemctl daemon-reload
systemctl enable kube-apiserver
systemctl restart kube-apiserver
2、检查进程是否启动成功。
[root@localhost k8s]# ps aux | grep kube
3、查看监听的https端口
[root@localhost k8s]# netstat -natp | grep 6443
[root@localhost k8s]# netstat -natp | grep 8080
2.2、部署scheduler
scheduler.sh脚本内容:
#!/bin/bash
MASTER_ADDRESS=$1
cat <<EOF >/opt/kubernetes/cfg/kube-scheduler
KUBE_SCHEDULER_OPTS="--logtostderr=true \\
--v=4 \\
--master=${MASTER_ADDRESS}:8080 \\
--leader-elect"
EOF
cat <<EOF >/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
EOF
systemctl daemon-reload
systemctl enable kube-scheduler
systemctl restart kube-scheduler
启动scheduler服务
[root@localhost k8s]# ./scheduler.sh 127.0.0.1
2.3、部署controller-manager
controller-manager.sh脚本编写内容:
#!/bin/bash
MASTER_ADDRESS=$1
cat <<EOF >/opt/kubernetes/cfg/kube-controller-manager
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \\
--v=4 \\
--master=${MASTER_ADDRESS}:8080 \\
--leader-elect=true \\
--address=127.0.0.1 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--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"
EOF
cat <<EOF >/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
EOF
systemctl daemon-reload
systemctl enable kube-controller-manager
systemctl restart kube-controller-manager
启动controller-manager
[root@localhost k8s]# ./controller-manager.sh 127.0.0.1
查看master节点状态
[root@localhost k8s]# /opt/kubernetes/bin/kubectl get cs
三、部署node节点组件
在 node上要部署以下三大核心组件:
- kubelet:是master在node节点上的agent,可以管理本机运行容器的生命周期,例如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作,kubelet 将每个 Pod转换成一组容器。
- kube-proxy:在 node节点上实现 Pod网络代理,维护网络规划和四层负载均衡工作。
- docker:容器(我们已经安装好了)
3.1、部署kubeconfig
- 在master节点上进行操作
1、在master上,把 kubelet、kube-proxy 拷贝到 两个node节点上去
[root@localhost bin]# scp kubelet kube-proxy root@192.168.100.131:/opt/kubernetes/bin/
[root@localhost bin]# scp kubelet kube-proxy root@192.168.100.136:/opt/kubernetes/bin/
2、编写kubeconfig脚本
[root@localhost k8s]# mkdir kubeconfig
[root@localhost k8s]# cd kubeconfig/
[root@localhost kubeconfig]# cat /opt/kubernetes/cfg/token.csv //获取 token令牌的序列号
84cf410ca1d9dd456dbba668de2c1aca,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
[root@localhost kubeconfig]# vim kubeconfig
APISERVER=$1 #master节点的IP地址
SSL_DIR=$2 #k8s证书路径
# 创建kubelet bootstrapping kubeconfig
export KUBE_APISERVER="https://$APISERVER:6443"
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=$SSL_DIR/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap \
--token=84cf410ca1d9dd456dbba668de2c1aca \ #注意:随机生成的序列号不同,要修改
--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=$SSL_DIR/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=$SSL_DIR/kube-proxy.pem \
--client-key=$SSL_DIR/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
3、设置环境变量,使可以在任意目录下识别kubectl命令
[root@localhost kubeconfig]# export PATH=$PATH:/opt/kubernetes/bin/
4、检查健康状态
[root@localhost kubeconfig]# kubectl get cs
5、运行kubeconfig脚本生成配置文件
[root@localhost kubeconfig]# bash kubeconfig 192.168.100.128 /root/k8s/k8s-cert/
将生成的配置文件传给两个node节点
[root@localhost kubeconfig]# scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.100.131:/opt/kubernetes/cfg/
[root@localhost kubeconfig]# scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.100.136:/opt/kubernetes/cfg/
6、创建 bootstrap角色赋予权限,用于连接 apiserver请求签名(重要)
[root@localhost kubeconfig]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
clusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created
3.2、部署node1的kubelet组件
- 在node1节点上操作
1、编写kubelet.sh脚本
#!/bin/bash
NODE_ADDRESS=$1
DNS_SERVER_IP=${2:-"10.0.0.2"}
cat <<EOF >/opt/kubernetes/cfg/kubelet
KUBELET_OPTS="--logtostderr=true \\
--v=4 \\
--hostname-override=${NODE_ADDRESS} \\
--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"
EOF
cat <<EOF >/opt/kubernetes/cfg/kubelet.config
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: ${NODE_ADDRESS}
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- ${DNS_SERVER_IP}
clusterDomain: cluster.local.
failSwapOn: false
authentication:
anonymous:
enabled: true
EOF
cat <<EOF >/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
EOF
systemctl daemon-reload
systemctl enable kubelet
systemctl restart kubelet
2、加执行权限
[root@localhost ~]# chmod +x /root/kubelet.sh
3、运行脚本启动kubelet,向master集群发送请求
[root@localhost ~]# bash kubelet.sh 192.168.100.131
4、检查 kubelet 服务启动
[root@localhost ~]# ps aux | grep kube
5、在master节点上,检查 node01 节点的请求
//用下面这个命令检查得到node1请求,并复制node1请求的名字
[root@localhost kubeconfig]# kubectl get csr
Pending(意思:等待群集给该节点颁发证书)
6、master设置同意连接请求,颁发证书
//同意请求的命令格式:kubectl certificate approve node1请求的NAME
[root@localhost kubeconfig]# kubectl certificate approve node-csr-wvb8EvLCzVY5I6sKJGeMh4oDLOkYVlHc6hY8_UHri4U
[root@localhost kubeconfig]# kubectl get csr #发现状态变成允许
7、查看群集节点,成功加入 node01 节点
[root@localhost kubeconfig]# kubectl get node
NAME STATUS ROLES AGE VERSION
192.168.100.131 Ready <none> 4m44s v1.12.3
3.3、部署node1 的kube-proxy组件
1、编写proxy.sh 脚本
#!/bin/bash
NODE_ADDRESS=$1
cat <<EOF >/opt/kubernetes/cfg/kube-proxy
KUBE_PROXY_OPTS="--logtostderr=true \\
--v=4 \\
--hostname-override=${NODE_ADDRESS} \\
--cluster-cidr=10.0.0.0/24 \\
--proxy-mode=ipvs \\
--kubeconfig=/opt/kubernetes/cfg/kube-proxy.kubeconfig"
EOF
cat <<EOF >/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
EOF
systemctl daemon-reload
systemctl enable kube-proxy
systemctl restart kube-proxy
2、加执行权限
[root@localhost ~]# chmod +x /root/proxy.sh
3、在 node1节点上操作,启动 proxy服务,并查看状态是否正常
[root@localhost ~]# bash proxy.sh 192.168.100.131
[root@localhost ~]# systemctl status kube-proxy.service
3.4、部署node2节点的 kubelet 和 kube-proxy 服务
1、为了提高效率,我们将 node01上现成的 /opt/kubernetes目录复制到其他节点进行修改。
[root@localhost ~]# scp -r /opt/kubernetes/ root@192.168.100.136:/opt/
再把kubelet,kube-proxy的service文件拷贝到node2中
[root@localhost ~]# scp /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@192192.168.109..168.100.136:/usr/lib/systemd/system/
2、接下来在 node02 节点上的操作
- 首先,先删除复制过来的证书,因为待会 node02 会自行申请属于自己的证书
[root@localhost ~]# cd /opt/kubernetes/ssl/
[root@localhost ssl]# ls
kubelet-client-2020-04-30-11-48-13.pem kubelet.crt
kubelet-client-current.pem kubelet.key
[root@localhost ssl]# rm -rf *
- 修改配置文件 kubelet 、kubelet.config 、kube-proxy(三个配置文件)中node1的IP地址
[root@localhost ssl]# cd /opt/kubernetes/cfg/
[root@localhost cfg]# vim kubelet
[root@localhost cfg]# vi kubelet.config
[root@localhost cfg]# vi kube-proxy
3、启动node2节点的 kubelet、kube-proxy 服务,并设置开机自启
[root@localhost cfg]# systemctl start kubelet.service
[root@localhost cfg]# systemctl enable kubelet.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /usr/lib/systemd/system/kubelet.service.
[root@localhost cfg]# systemctl start kube-proxy.service
[root@localhost cfg]# systemctl enable kube-proxy.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-proxy.service to /usr/lib/systemd/system/kube-proxy.service.
4、在master上查看node2节点的请求
[root@localhost kubeconfig]# kubectl get csr
接下来和刚刚一样,授权许可加入集群
[root@localhost kubeconfig]# kubectl certificate approve node-csr-DiaTo2KEty9zNGCNdV4Hw8AUPfjd7gdLHvph41lkQ9k
- 1
四、验证集群
查看群集中的节点
[root@localhost ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
192.168.100.131 Ready <none> 50m v1.12.3
192.168.100.136 Ready <none> 22s v1.12.3
到这里,我的单master节点的K8s集群部署完成了。
kubernetes二进制集群部署--------多master集群(步骤非常详细,适合初学者)
文章目录
一、多master节点集群搭建示意图
我的虚拟机 IP地址规划:
Master节点
master01:192.168.100.128
master02:192.168.100.132
VIP 地址:192.168.100.100
Node节点
node01:192.168.100.131
node02:192.168.100.136
负载均衡
Nginx01:192.168.100.133 master
Nginx02:192.168.100.129 backup
Harbor私有仓库
192.168.100.134
- 本篇博客将在单master节点的K8s集群上搭建 多master节点集群 和 LB负载均衡服务器。
二、部署环境—单 master 节点的 k8s集群
部署步骤在之前的博客中已经介绍了。
三、添加 master2 多节点K8s集群
3.1、在master1上拷贝重要文件给master2
1、复制/opt/kubernetes/目录下的所有文件到master02节点上
[root@localhost kubeconfig]# scp -r /opt/kubernetes/ root@192.168.100.132:/opt
2、复制master1中三个组件的启动脚本:kube-apiserver.service、kube-controller-manager.service、kube-scheduler.service
[root@localhost kubeconfig]# scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@192.168.100.132:/usr/lib/systemd/system/
3.2、master2修改复制的配置文件
只有kube-apiserver文件里有IP地址,所以只需要修改这个文件即可。
[root@master2 ~]# cd /opt/kubernetes/cfg/
[root@master2 cfg]# ls
kube-apiserver kube-controller-manager kube-scheduler token.csv
[root@master2 cfg]# vi kube-apiserver
#修改两处:
3.3、制作master2 的ETCD证书
- master2节点与node节点之间的操作信息需要保存在ETCD集群中,所以 master 节点都必须有etcd证书,实现通信。
拷贝master1上已有的 etcd 证书给 master2 使用
[root@master1 ~]# scp -r /opt/etcd/ root@192.168.100.132:/opt/
root@192.168.100.132's password:
etcd 100% 523 326.2KB/s 00:00
etcd 100% 18MB 45.1MB/s 00:00
etcdctl 100% 15MB 33.0MB/s 00:00
ca-key.pem 100% 1679 160.2KB/s 00:00
ca.pem 100% 1265 592.6KB/s 00:00
server-key.pem 100% 1679 884.2KB/s 00:00
server.pem 100% 1338 768.5KB/s 00:00
3.4、启动 master2 的三个组件
//开启 apiserver 组件
[root@master2 cfg]# systemctl start kube-apiserver.service
[root@master2 cfg]# systemctl enable kube-apiserver.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-apiserver.service to /usr/lib/systemd/system/kube-apiserver.service.
开启 controller-manager 组件
[root@master2 cfg]# systemctl start kube-controller-manager.service
[root@master2 cfg]# systemctl enable kube-controller-manager.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-controller-manager.service to /usr/lib/systemd/system/kube-controller-manager.service.
//开启 scheduler 组件
[root@master2 cfg]# systemctl start kube-scheduler.service
[root@master2 cfg]# systemctl enable kube-scheduler.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-scheduler.service to /usr/lib/systemd/system/kube-scheduler.service.
增加环境变量,优化kubectl命令
[root@master2 cfg]# vi /etc/profile
在末尾添加:
export PATH=$PATH:/opt/kubernetes/bin/
[root@master2 cfg]# source /etc/profile 使之生效
3.5、验证master2是否加入K8s集群
在master2 上查看node节点情况(和 master01一样即可)
[root@localhost cfg]# kubectl get node
- 1
四、搭建nginx负载均衡
准备两台虚拟机 搭建 nginx的高可用群集。
- 节点地址如下
Nginx01:192.168.100.133 master
Nginx02:192.168.100.129 backup
1、首先关闭防火墙
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# setenforce 0
2、建立本地yum官方nginx源
//编写repo文件
[root@localhost ~]# vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
[root@localhost ~]# yum list
[root@localhost ~]# yum install nginx -y //下载nginx
3、接下来在配置文件设置 nginx的四层负载均衡
[root@localhost ~]# vim /etc/nginx/nginx.conf
在events模块下添加以下内容:日志格式、日志存放位置、upstream模块
//检查配置文件是否有语法错误
[root@localhost ~]# nginx -t
[root@localhost ~]# systemctl start nginx //开启服务
//注意:查看端口6443必须在监听中,如下图。
[root@localhost ~]# netstat -natp | grep nginx
五、搭建 keepalived 高可用服务
5.1、搭建 nginx 的高可用
1、yum安装keepalived软件
[root@localhost ~]# yum install keepalived -y
2、修改 nginx1 和 nginx2 的配置文件
- nginx1节点作为master。
[root@nginx1 ~]# vi /etc/keepalived/keepalived.conf
//删除配置文件全部内容,添加以下内容:
! Configuration File for keepalived
global_defs {
# 接收邮件地址
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# 邮件发送地址
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER
}
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh" ##检测nginx脚本的路径,稍后会创建
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100 ##优先级
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.100.100/24 ##虚拟IP地址
}
track_script {
check_nginx
}
}
- nginx2 节点作为backup。
[root@nginx2 ~]# vi /etc/keepalived/keepalived.conf
//删除配置文件全部内容,添加以下内容:
! Configuration File for keepalived
global_defs {
# 接收邮件地址
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# 邮件发送地址
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER
}
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh" ##检测脚本的路径,稍后会创建
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90 ##优先级低于master
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.100.100/24 ##虚拟IP地址
}
track_script {
check_nginx
}
}
3、创建检测脚本
[root@localhost ~]# vim /etc/nginx/check_nginx.sh
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
systemctl stop keepalived
fi
[root@localhost ~]# chmod +x /etc/nginx/check_nginx.sh //授权
4、开启keepalived 服务
[root@localhost ~]# systemctl start keepalived.service
5、查看ip地址,可以看到高可用群集中的master节点上有漂移地址,backup节点上没有。
[root@localhost ~]# ip a
5.2、验证高可用功能
1、此时 虚拟ip在 nginx1 上,验证地址漂移,可以在 lb01 中使用 pkill nginx 停止nginx服务,再在 lb02 上使用 ip a 命令查看地址是否进行了漂移。
2、恢复操作:此时在 nginx02上,我们先启动 nginx服务,再启动 keepalived服务,再用 ip a命令查看,地址又漂移回来了,而 nginx02上没有虚拟ip。
六、node节点指向 LB 高可用群集
1、修改 两个node节点的配置文件,server ip 地址为统一的VIP地址(三个文件)
//修改内容:server: https://192.168.100.100:6443(都改成vip地址)
[root@localhost cfg]# vim /opt/kubernetes/cfg/bootstrap.kubeconfig
[root@localhost cfg]# vim /opt/kubernetes/cfg/kubelet.kubeconfig
[root@localhost cfg]# vim /opt/kubernetes/cfg/kube-proxy.kubeconfig
重启服务
[root@localhost cfg]# systemctl restart kubelet.service
[root@localhost cfg]# systemctl restart kube-proxy.service
2、检查修改内容
//确保必须在此路径下 grep 检查
[root@localhost ~]# cd /opt/kubernetes/cfg/
[root@localhost cfg]# grep 100 *
3、接下来在 nginx1 上查看 nginx 的 k8s日志:
[root@localhost ~]# tail /var/log/nginx/k8s-access.log
七、k8s多节点集群测试
//在 master1上操作,创建 Pod进行测试
[root@localhost kubeconfig]# kubectl run nginx --image=nginx
//查看 Pod 状态
[root@master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-dbddb74b8-vj4wk 1/1 Running 0 16s
此时已经创建完成,正在运行中。
//查看刚刚创建的nginx日志
[root@master1 ~]# kubectl logs nginx-dbddb74b8-vj4wk
Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log nginx-dbddb74b8-vj4wk)
#出现 error 是由于权限不足,下面来授权解决一下这个问题。
解决办法(添加匿名用户授予权限):
[root@master1 ~]# kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
clusterrolebinding.rbac.authorization.k8s.io/cluster-system-anonymous created
此时,再次查看日志,就不会出现报错,但是没有信息产生,因为没有访问容器。
//查看 Pod 网络
[root@localhost kubeconfig]# kubectl get pods -o wide
可以看出,这个在master1上创建的 pod 被分配到了node01上了。
我们可以在对应网络的node节点上操作就可以直接访问。
故在node01上操作:
[root@localhost cfg]# curl 172.17.14.3
我们在node节点之间部署了 flannel网络组件,实现node节点互通。所以在node1和node2的浏览器上访问这个地址:172.17.14.3
因为flannel组件挂了,没有及时发现,我解决完这个问题后,flannel分配的IP地址发生变化,导致Pod的IP网段变了,但是node2节点是可以访问换这个Pod的,所以node2的效果图这里就不展示了。
建议大家的虚拟机用挂起状态,并且开机的时候,检查一下之前配置的服务状态是否正常。