使用python脚本部署k8s集群

1.环境规划:

节点IP地址操作系统配置
脚本运行节点192.168.174.5centos7.92G2核
server192.168.174.150centos7.92G2核
client1192.168.174.151centos7.92G2核
client2192.168.174.152centos7.92G2

2.运行准备:

yum install -y python python-pip
pip install pexpect

3.完整脚本:

# coding=UTF-8
import sys,os,pexpect,subprocess,remaster_addresses=["192.168.174.150"]           # 主节点们的IP地址
master_domains=["server"]                          # 域名们
client_addresses=["192.168.174.151","192.168.174.152"]           # 从节点们的IP地址
client_domains=["client1","client2"]                          # 域名们host_username="root"                                         # ssh连接的用户,控制端的用户为root
host_passwd="110119"                                         # ssh连接的用户密码yum_mount_dev="/dev/cdrom"                                   # 本地yum源挂载设备路径
yum_mount_dir="/mnt/cdrom"                                   # 本地yum源挂载点chrony_allows_addresses="192.168.174.0"                       # chrony主节点允许那个网段的从节点来同步时间# ping主机
def ping_hosts(address):ping_flag=os.system("ping -c 3 {}".format(address))if ping_flag != 0:print("\033[1;31m" + "Failed:{address} ping失败" + "\033[0m")sys.exit("请检查!")
for i in range(0, len(master_addresses)):ping_hosts(master_addresses[i])print("\n")
for i in range(0, len(client_addresses)):ping_hosts(client_addresses[i])print("\n")# 1.本地创建ssh公钥
if os.path.exists("/root/.ssh/id_rsa.pub") == True:print("\033[32m"+"ssh公钥已创建"+"\033[0m")                # 输出绿色字体
else:print("\033[32m"+"ssh公钥未创建,开始创建"+"\033[0m")child = pexpect.spawn('ssh-keygen -t rsa -b 1024')child.expect('Enter file in which to save the key')child.sendline('')child.expect('Enter passphrase')child.sendline('')child.expect('Enter same passphrase again')child.sendline('')child.expect(pexpect.EOF)               # 用于等待子进程的结束print(child.before.decode())            # 等待命令执行完毕并打印输出信息print("\033[32m" + "ssh公钥已创建" + "\033[0m")print("\n")# 向被控主机添加公钥的方法
def add_ssh_public_key_client(address,username,password):print("\033[32m"+"{}正在被添加公钥".format(address)+"\033[0m")# BatchMode=yes:表示使SSH在连接过程中不会提示输入密码,而直接尝试免密连接,-o ConnectTimeout=5:表示限制连接超时时间为5秒public_key_flag=os.system("ssh {}@{} -o BatchMode=yes 'exit' &> /dev/null".format(username,address))if public_key_flag== 0:print("\033[32m" + "{}已经可以ssh连接".format(address) + "\033[0m")returnchild = pexpect.spawn('ssh-copy-id -i /root/.ssh/id_rsa.pub {}@{}'.format(username,address))try:child.expect('Are you sure you want to continue connecting')except pexpect.exceptions.TIMEOUT:       # 如果try块中的咨询超时5秒没有出现就会出现异常pexpect.TIMEOUTprint("\033[32m"+"{}已经不是首次ssh连接了".format(address)+"\033[0m")else:                         # 是否回答咨询yeschild.sendline('yes')finally:child.expect('password')child.sendline(password)child.expect(pexpect.EOF)               # 用于等待子进程的结束print(child.before.decode())            # 等待命令执行完毕并打印输出信息
# 测试ssh连接的方法
def test_ssh_connection(all_flag,address,username):print("\033[32m" + "{}测试是否可以ssh连接".format(address) + "\033[0m")flag=os.system('ssh {}@{} -o ConnectTimeout=5 "exit"'.format(username,address))if flag==0:print("\033[32m" + "Success: {}可以ssh免密连接".format(address) + "\033[0m")else:print("\033[1;31m" + "Failed: {}ssh免密连接失败".format(address) + "\033[0m")     # 输出红色字体all_flag=1return all_flag# 本地的密钥开始加入被控制主机
for i in range(0, len(master_addresses)):add_ssh_public_key_client(master_addresses[i],host_username,host_passwd)print("\n")
for i in range(0, len(client_addresses)):add_ssh_public_key_client(client_addresses[i],host_username,host_passwd)print("\n")
# 测试ssh连接
for i in range(0, len(master_addresses)):final_flag=test_ssh_connection(0,master_addresses[i],host_username)
for i in range(0, len(client_addresses)):final_flag = test_ssh_connection(0, client_addresses[i], host_username)
if final_flag ==1:sys.exit("ssh测试失败,请检查!")
else:print("\033[32m" + "Success: 全部可以ssh免密连接" + "\033[0m")
print("\n")# 2.配置防火墙和selinux的方法
def set_firwalld_selinux(address,username):print("\033[32m" + "{}正在配置防火墙和selinux".format(address + "\033[0m"))fir_flag=os.system('ssh {}@{} "systemctl stop firewalld;systemctl disable firewalld"'.format(username,address))if fir_flag!=0:print("\033[1;31m" + "Failed: 防火墙修改失败" + "\033[0m")sys.exit("请检查!")sel_flag=os.system("ssh {}@{} 'sed -i 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config'".format(username,address))if sel_flag!=0:print("\033[1;31m" + "Failed: selinux修改失败" + "\033[0m")sys.exit("请检查!")
# 配置防火墙和selinux
for i in range(0, len(master_addresses)):set_firwalld_selinux(master_addresses[i],host_username)
for i in range(0, len(client_addresses)):set_firwalld_selinux(client_addresses[i],host_username)
print("\n")# 3.配置域名映射
print("\033[32m" + "本地开始配置域名映射" + "\033[0m")
with open("/etc/hosts","w") as f:                      # w重写,a添加,只读f.write("127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4\n")f.write("::1         localhost localhost.localdomain localhost6 localhost6.localdomain6\n")for i in range(0, len(master_addresses)):f.write("{} {}\n".format(master_addresses[i],master_domains[i]))for i in range(0, len(client_addresses)):f.write("{} {}\n".format(client_addresses[i],client_domains[i]))
# 复制本地的/etc/hosts覆盖掉远程主机的/etc/hosts文件
for i in range(0, len(master_addresses)):os.system("scp /etc/hosts {}@{}:/etc/hosts".format(host_username,master_addresses[i]))
for i in range(0, len(client_addresses)):os.system("scp /etc/hosts {}@{}:/etc/hosts".format(host_username,client_addresses[i]))# 使用域名首次ssh连接
# 首次域名ssh连接的方法
def first_domain_name_con(domain,username,password):print("\033[32m"+"{}首次ssh连接".format(domain)+"\033[0m")# BatchMode=yes:表示使SSH在连接过程中不会提示输入密码,而直接尝试免密连接,-o ConnectTimeout=5:表示限制连接超时时间为5秒os.system("ssh -o BatchMode=yes -o ConnectTimeout=5 {}@{} 'exit' &> /dev/null".format(username, domain))first_domain_flag = os.system("ssh -o BatchMode=yes -o ConnectTimeout=5 {}@{} 'exit'".format(username, domain))if first_domain_flag == 0:print("\033[32m" + "{}已经可以ssh连接".format(domain) + "\033[0m")returnchild = pexpect.spawn('ssh {}@{} "exit"'.format(username,domain))try:connecting_tuple = child.expect('Are you sure you want to continue connecting')except pexpect.exceptions.TIMEOUT:print("\033[32m"+"{}已经不是首次ssh连接了".format(domain)+"\033[0m")else:child.sendline('yes')child.expect(pexpect.EOF)               # 用于等待子进程的结束print(child.before.decode())            # 等待命令执行完毕并打印输出信息for i in range(0, len(master_domains)):first_domain_name_con(master_domains[i],host_username,host_passwd)
for i in range(0, len(client_domains)):first_domain_name_con(client_domains[i], host_username, host_passwd)print("\n")# 4.配置主机名(主机名即域名)
print("\033[32m" + "开始配置主机名" + "\033[0m")
# 配置主机名的方法
def set_hostname(username, address,hostname):print("\033[32m" + "{}配置主机名".format(address) + "\033[0m")set_hostname_flag=os.system('ssh {}@{} "hostnamectl set-hostname {}"'.format(username, address,hostname))if set_hostname_flag != 0:print("\033[1;31m" + "Failed: {}配置主机名".format(address) + "\033[0m")sys.exit("请检查!")
for i in range(0, len(master_addresses)):set_hostname(host_username,master_addresses[i],master_domains[i])
for i in range(0, len(client_addresses)):set_hostname(host_username,client_addresses[i],client_domains[i])# 5.配置yum源
# 配置yum源的方法
def config_local_yum(username,address):print("\033[32m" + "{}开始配置本地yum源".format(address) + "\033[0m")os.system("ssh {}@{} 'mkdir -p {} && mount {} {}'".format(username,address,yum_mount_dir,yum_mount_dev,yum_mount_dir))sed_local_yum='echo "{} {} iso9660 defaults  0  0" >> /etc/fstab'.format(yum_mount_dev,yum_mount_dir)os.system("ssh {}@{} '{}'".format(username, address,sed_local_yum))os.system("scp /etc/yum.repos.d/centos-local.repo {}@{}:/etc/yum.repos.d/centos-local.repo".format(username,address))repolist_flag=os.system("ssh {}@{} '{}'".format(username, address, "yum clean all && yum repolist"))if repolist_flag != 0:print("\033[1;31m" + "Failed: {}配置yum源失败".format(address) + "\033[0m")sys.exit("请检查!")
# 配置扩展源的方法
def config_epel_yum(username,address):print("\033[32m" + "{}开始配置扩展源".format(address) + "\033[0m")epel_flag=os.system("ssh {}@{} '{}'".format(username, address, "yum install epel-release -y"))if epel_flag != 0:print("\033[1;31m" + "Failed: {}配置扩展源失败".format(address) + "\033[0m")sys.exit("请检查!")
# 配置远程阿里源的方法
def config_remote_yum(username,address):print("\033[32m" + "{}开始配置远程阿里源".format(address) + "\033[0m")os.system("ssh {}@{} '{}'".format(username, address, "yum install -y wget && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo"))repolist_flag=os.system("ssh {}@{} '{}'".format(username, address, "yum clean all && yum repolist"))if repolist_flag != 0:print("\033[1;31m" + "Failed: {}配置远程阿里源失败".format(address) + "\033[0m")sys.exit("请检查!")with open("/etc/yum.repos.d/centos-local.repo", "w") as f:  # w重写,a添加,只读f.write("[centos7.9]\n")f.write("name=centos7.9\n")f.write("baseurl=file://{}\n".format(yum_mount_dir))f.write("enabled=1\n")f.write("gpgcheck=0\n")for i in range(0, len(master_addresses)):config_local_yum(host_username, master_addresses[i])config_epel_yum(host_username, master_addresses[i])config_remote_yum(host_username, master_addresses[i])
for i in range(0, len(client_addresses)):config_local_yum(host_username, client_addresses[i])config_epel_yum(host_username, client_addresses[i])config_remote_yum(host_username, client_addresses[i])
print("\n")# 6.安装必要工具
def yum_necessary_tools(username,address):print("\033[32m" + "{}开始安装必要工具".format(address) + "\033[0m")yum_tool_flag=os.system("ssh {}@{} '{}'".format(username, address,"yum install -y bash-completion vim net-tools tree psmisc lrzsz dos2unix"))if yum_tool_flag != 0:print("\033[1;31m" + "Failed: {}安装必要工具失败".format(address) + "\033[0m")sys.exit("请检查!")
for i in range(0, len(master_addresses)):yum_necessary_tools(host_username, master_addresses[i])
for i in range(0, len(client_addresses)):yum_necessary_tools(host_username, client_addresses[i])
print("\n")# 7.配置chrony服务器
print("\033[32m" + "开始配置chrony" + "\033[0m")
# 配置chrony主服务器的方法
def chrony_master_service(username,address):print("\033[32m" + "{}配置主chrony".format(address) + "\033[0m")# 安装chronychrony_flag = os.system("ssh {}@{} 'yum install -y chrony'".format(username,address))if chrony_flag != 0:print("\033[1;31m" + "Failed: {}chrony安装失败".format(address) + "\033[0m")sys.exit("请检查!")# 开启同步地址范围chrony_master_allows_addresses = "sed -i 's/#allow 192.168.0.0\/16/allow {}\/24/' /etc/chrony.conf".format(chrony_allows_addresses)os.system('ssh {}@{} "{}"'.format(username, address, chrony_master_allows_addresses))# 开启stratum层数chrony_master_allows_stratum = "sed -i 's/#local stratum 10/local stratum 10/' /etc/chrony.conf"os.system('ssh {}@{} "{}"'.format(username, address, chrony_master_allows_stratum))# 重启服务chrony_service = "systemctl restart chronyd && systemctl enable chronyd &> /dev/null"os.system('ssh {}@{} "{}"'.format(username, address, chrony_service))os.system('ssh {}@{} "sleep 5"'.format(username, address))# 开启时间同步os.system('ssh {}@{} "timedatectl set-ntp true"'.format(username, address))
# 配置chrony同步节点的方法
def chrony_master_client(username,address):print("\033[32m" + "{}配置同步chrony".format(address) + "\033[0m")# 安装chronychrony_flag = os.system("ssh {}@{} 'yum install -y chrony'".format(username,address))if chrony_flag != 0:print("\033[1;31m" + "Failed: {}chrony安装失败".format(address) + "\033[0m")sys.exit("请检查!")# 删除默认的server地址sed_chrony_delete = "sed -i '{}' /etc/chrony.conf".format('/^server/d')os.system('ssh {}@{} "{}"'.format(username,address,sed_chrony_delete))# 添加自定义的server地址for j in range(0, len(master_addresses)):sed_chrony_add = "sed -i '{}' /etc/chrony.conf".format("2a\server {} iburst".format(master_addresses[j]))os.system('ssh {}@{} "{}"'.format(username, address, sed_chrony_add))# 重启服务chrony_service = "systemctl restart chronyd && systemctl enable chronyd &> /dev/null"os.system('ssh {}@{} "{}"'.format(username,address,chrony_service))# 开启时间同步os.system('ssh {}@{} "timedatectl set-ntp true"'.format(username, address))os.system('ssh {}@{} "sleep 5"'.format(username, address))chrony_time = "chronyc sources -v | sed -n '{}'".format("/^\^\*/p")chrony_output = subprocess.check_output('ssh {}@{} "{}"'.format(username,address,chrony_time) ,shell=True)# 输出结果print(chrony_output)if chrony_output == "" or chrony_output is None:print("\033[1;31m" + "Failed: {}时间同步失败".format(address) + "\033[0m")sys.exit("请检查!")for i in range(0, len(master_addresses)):chrony_master_service(host_username,master_addresses[i])
for i in range(0, len(client_addresses)):chrony_master_client(host_username,client_addresses[i])
print("\n")# 8.禁用swap分区,修改linux的内核参数,配置ipvs功能
# 禁用swap分区的方法
def disable_swap(username,address):print("\033[32m" + "{}禁用swap分区".format(address) + "\033[0m")os.system('ssh {}@{} "{}"'.format(username, address,"sed -i 's/\/dev\/mapper\/centos-swap/#\/dev\/mapper\/centos-swap/' /etc/fstab"))# 修改linux的内核参数的方法
def update_linux_kernel(username, address):print("\033[32m" + "{}修改linux的内核参数".format(address) + "\033[0m")os.system("scp /etc/sysctl.d/kubernetes.conf {}@{}:/etc/sysctl.d/kubernetes.conf".format(username,address))os.system('ssh {}@{} "sysctl -p"'.format(username, address))os.system('ssh {}@{} "modprobe br_netfilter"'.format(username, address))os.system('ssh {}@{} "lsmod | grep br_netfilter"'.format(username, address))# 配置ipvs功能的方法
def config_ipvs(username, address):print("\033[32m" + "{}配置ipvs功".format(address) + "\033[0m")os.system('ssh {}@{} "yum install -y ipset ipvsadm"'.format(username, address))os.system("scp /etc/sysconfig/modules/ipvs.modules {}@{}:/etc/sysconfig/modules/ipvs.modules".format(username,address))os.system('ssh {}@{} "chmod +x /etc/sysconfig/modules/ipvs.modules"'.format(username, address))os.system('ssh {}@{} "/bin/bash /etc/sysconfig/modules/ipvs.modules"'.format(username, address))os.system('ssh {}@{} "lsmod | grep -e ip_vs -e nf_conntrack_ipv4"'.format(username, address))with open("/etc/sysctl.d/kubernetes.conf", "w") as f:  # w重写,a添加,只读f.write("net.bridge.bridge-nf-call-ip6tables = 1\n")f.write("net.bridge.bridge-nf-call-iptables = 1\n")f.write("net.ipv4.ip_forward = 1")
with open("/etc/sysconfig/modules/ipvs.modules", "w") as f:  # w重写,a添加,只读f.write("#!/bin/bash\n")f.write("modprobe -- ip_vs\n")f.write("modprobe -- ip_vs_rr\n")f.write("modprobe -- ip_vs_wrr\n")f.write("modprobe -- ip_vs_sh\n")f.write("modprobe -- nf_conntrack_ipv4\n")for i in range(0, len(master_addresses)):disable_swap(host_username,master_addresses[i])update_linux_kernel(host_username, master_addresses[i])config_ipvs(host_username, master_addresses[i])
for i in range(0, len(client_addresses)):disable_swap(host_username,client_addresses[i])update_linux_kernel(host_username, client_addresses[i])config_ipvs(host_username, client_addresses[i])
print("\n")# 9.重启主机并判断可以ssh登陆(如果要执行此内容需python脚本运行在集群之外的节点,不然手动重启)
def is_ssh_host(username,address):print("\033[32m" + "{}开始重启主机".format(address) + "\033[0m")os.system('ssh {}@{} "reboot"'.format(username, address))os.system('sleep 5')for j in range(0,100):connect_time_flag=os.system('ssh {}@{} -o ConnectTimeout=5 "exit"'.format(username, address))os.system('sleep 3')if j == 99:print("\033[1;31m" + "Failed: {}设备连接超时".format(address) + "\033[0m\n")sys.exit("请检查!")if connect_time_flag==0:print("\033[32m" + "{}已可以ssh登陆".format(address) + "\033[0m\n")breakelse:print("\033[32m" + "{}设备正在重启".format(address) + "\033[0m\n")for i in range(0, len(master_addresses)):is_ssh_host(host_username, master_addresses[i])
for i in range(0, len(client_addresses)):is_ssh_host(host_username, client_addresses[i])
print("\n")# 10.安装Docker和k8s组件
# 安装docker的方法
def install_docker(username,address):print("\033[32m" + "{}开始安装Docker".format(address) + "\033[0m")os.system('ssh {}@{} "wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo"'.format(username, address))os.system('ssh {}@{} "yum install -y --setopt=obsoletes=0 docker-ce-18.06.3.ce-3.el7"'.format(username, address))os.system('ssh {}@{} "mkdir -p /etc/docker"'.format(username, address))os.system("scp /etc/docker/daemon.json {}@{}:/etc/docker/daemon.json".format(username,address))os.system("scp /etc/sysconfig/docker {}@{}:/etc/sysconfig/docker".format(username, address))systemctl_docker_flag=os.system('ssh {}@{} "systemctl restart docker && systemctl enable docker"'.format(username, address))if systemctl_docker_flag != 0:print("\033[1;31m" + "Failed: {}docker服务启动失败,请检查".format(address) + "\033[0m")sys.exit("请检查!")
# 安装k8s组件的方法
def install_k8s_module(username,address):print("\033[32m" + "{}开始安装k8s组件r".format(address) + "\033[0m")os.system("scp /etc/yum.repos.d/kubernetes.repo {}@{}:/etc/yum.repos.d/kubernetes.repo".format(username, address))os.system('ssh {}@{} "yum install --setopt=obsoletes=0 kubeadm-1.17.4-0 kubelet-1.17.4-0 kubectl-1.17.4-0 -y"'.format(username, address))os.system("scp /etc/sysconfig/kubelet {}@{}:/etc/sysconfig/kubelet".format(username, address))systemctl_k8s_flag=os.system('ssh {}@{} "systemctl enable kubelet"'.format(username, address))if systemctl_k8s_flag != 0:print("\033[1;31m" + "Failed: {}kubelet服务开机自启设置失败,请检查".format(address) + "\033[0m")sys.exit("请检查!")os.system('mkdir -p /etc/docker')
with open("/etc/docker/daemon.json", "w") as f:  # w重写,a添加,只读f.write("{\n")f.write('"storage-driver": "devicemapper",\n')f.write('"exec-opts": ["native.cgroupdriver=systemd"],\n')f.write('"registry-mirrors": ["https://ja9e22yz.mirror.aliyuncs.com"]\n')f.write("}\n")with open("/etc/sysconfig/docker", "w") as f:  # w重写,a添加,只读f.write("OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false'\n")with open("/etc/yum.repos.d/kubernetes.repo", "w") as f:  # w重写,a添加,只读f.write("[kubernetes]\n")f.write("name=Kubernetes\n")f.write("baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64\n")f.write("enabled=1\n")f.write("gpgcheck=0\n")f.write("repo_gpgcheck=0\n")f.write("gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg\n")
with open("/etc/sysconfig/kubelet", "w") as f:  # w重写,a添加,只读f.write('KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"\n')f.write('KUBE_PROXY_MODE="ipvs"\n')for i in range(0, len(master_addresses)):install_docker(host_username, master_addresses[i])install_k8s_module(host_username, master_addresses[i])
for i in range(0, len(client_addresses)):install_docker(host_username, client_addresses[i])install_k8s_module(host_username, client_addresses[i])# 11.准备集群镜像
def plan_k8s_images(username,address):print("\033[32m" + "{}准备集群镜像".format(address) + "\033[0m")kubeadm_images_output =subprocess.check_output('ssh {}@{} "kubeadm config images list"'.format(username, address),shell=True)kubeadm_images = [line.strip() for line in kubeadm_images_output.split('\n')]kubeadm_images.remove("")for kubeadm_image in kubeadm_images:kubeadm_image=kubeadm_image.split("/")[1]print("\033[1;33;40m" + "正在操作{}相关镜像".format(kubeadm_image) + "\033[0m")  # 黄色字体os.system('ssh {}@{} "docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/{}"'.format(username, address,kubeadm_image))os.system('ssh {}@{} "docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/{} k8s.gcr.io/{}"'.format(username, address,kubeadm_image,kubeadm_image))os.system('ssh {}@{} "docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/{}"'.format(username, address,kubeadm_image))
# 如果后面集群初始化出现镜像缺失问题,请重新拉取镜像
for i in range(0, len(master_addresses)):plan_k8s_images(host_username, master_addresses[i])plan_k8s_images(host_username, master_addresses[i])
for i in range(0, len(client_addresses)):plan_k8s_images(host_username, client_addresses[i])plan_k8s_images(host_username, client_addresses[i])
print("\n")# 12.集群初始化
# 主节点方法
def k8s_init_master(username,address):print("\033[32m" + "{}集群主节点初始化".format(address) + "\033[0m")kubeadm_init_flag=os.system('ssh {}@{} "kubectl cluster - info &> /dev/null"'.format(username, address))if kubeadm_init_flag == 0:kubeadm_output=subprocess.check_output('ssh {}@{} "{}"'.format(username, address, "cat $HOME/kubeadm_init.txt"),shell=True)else:kubeadm_init_command="kubeadm init --kubernetes-version=v1.17.4 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --apiserver-advertise-address={}".format(address)kubeadm_output = subprocess.check_output('ssh {}@{} "{}"'.format(username, address,kubeadm_init_command),shell=True)lines_with_token = re.findall(r'--token.*', kubeadm_output, re.DOTALL)os.system('ssh {}@{} "{}"'.format(username, address, "echo '{}' > $HOME/kubeadm_init.txt".format(kubeadm_output)))token_cert_list = lines_with_token[0].split(' ')print(token_cert_list)kubeadm_codes = []for k in range(0,len(token_cert_list)):if (token_cert_list[k]=="--token" or token_cert_list[k]=="--discovery-token-ca-cert-hash") and k+1<len(token_cert_list):kubeadm_codes.append(token_cert_list[k+1])if len(kubeadm_codes)!=2:print("\033[1;31m" + "Failed: {}节点初始化失败".format(address) + "\033[0m")sys.exit("请检查!")os.system('ssh {}@{} "mkdir -p $HOME/.kube"'.format(username, address))os.system('ssh {}@{} "cp -i /etc/kubernetes/admin.conf $HOME/.kube/config"'.format(username, address))os.system('ssh {}@{} "chown $(id -u):$(id -g) $HOME/.kube/config"'.format(username, address))return kubeadm_codes
# 从节点方法
def k8s_init_node(username, address,master_address,kubeadm_codes):print("\033[32m" + "{}集群从节点初始化".format(address) + "\033[0m")kubeadm_join_command="kubeadm join {}:6443 --token {} \--discovery-token-ca-cert-hash {}".format(master_address,kubeadm_codes[0],kubeadm_codes[1])kubeadm_join_flag=os.system('ssh {}@{} "{}"'.format(username, address,kubeadm_join_command))if kubeadm_join_flag != 0:print("\033[1;31m" + "Failed: {}kubeadm join到{}".format(address,master_address) + "\033[0m")sys.exit("请检查!")for i in range(0, len(master_addresses)):kubeadm_codes=k8s_init_master(host_username, master_addresses[i])for j in range(0, len(client_addresses)):k8s_init_node(host_username, client_addresses[j],master_addresses[i],kubeadm_codes)os.system('ssh {}@{} "kubectl get nodes"'.format(host_username, master_addresses[i]))
print("\n")# 12.安装网络插件
def install_kube_flannel(username, address):print("\033[32m" + "{}安装网络插件".format(address) + "\033[0m")os.system('ssh {}@{} "wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"'.format(username, address))os.system('ssh {}@{} "kubectl apply -f kube-flannel.yml"'.format(username, address))os.system('sleep 90')os.system('ssh {}@{} "kubectl get nodes"'.format(username, address))for i in range(0, len(master_addresses)):install_kube_flannel(host_username, master_addresses[i])
print("\n")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI人工智能与云原生:创新科技的完美结合

人工智能&#xff08;AI&#xff09;是当今科技领域的热门话题&#xff0c;而云原生则是一种新兴的软件开发和部署模式。AI人工智能与云原生的结合&#xff0c;为现代技术创新提供了无限的可能性。本文将探讨AI与云原生的关系&#xff0c;并介绍其如何在实际应用中实现协同效应…

微信小程序如何实现WXML和js文件之间的数据交互

在微信小程序中&#xff0c;WXML负责页面结构的描述&#xff0c;而js文件则负责页面的逻辑处理和数据交互。要实现WXML和js文件之间的数据交互&#xff0c;可以通过以下几种方法&#xff1a; JS传输数据到WXML 数据绑定&#xff1a;在WXML中使用{{}}语法将js文件中的数据绑定…

宏景eHR SQL注入漏洞复现

0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合&#xff0c;满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR app_check_in/get_org_tree.jsp接口处存在SQL注入漏洞&#xff0c;未经过身份认证的远程攻击者可利用此漏洞…

SQL事务管理

事务管理是针对数据库的一组操作。由一条或多条SQL语句组成&#xff0c;这些语句在逻辑上具有强烈的相关性&#xff0c;如果其中一条语句无法执行&#xff0c;那么所有的语句都不会执行。 1 事务管理 原子性 指一个事务必须被视为一个不可分割的最小单元。只有事务中所有的数…

Django、Echarts异步请求、动态更新

前端页面 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>echarts示例</title> <script src"jquery.min.js"></script><script type "text/javascript" src "echarts.m…

什么是PHP的SPL(标准PHP库)?

SPL&#xff08;Standard PHP Library&#xff09;是 PHP 中的标准库&#xff0c;提供了一组用于解决常见问题的接口和类。它包含了一系列的数据结构、算法、迭代器、文件处理、异常处理等组件&#xff0c;使得 PHP 开发者能够更方便地处理各种编程任务。 SPL 提供的主要组件包…

Rancher中使用promtail+loki+grafna收集k8s日志并展示

Rancher中使用promtail+loki+grafna收集k8s日志并展示 根据应用需求和日志数量级别选择对应的日志收集、过滤和展示方式,当日志量不太大,又想简单集中管理查看日志时,可使用promtail+loki+grafna的方式。本文找那个loki和grafana外置在了k8s集群之外。 1、添加Chart Repo …

Pencile - exer

import java.util.HashMap; import java.util.Map;public class TableConverter {public static void main(String[] args) {// 示例输入数据String[] inputData {"line1 col1 A","line2 col3 B","line3 col1 C","line4 col2 D",};//…

云架构的思考4--云上灾备

目录 1 关键指标2 灾备方案3 云上灾备常见模式3.1 “地域”模式3.2 “应用”模式3.3 “数据”模式 4 总结 前几章讲了云上架构、开发等事项&#xff0c;其实灾备也算是架构中的一步&#xff0c;但是这里特意拎出来讲主要有2个原因&#xff0c;其一是因为灾备相对独立且复杂&…

Linux-----5、文件系统

# 文件系统 # 终端的基本操作 ㈠ 打开多个终端 ㈡ 快速清屏 新建标签&#xff1a;command T 新建窗口&#xff1a;command N 关闭标签&#xff1a;command Q 关闭窗口&#xff1a;command W 放大&#xff1a;command 缩小&#xff1a;command - 清屏&#xff…

智慧城市/一网统管建设:人员危险行为检测算法,为城市安全保驾护航

随着人们压力的不断增加&#xff0c;经常会看见在日常生活中由于小摩擦造成的大事故。如何在事故发生时进行及时告警&#xff0c;又如何在事故发生后进行证据搜索与事件溯源&#xff1f;旭帆科技智能视频监控人员危险行为/事件检测算法可以给出答案。 全程监控&#xff0c;有源…

函数节流(js的问题)

函数节流也用到了高阶函数的知识&#xff0c;因为比较重要&#xff0c;所以单开了一个标题。 javascript中的函数在大多数情况下都是由用户主动调用触发的&#xff0c;除非是函数本身的实现不合理。但是在一些少数情况下&#xff0c;函数可能被很频繁的调用&#xff0c;而造成大…

【Linux】多线程编程

目录 1. 线程基础知识 2. 线程创建 3. 线程ID&#xff08;TID&#xff09; 4. 线程终止 5. 线程取消 6. 线程等待 7. 线程分离 8. 线程互斥 8.1 初始化互斥量 8.2 销毁互斥量 8.3 互斥量加锁和解锁 9. 可重入和线程安全 10. 线程同步之条件变量 10.1 初始化条件变…

Qt图像处理-亮度、对比度、灰度、锐化、负片的实现

本文演示Qt中图像的亮度、对比度、灰度、锐化、负片处理实现 一、概述 亮度和对比度原理 图像亮度通俗理解便是图像的明暗程度,数字图像 f(x,y) = i(x,y) r(x, y) ,如果灰度值在[0,255]之间,则 f 值越接近0亮度越低,f 值越接近255亮度越高。而且我们也要把亮度和对比…

Maven下载及安装自用版

Maven下载及安装自用版 可能是Maven用久了。感觉Maven用起来还算顺手&#xff0c;比Gradle要好上手一些。 一、下载 Maven 下载地址 注意下载版本和依赖要求&#xff0c;下载后&#xff0c;解压放在指定的位置;注意安装地址&#xff0c;放在自己规划好的开发环境专用文件夹里…

ubuntu创建apt-mirror本地仓库

首先创建apt-mirror的服务端&#xff0c;也就是存储所有apt-get下载的文件和依赖。大约需要300G&#xff0c;预留400G左右空间就可以开始了。 安装ubuntu省略&#xff0c;用的是ubuntu202204 ubuntu挂载硬盘&#xff08;不需要的可以跳过&#xff09;: #下载挂载工具 sudo apt…

C++类与对象(一)

目录 一&#xff0c;面向过程和面向对象初步认识 二&#xff0c;类的引入 三&#xff0c;类的定义 四&#xff0c;类的访问限定符及封装 五&#xff0c;类的实例化 六&#xff0c;类对象模型 七&#xff0c;this指针 一&#xff0c;面向过程和面向对象初步认识 c语言是面…

使用动画曲线编辑器打造炫酷的3D可视化ACE

前言 在制作3D可视化看板时&#xff0c;除了精细的模型结构外&#xff0c;炫酷的动画效果也是必不可少的。无论是复杂的还是简单的动画效果&#xff0c;要实现100%的自然平滑都是具有挑战性的工作。这涉及到物理引擎的计算和对动画效果的数学建模分析。一般来说&#xff0c;只…

HPM6750系列--第七篇 Visual Studio Code使用openocd调试查看外设信息

一、目的 在《HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境》我们已经手把手指导大家如何在visual studio code中进行开发&#xff0c;包括编译调试等步骤以及相关配置文件。 但是在实际调试时发现找不到芯片寄存器实时显示的窗口&#xff0c;本篇主要讲解如何实现…

天翼云盘秒变硬盘分享

https://cloud.189.cn/web/share?codeAvUnqaj6NNza&#xff08;访问码&#xff1a;wf4r&#xff09;y 以下介绍为作者开发的单机版软件&#xff0c;可用于Windows环境中将天翼云盘挂载为本地硬盘&#xff0c;确实可以达到本地硬盘的使用感知&#xff0c;对于多终端数据副本一…