油猴 1688列表自动爬取数据此代码为油猴脚本，用于1688商品搜索列表和店铺商品列表爬取自动数据，请在商品两处地方补充自己的代码，将商品信息上传到自己的数据库。代码原理是，hook 1688的xhr请求，请求中途拦截响应，取出请求内容处理。但是有些请求是通过JSONP的方式，就是通过script标签动态插入body，从而让浏览器加载，所以同样监听了script加载内容回调，符合的响应内容则返回。对于商品详情的数据，则通过iframe，父页面开启监听，子页面进行推送。// ==UserScript== // @name 1688列表自动爬取数据 // @namespace http://tampermonkey.net/ // @version 0.2 // @description 1688列表自动爬取数据 // @author 我亏一点 // @match *.1688.com/page/offerlist.htm* // @match *.1688.com/offer/*.html* // @match *.1688.com/selloffer/offer_search.htm* // @icon https://s1.ax1x.com/2022/10/14/xwsJYT.png // @grant none // ==/UserScript== (function () { "use strict"; const config = { lock: false, //是否自动爬取 true为是，false为否 run_status: false, //是否正在拦截爬取 sleep: 5, // 爬取间隔 (秒) iframe_timeout: 3600, // 最大等待时间（秒），防止卡死 debug: false, // 是否开启测试，开启只会爬一个数据 data: [], //数据集 is_iframe: window.self !== window.top, type: "", // 页面类型 shop_list为店铺商品列表，goods_list为搜索商品列表，detail为商品详情 type_match: { shop_list: "mtop.alibaba.alisite.cbu.server.moduleasyncservice", // 店铺商品列表 goods_list: "mtop.relationrecommend.wirelessrecommend.recommend", // 搜索商品列表 }, }; //================创建面板开始==================== // 创建一个 div 元素用于显示日志 const logDiv = document.createElement("div"); logDiv.id = "log-div-1688"; logDiv.style.position = "fixed"; logDiv.style.bottom = "10px"; logDiv.style.left = "10px"; logDiv.style.width = "400px"; logDiv.style.height = "300px"; logDiv.style.overflowY = "auto"; logDiv.style.border = "10px solid black"; logDiv.style.backgroundColor = "white"; logDiv.style.zIndex = 9999; logDiv.style.padding = "20px"; logDiv.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.1)"; logDiv.style.wordWrap = "break-word"; logDiv.style.overflowWrap = "break-word"; logDiv.style.fontFamily = "monospace"; logDiv.style.fontSize = "12px"; // 日志容器 - 使用单独的容器存放日志条目 const logContainer = document.createElement("div"); logContainer.id = "log-container-1688"; logContainer.style.maxHeight = "240px"; logContainer.style.overflowY = "auto"; logDiv.appendChild(logContainer); // 日志头部 const logHeader = document.createElement("p"); logHeader.style.color = "green"; logHeader.style.fontWeight = "bold"; logHeader.style.margin = "0 0 10px 0"; logHeader.textContent = "插件初始化——我亏一点"; logDiv.insertBefore(logHeader, logContainer); document.body.appendChild(logDiv); // 日志配置 const logConfig = { maxLines: 200, // 最大日志行数 batchUpdate: true, // 批量更新 autoScroll: true, // 自动滚动 }; // 日志缓冲队列 let logBuffer = []; let logUpdateTimer = null; let pendingScroll = false; // 标记是否需要滚动 // 优化后的日志添加函数 function addLog(html_code, lock = true) { logBuffer.push(html_code); // 标记需要滚动 if (lock && logConfig.autoScroll) { pendingScroll = true; } // 批量更新，避免频繁 DOM 操作 if (!logUpdateTimer) { logUpdateTimer = setTimeout(flushLogBuffer, 50); } } // 刷新日志缓冲 function flushLogBuffer() { if (logBuffer.length === 0) { logUpdateTimer = null; return; } // 使用 DocumentFragment 批量插入 const fragment = document.createDocumentFragment(); logBuffer.forEach((html) => { const p = document.createElement("p"); p.innerHTML = html; p.style.margin = "2px 0"; fragment.appendChild(p); }); logContainer.appendChild(fragment); // 限制日志行数，自动清理旧日志 while (logContainer.children.length > logConfig.maxLines) { logContainer.removeChild(logContainer.firstChild); } logBuffer = []; logUpdateTimer = null; // DOM 更新后执行滚动 if (pendingScroll) { pendingScroll = false; scrollToBottom(); } } // 滚动到底部函数 function scrollToBottom() { requestAnimationFrame(() => { setTimeout(() => { logContainer.scrollTop = logContainer.scrollHeight; }, 10); }); } // 清空日志功能 function clearLog() { logContainer.innerHTML = ""; logBuffer = []; pendingScroll = false; } // 添加清空按钮到日志头部 const clearBtn = document.createElement("button"); clearBtn.textContent = "清空日志"; clearBtn.style.marginLeft = "10px"; clearBtn.style.fontSize = "10px"; clearBtn.style.cursor = "pointer"; clearBtn.onclick = clearLog; logHeader.appendChild(clearBtn); // 拖动相关变量 let isDragging = false; let currentX; let currentY; let initialX; let initialY; let xOffset = 0; let yOffset = 0; logDiv.addEventListener("mousedown", dragStart); document.addEventListener("mousemove", drag); document.addEventListener("mouseup", dragEnd); function dragStart(e) { if (e.target.tagName === "BUTTON" || e.target.id === "start_run_button") { return; } initialX = e.clientX - xOffset; initialY = e.clientY - yOffset; if (e.target === logDiv) { isDragging = true; logDiv.style.cursor = "grabbing"; } } function drag(e) { if (isDragging) { e.preventDefault(); currentX = e.clientX - initialX; currentY = e.clientY - initialY; xOffset = currentX; yOffset = currentY; setTranslate(currentX, currentY, logDiv); } } function dragEnd(e) { initialX = currentX; initialY = currentY; isDragging = false; logDiv.style.cursor = "grab"; } function setTranslate(xPos, yPos, el) { el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`; } //================创建面板结束==================== //================页面检测开始================== // 如果跳转登录，提示请登录 if (window.location.href.includes("login.taobao.com")) { addLog(" 请自行登录账号 "); return; } // 如果在商品详情页面 if (window.location.href.includes("detail.1688.com/offer")) { config.type = "detail"; addLog(" 已进入商品详情页面 "); const item_detail = window.context.result.global.globalData.model; addLog( ` 商品编号：${item_detail.offerDetail.offerId} `, ); addLog( ` 商品名称：${item_detail.offerDetail.subject} `, ); addLog( ` 商品价格：${item_detail.tradeModel.priceDisplay} `, ); addLog( ` 商品首图：${item_detail.offerDetail.mainImageList[0].fullPathImageURI} `, ); if (config.is_iframe) { addLog(` 检测到子页面，自动推送数据 `); window.parent.postMessage( { type: "item_detail", data: item_detail, }, "*", ); } return; } // 如果在店铺商品列表或者搜索商品列表页面 else if ( window.location.href.includes("1688.com/page/offerlist.htm") || window.location.href.includes("1688.com/selloffer/offer_search.htm") ) { // 如果是店铺商品列表页面 if (window.location.href.includes("1688.com/page/offerlist.htm")) { config.type = "shop_list"; addLog(" 已进入店铺商品列表页面 "); } // 如果是搜索商品列表页面 if (window.location.href.includes("1688.com/selloffer/offer_search.htm")) { config.type = "goods_list"; addLog(" 已进入搜索商品列表页面 "); } // 如果不在子页面，则监听消息 if (!config.is_iframe) { addLog(" 自动监听消息 "); window.addEventListener("message", function (e) { if (e.data.type === "item_detail") { const item_detail = e.data.data; addLog( ` 商品编号：${item_detail.offerDetail.offerId} `, ); addLog( ` 商品名称：${item_detail.offerDetail.subject} `, ); addLog( ` 商品价格：${item_detail.tradeModel.priceDisplay} `, ); addLog( ` 商品首图：${item_detail.offerDetail.mainImageList[0].fullPathImageURI} `, ); if (typeof currentItemResolver === "function") { currentItemResolver(item_detail); } // 可以在这里写把数据保存到数据库的逻辑 } }); } // 如果配置锁开启，则自动开始爬取 if (config.lock) { addLog( " 自动爬取：" + (config.lock ? "启动" : "关闭") + " ", ); window.onload = () => { run(); }; } else { // 否则添加开始按钮 const startBtn = document.createElement("button"); startBtn.textContent = "开始爬取"; startBtn.style.marginLeft = "10px"; startBtn.style.fontSize = "10px"; startBtn.style.cursor = "pointer"; startBtn.onclick = run; logHeader.appendChild(startBtn); } } // 如果不是商品列表页面，则提示请进入商品列表页面 else { addLog(" 请进入商品列表页面 "); return; } //================页面检测结束================== //================拦截请求开始================== // hook请求方法 const originalOpen = XMLHttpRequest.prototype.open; const originalSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function () { originalOpen.apply(this, arguments); this.addEventListener("load", function () { switch (config.type) { case "shop_list": if ( this.responseURL .toLocaleLowerCase() .includes(config.type_match.shop_list.toLocaleLowerCase()) && config.run_status ) { try { const list = JSON.parse(this.responseText).data.content.offerList; if (list) { const pageNum = document.querySelector( 'div[style*="background: rgb(255, 64, 0)"]', )?.textContent || "未知"; addLog(" 开始爬取第 " + pageNum + " 页 "); processAllItemsSequentially(list).then(() => { setTimeout(() => { if ( document.querySelectorAll("button")[1] && !config.debug ) { document.querySelectorAll("button")[1].click(); } }, config.sleep * 1000); }); } } catch (e) { addLog(" 列表数据解析失败 "); } } break; default: break; } }); }; XMLHttpRequest.prototype.send = function () { originalSend.apply(this, arguments); }; //================拦截请求结束================== //================拦截jsonp请求开始================== // 保存原生 src 的 setter const srcDescriptor = Object.getOwnPropertyDescriptor( HTMLScriptElement.prototype, "src", ); const originalSrcSetter = srcDescriptor.set; // 重写 src setter，拦截所有 script.src 赋值 Object.defineProperty(HTMLScriptElement.prototype, "src", { // 重写 setter set(url) { // 如果不是 1688/淘宝的 mtop JSONP，直接走原生逻辑 if (typeof url !== "string" || !isMtopJsonpUrl(url)) { return originalSrcSetter.call(this, url); } // 从 URL 中取出 callback 参数 const callbackName = extractCallbackName(url); if (!callbackName) { return originalSrcSetter.call(this, url); } // 在真正设置 src 之前，先 hook 这个全局回调函数 hookMtopJsonpCallback(callbackName, url); // 再让浏览器正常去加载这个 script return originalSrcSetter.call(this, url); }, get() { return srcDescriptor.get.call(this); }, configurable: true, }); // 判断是否是 1688/淘宝 mtop JSONP 请求 function isMtopJsonpUrl(url) { if (!url) return false; const lower = url.toLowerCase(); return ( (lower.includes("h5api.m.1688.com/h5/mtop.") || lower.includes("h5api.m.taobao.com/h5/mtop.")) && /[?&]callback=mtopjsonp/i.test(url) ); } // 从 URL 中解析 callback 参数名 function extractCallbackName(url) { try { const search = url.split("?")[1]; if (!search) return null; const params = new URLSearchParams(search); const callback = params.get("callback"); return callback || null; } catch (e) { return null; } } /** * 动态替换全局 JSONP 回调函数 * @param {string} callbackName - 如 mtopjsonp5 * @param {string} url - 原始 JSONP URL（用于日志、匹配接口） */ function hookMtopJsonpCallback(callbackName, url) { const win = window; // 如果回调已经是函数，则直接劫持覆盖 if (typeof win[callbackName] === "function") { // 如果已经被 hook 过，就不重复，防止同页面请求爬取多次 if (win["__" + callbackName + "__hooked__"]) return; win["__" + callbackName + "__hooked__"] = true; const raw = win[callbackName]; win[callbackName] = function (data) { handleMtopJsonResponse(url, data); return raw.apply(this, arguments); }; return; } // 如果没有回调函数，则劫持函数赋值，等待赋值再进行劫持 Object.defineProperty(win, callbackName, { configurable: true, // 允许后续重新定义 enumerable: true, get: function () { // 返回 undefined 或者你缓存的函数，通常不影响逻辑 return win["__proxy_" + callbackName]; }, set: function (realCallback) { // 此时页面正在把真正的回调函数赋值给这个变量 // 我们把这个属性"篡改"成我们的函数，并保存真正的回调 Object.defineProperty(win, callbackName, { value: function (data) { // console.log("[JSONP HOOK] 拿到数据:", data); // 拦截数据处理 handleMtopJsonResponse(url, data); // 继续运行原函数 if (typeof realCallback === "function") { return realCallback.apply(this, arguments); } }, writable: true, // 允许被删除或修改 configurable: true, // 允许被删除 enumerable: true, }); }, }); } /** * 根据接口类型分发处理 * @param {string} url * @param {any} data */ function handleMtopJsonResponse(url, data) { const lowerUrl = url.toLowerCase(); if ( lowerUrl.includes("mtop.relationrecommend.wirelessrecommend.recommend") ) { handleGoodsListJsonp(data); } } /** * 处理搜索列表 goods_list 的 JSONP 数据 * @param {any} data */ function handleGoodsListJsonp(data) { if (!config.run_status) return; try { const list = data && data.data && data.data.data && data.data.data.OFFER && data.data.data.OFFER.items; if (!list) { addLog(" JSONP 列表数据格式异常 "); return; } const pageNum = document.querySelector(".fui-current")?.textContent || "未知"; addLog(" 开始爬取第 " + pageNum + " 页（JSONP） "); processAllItemsSequentially(list).then(() => { setTimeout(() => { if (document.querySelector(".fui-next") && !config.debug) { document.querySelector(".fui-next").click(); } }, config.sleep * 1000); }); } catch (e) { console.error(e); addLog(" JSONP 列表数据解析失败 "); } } //================拦截jsonp请求结束================== //=================处理商品详情开始================== // 用于在拦截器和处理函数之间通信 let currentItemResolver = null; function run() { if (config.run_status) { addLog(" 已开始自动爬取 "); return; } config.run_status = true; addLog(" 开始自动爬取 "); let firstPageBtn = null; if (config.type === "goods_list") { firstPageBtn = document.querySelector(".fui-current"); } if (config.type === "shop_list") { firstPageBtn = document.querySelector( 'div[style*="background: rgb(255, 64, 0)"]', ); } if (firstPageBtn) { firstPageBtn.click(); } else { addLog(" 未找到分页按钮，请确保在商品列表页 "); } } async function processItemDetail(item) { return new Promise((resolve) => { addLog(` 开始处理商品: ${item.subject} `); const iframe = document.createElement("iframe"); iframe.style.width = "800px"; iframe.style.height = "600px"; iframe.style.border = "1px solid #ccc"; iframe.style.position = "fixed"; iframe.style.top = "0"; iframe.style.right = "0"; iframe.style.zIndex = "9999"; iframe.src = `https://detail.1688.com/offer/${item.id}.html`; // 定义清理和关闭的逻辑 const cleanup = (data = null) => { if (iframe.parentNode) { document.body.removeChild(iframe); addLog( ` 商品: ${item.subject} 处理完成${data ? " (数据已保存)" : " (超时或失败)"} `, ); } resolve(); }; // 将 resolver 暴露给全局拦截器 currentItemResolver = cleanup; // 设置一个最大超时时间，防止某些商品加载不出数据导致脚本卡死 const timeoutId = setTimeout(() => { if (currentItemResolver === cleanup) { addLog( ` 商品: ${item.subject} 捕获超时，自动跳过 `, ); currentItemResolver = null; cleanup(); } }, config.iframe_timeout * 1000); iframe.onload = function () {}; iframe.onerror = function () { addLog( ` 商品: ${item.subject} iframe加载失败 `, ); clearTimeout(timeoutId); cleanup(); }; document.body.appendChild(iframe); }); } async function processAllItemsSequentially(list) { for (const item of list) { if (config.type == "goods_list") { item.subject = item.data.title; item.id = item.data.offerId; } if (item && item.id) { // 可以对接数据库校验是否已存在 await processItemDetail(item); if (config.debug) { break; } // 休眠 addLog(` 等待${config.sleep}秒 `); await new Promise((r) => setTimeout(r, config.sleep * 1000)); } } addLog(" 本页处理完成 "); } //=================处理商品详情结束================== })(); 需补充的两处地方，请搜索 数据库位置1 自动入库 // 如果不在子页面，则监听消息 if (!config.is_iframe) { addLog(" 自动监听消息 "); window.addEventListener("message", function (e) { if (e.data.type === "item_detail") { const item_detail = e.data.data; addLog( ` 商品编号：${item_detail.offerDetail.offerId} `, ); addLog( ` 商品名称：${item_detail.offerDetail.subject} `, ); addLog( ` 商品价格：${item_detail.tradeModel.priceDisplay} `, ); addLog( ` 商品首图：${item_detail.offerDetail.mainImageList[0].fullPathImageURI} `, ); if (typeof currentItemResolver === "function") { currentItemResolver(item_detail); } // 可以在这里写把数据保存到数据库的逻辑 } }); }位置2 校验数据库是否存在 async function processAllItemsSequentially(list) { for (const item of list) { if (config.type == "goods_list") { item.subject = item.data.title; item.id = item.data.offerId; } if (item && item.id) { // 可以对接数据库校验是否已存在 await processItemDetail(item); if (config.debug) { break; } // 休眠 addLog(` 等待${config.sleep}秒 `); await new Promise((r) => setTimeout(r, config.sleep * 1000)); } } addLog(" 本页处理完成 "); }
苹果cms10 列表和搜索过滤会员组没有权限的数据
苹果cms10 列表和搜索过滤会员组没有权限的数据苹果cms10的列表中，会出现会员组没有权限的数据，只有点进去才会提示登录。1.新版本后台-》网站基础参数-》性能优化-》数据权限过滤开启即可2.老版本编辑文件application/common/model/Vod.php找到listData方法，增加过滤方法public function listData($where,$order,$page=1,$limit=20,$start=0,$field='*',$addition=1,$totalshow=1) { $page = $page > 0 ? (int)$page : 1; $limit = $limit ? (int)$limit : 20; $start = $start ? (int)$start : 0; if(!is_array($where)){ $where = json_decode($where,true); } $where2=''; if(!empty($where['_string'])){ $where2 = $where['_string']; unset($where['_string']); } // =====修改开始===== // 增加会员组过滤方法 $where3 = []; // 如果是用户请求 if(isset($GLOBALS['user'])){ $category_ids = array_filter(explode(',',$GLOBALS['user']['group']['group_type'])); $where3['type_id'] = ['in',$category_ids]; } $limit_str = ($limit * ($page-1) + $start) .",".$limit; if($totalshow==1) { // 增加where3查询 $total = $this->where($where)->where($where2)->where($where3)->count(); } // 增加where3查询 $list = Db::name('Vod')->field($field)->where($where)->where($where2)->where($where3)->order($order)->limit($limit_str)->select(); // =====修改结束===== //分类 $type_list = model('Type')->getCache('type_list'); //用户组 $group_list = model('Group')->getCache('group_list'); foreach($list as $k=>$v){ if($addition==1){ if(!empty($v['type_id'])) { $list[$k]['type'] = $type_list[$v['type_id']]; $list[$k]['type_1'] = $type_list[$list[$k]['type']['type_pid']]; } if(!empty($v['group_id'])) { $list[$k]['group'] = $group_list[$v['group_id']]; } } } return ['code'=>1,'msg'=>lang('data_list'),'page'=>$page,'pagecount'=>ceil($total/$limit),'limit'=>$limit,'total'=>$total,'list'=>$list]; }
PHP多级分类数据列表转为树型父子结构
PHP多级分类数据列表转为树型父子结构function formatToTree($array, $pid = 0, $pidName = 'parent_id') { return array_values(array_map(function ($item) use ($array, $pid) { $item['children'] = formatToTree($array, $item['id']); return $item; },array_filter($array,function ($item) use ($pidName,$pid) { return $item[$pidName] === $pid; }))); }$array为mysql查询出来的列表数据$pid为最上级父节点id$pidName为父id字段
代码（仅适用亿位以下）：function numToChinese(num) { const CN_NUM = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; const CN_UNIT = ['', '十', '百', '千', '万', '十', '百', '千', '亿']; let numStr = String(num); let len = numStr.length; let result = ''; if (len === 0) { return '零'; } for (let i = 0; i < len; i++) { let n = numStr.charAt(i); let unitIndex = len - i - 1; let numIndex = parseInt(n); let preUnit = CN_UNIT[unitIndex]; let preNum = CN_NUM[numIndex]; let replaceNum = preNum ? preNum : ''; if (unitIndex > 0 && numIndex === 0) { replaceNum = ''; } else if (numIndex > 0) { replaceNum = preNum; } result += replaceNum + preUnit; } result = result.replace(/零(千|百|十|)/g, '零$1'); let matchs = (result.match(/([亿|万|千|百|十]{2,})/g))||[] for (const iterator of matchs) { result = result.replace(iterator,iterator.slice(0,1) + "零") } result = result.replace("一十","十") return result.endsWith("零") ? result.slice(0,-1) : result; } console.log(numToChinese(12));结果：十二
Centos7系统的笔记本，启动摄像头1. 确认摄像头已正确安装。在终端中运行以下命令，检查摄像头是否被正确识别：dmesg | grep -i webcam如果摄像头被正确识别，你应该能在输出中看到相关的信息。2. 检查摄像头是否已经启动。在终端中运行以下命令，启动摄像头：modprobe -r uvcvideo modprobe uvcvideo
mysql5.7 sql语句实现父子查询1.数据表创建SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS `goods_metas`; CREATE TABLE `goods_metas` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号', `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名', `type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类型', `count` int(11) NULL DEFAULT 0 COMMENT '统计', `parent` int(11) NULL DEFAULT 0 COMMENT '父编号（只有class需要）', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `name`(`name`, `type`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; INSERT INTO `goods_metas` VALUES (1, '美甲', 'class', 0, 0); INSERT INTO `goods_metas` VALUES (2, '长甲', 'class', 0, 1); INSERT INTO `goods_metas` VALUES (3, '短甲', 'class', 0, 1); INSERT INTO `goods_metas` VALUES (4, '可爱', 'tag', 0, 0); INSERT INTO `goods_metas` VALUES (5, '简约', 'tag', 0, 0); INSERT INTO `goods_metas` VALUES (6, '测试', 'class', 0, 2); SET FOREIGN_KEY_CHECKS = 1;2.根据父id查所有子节点将{id}修改为查询的父id不包含父节点自身select * from goods_metas where id in (SELECT id FROM (SELECT * FROM goods_metas where type="class") goods_metas, (SELECT @pid := '{id}') pd WHERE FIND_IN_SET(parent, @pid) > 0 AND @pid := concat(@pid, ',', id));id=0查询结果+----+----------+-------+-------+--------+ | id | name | type | count | parent | +----+----------+-------+-------+--------+ | 2 | 长甲 | class | 0 | 1 | | 3 | 短甲 | class | 0 | 1 | | 6 | 测试 | class | 0 | 2 | +----+----------+-------+-------+--------+
Kubernetes使用kubeeasy部署集群1.环境准备主机信息（一定要双网卡）主机名NAT网卡本地网卡节点状态master10.107.24.80192.168.50.80masternode10.107.24.81192.168.50.81worker准备文件chinaskills_cloud_paas_v2.0.2.iso[root@master ~]# mount -o loop /dev/cdrom /mnt/ [root@master ~]# cp -rf /mnt/* /opt/ [root@master ~]# umount /mnt/ [root@master ~]# ls /opt/ centos extended-images helm-v3.7.1-linux-amd64.tar.gz kubeeasy kubevirt.tar.gz dependencies harbor-offline.tar.gz istio.tar.gz kubernetes.tar.gz2.离线安装步骤2.1 安装kubeeasy[root@master ~]# cp -rf /opt/kubeeasy /usr/bin/ [root@master ~]# chmod +x /usr/bin/kubeeasy2.2 安装集群依赖包[root@master ~]# kubeeasy install dependencies \ --host 10.107.24.80,10.107.24.81 \ --user root \ --password 000000 \ --offline-file /opt/dependencies/base-rpms.tar.gz[2023-03-20 01:20:52] INFO: [start] bash kubeeasy install dependencies --host 10.107.24.80,10.107.24.81 --user root --password ****** --offline-file /opt/dependencies/base-rpms.tar.gz [2023-03-20 01:20:52] INFO: [offline] unzip offline dependencies package on local. [2023-03-20 01:20:54] INFO: [offline] unzip offline dependencies package succeeded. [2023-03-20 01:20:54] INFO: [install] install dependencies packages on local. [2023-03-20 01:22:36] INFO: [install] install dependencies packages succeeded. [2023-03-20 01:22:37] INFO: [offline] 10.107.24.80: load offline dependencies file [2023-03-20 01:22:39] INFO: [offline] load offline dependencies file to 10.107.24.80 succeeded. [2023-03-20 01:22:39] INFO: [install] 10.107.24.80: install dependencies packages [2023-03-20 01:22:40] INFO: [install] 10.107.24.80: install dependencies packages succeeded. [2023-03-20 01:22:41] INFO: [offline] 10.107.24.81: load offline dependencies file [2023-03-20 01:22:46] INFO: [offline] load offline dependencies file to 10.107.24.81 succeeded. [2023-03-20 01:22:46] INFO: [install] 10.107.24.81: install dependencies packages [2023-03-20 01:24:26] INFO: [install] 10.107.24.81: install dependencies packages succeeded. See detailed log >> /var/log/kubeinstall.log 2.3 安装Kubernetes集群[root@master ~]# kubeeasy install kubernetes \ --master 10.107.24.80 \ --worker 10.107.24.81 \ --user root \ --password 000000 \ --version 1.22.1 \ --offline-file /opt/kubernetes.tar.gz[2023-03-20 01:24:58] INFO: [start] bash kubeeasy install kubernetes --master 10.107.24.80 --worker 10.107.24.81 --user root --password ****** --version 1.22.1 --offline-file /opt/kubernetes.tar.gz [2023-03-20 01:24:58] INFO: [check] sshpass command exists. [2023-03-20 01:24:58] INFO: [check] rsync command exists. [2023-03-20 01:24:59] INFO: [check] ssh 10.107.24.80 connection succeeded. [2023-03-20 01:24:59] INFO: [check] ssh 10.107.24.81 connection succeeded. [2023-03-20 01:24:59] INFO: [offline] unzip offline package on local. [2023-03-20 01:25:09] INFO: [offline] unzip offline package succeeded. [2023-03-20 01:25:09] INFO: [offline] master 10.107.24.80: load offline file [2023-03-20 01:25:10] INFO: [offline] load offline file to 10.107.24.80 succeeded. [2023-03-20 01:25:10] INFO: [offline] master 10.107.24.80: disable the firewall [2023-03-20 01:25:11] INFO: [offline] 10.107.24.80: disable the firewall succeeded. [2023-03-20 01:25:11] INFO: [offline] worker 10.107.24.81: load offline file [2023-03-20 01:26:05] INFO: [offline] load offline file to 10.107.24.81 succeeded. [2023-03-20 01:26:05] INFO: [offline] worker 10.107.24.81: disable the firewall [2023-03-20 01:26:06] INFO: [offline] 10.107.24.81: disable the firewall succeeded. [2023-03-20 01:26:06] INFO: [get] Get 10.107.24.80 InternalIP. [2023-03-20 01:26:07] INFO: [result] get MGMT_NODE_IP value succeeded. [2023-03-20 01:26:07] INFO: [result] MGMT_NODE_IP is 10.107.24.80 [2023-03-20 01:26:07] INFO: [init] master: 10.107.24.80 [2023-03-20 13:26:09] INFO: [init] init master 10.107.24.80 succeeded. [2023-03-20 13:26:09] INFO: [init] master: 10.107.24.80 set hostname and hosts [2023-03-20 13:26:09] INFO: [init] 10.107.24.80 set hostname and hosts succeeded. [2023-03-20 13:26:09] INFO: [init] worker: 10.107.24.81 [2023-03-20 13:26:12] INFO: [init] init worker 10.107.24.81 succeeded. [2023-03-20 13:26:12] INFO: [init] master: 10.107.24.81 set hostname and hosts [2023-03-20 13:26:12] INFO: [init] 10.107.24.81 set hostname and hosts succeeded. [2023-03-20 13:26:12] INFO: [install] install docker on 10.107.24.80. [2023-03-20 13:27:59] INFO: [install] install docker on 10.107.24.80 succeeded. [2023-03-20 13:27:59] INFO: [install] install kube on 10.107.24.80 [2023-03-20 13:28:01] INFO: [install] install kube on 10.107.24.80 succeeded. [2023-03-20 13:28:01] INFO: [install] install docker on 10.107.24.81. [2023-03-20 13:29:45] INFO: [install] install docker on 10.107.24.81 succeeded. [2023-03-20 13:29:45] INFO: [install] install kube on 10.107.24.81 [2023-03-20 13:29:47] INFO: [install] install kube on 10.107.24.81 succeeded. [2023-03-20 13:29:47] INFO: [kubeadm init] kubeadm init on 10.107.24.80 [2023-03-20 13:29:47] INFO: [kubeadm init] 10.107.24.80: set kubeadm-config.yaml [2023-03-20 13:29:48] INFO: [kubeadm init] 10.107.24.80: set kubeadm-config.yaml succeeded. [2023-03-20 13:29:48] INFO: [kubeadm init] 10.107.24.80: kubeadm init start. [2023-03-20 13:30:03] INFO: [kubeadm init] 10.107.24.80: kubeadm init succeeded. [2023-03-20 13:30:06] INFO: [kubeadm init] 10.107.24.80: set kube config. [2023-03-20 13:30:06] INFO: [kubeadm init] 10.107.24.80: set kube config succeeded. [2023-03-20 13:30:06] INFO: [kubeadm init] 10.107.24.80: delete master taint [2023-03-20 13:30:07] INFO: [kubeadm init] 10.107.24.80: delete master taint succeeded. [2023-03-20 13:30:07] INFO: [kubeadm init] Auto-Approve kubelet cert csr succeeded. [2023-03-20 13:30:07] INFO: [kubeadm join] master: get join token and cert info [2023-03-20 13:30:08] INFO: [result] get CACRT_HASH value succeeded. [2023-03-20 13:30:08] INFO: [result] get INTI_CERTKEY value succeeded. [2023-03-20 13:30:09] INFO: [result] get INIT_TOKEN value succeeded. [2023-03-20 13:30:09] INFO: [kubeadm join] worker 10.107.24.81 join cluster. [2023-03-20 13:30:28] INFO: [kubeadm join] worker 10.107.24.81 join cluster succeeded. [2023-03-20 13:30:28] INFO: [kubeadm join] set 10.107.24.81 worker node role. [2023-03-20 13:30:29] INFO: [kubeadm join] set 10.107.24.81 worker node role succeeded. [2023-03-20 13:30:29] INFO: [network] add flannel network [2023-03-20 13:30:29] INFO: [calico] change flannel pod subnet succeeded. [2023-03-20 13:30:29] INFO: [apply] apply kube-flannel.yaml file [2023-03-20 13:30:30] INFO: [apply] apply kube-flannel.yaml file succeeded. [2023-03-20 13:30:33] INFO: [waiting] waiting kube-flannel-ds [2023-03-20 13:30:34] INFO: [waiting] kube-flannel-ds pods ready succeeded. [2023-03-20 13:30:34] INFO: [apply] apply coredns-cm.yaml file [2023-03-20 13:30:34] INFO: [apply] apply coredns-cm.yaml file succeeded. [2023-03-20 13:30:35] INFO: [apply] apply metrics-server.yaml file [2023-03-20 13:30:35] INFO: [apply] apply metrics-server.yaml file succeeded. [2023-03-20 13:30:38] INFO: [waiting] waiting metrics-server [2023-03-20 13:30:39] INFO: [waiting] metrics-server pods ready succeeded. [2023-03-20 13:30:39] INFO: [apply] apply dashboard.yaml file [2023-03-20 13:30:39] INFO: [apply] apply dashboard.yaml file succeeded. [2023-03-20 13:30:42] INFO: [waiting] waiting dashboard-agent [2023-03-20 13:30:43] INFO: [waiting] dashboard-agent pods ready succeeded. [2023-03-20 13:30:46] INFO: [waiting] waiting dashboard-en [2023-03-20 13:30:46] INFO: [waiting] dashboard-en pods ready succeeded. [2023-03-20 13:31:01] INFO: [cluster] kubernetes cluster status + kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME k8s-master-node1 Ready control-plane,master,worker 61s v1.22.1 10.107.24.80 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.8 k8s-worker-node1 Ready worker 37s v1.22.1 10.107.24.81 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.8 + kubectl get pods -A -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES dashboard-cn dashboard-agent-cd88cf454-q48b4 1/1 Running 0 22s 10.244.1.2 k8s-worker-node1 <none> <none> dashboard-cn dashboard-cn-64bd46887f-jvm4t 1/1 Running 0 22s 10.244.1.3 k8s-worker-node1 <none> <none> dashboard-en dashboard-en-55596d469-lrnp9 1/1 Running 0 22s 10.244.1.4 k8s-worker-node1 <none> <none> kube-system coredns-78fcd69978-49kgg 1/1 Running 0 44s 10.244.0.2 k8s-master-node1 <none> <none> kube-system coredns-78fcd69978-hq69g 1/1 Running 0 44s 10.244.0.3 k8s-master-node1 <none> <none> kube-system etcd-k8s-master-node1 1/1 Running 0 58s 10.107.24.80 k8s-master-node1 <none> <none> kube-system kube-apiserver-k8s-master-node1 1/1 Running 0 58s 10.107.24.80 k8s-master-node1 <none> <none> kube-system kube-controller-manager-k8s-master-node1 1/1 Running 0 58s 10.107.24.80 k8s-master-node1 <none> <none> kube-system kube-flannel-ds-9lnld 1/1 Running 0 31s 10.107.24.81 k8s-worker-node1 <none> <none> kube-system kube-flannel-ds-xf86g 1/1 Running 0 31s 10.107.24.80 k8s-master-node1 <none> <none> kube-system kube-proxy-2f2vj 1/1 Running 0 37s 10.107.24.81 k8s-worker-node1 <none> <none> kube-system kube-proxy-d6xjq 1/1 Running 0 44s 10.107.24.80 k8s-master-node1 <none> <none> kube-system kube-scheduler-k8s-master-node1 1/1 Running 0 58s 10.107.24.80 k8s-master-node1 <none> <none> kube-system metrics-server-77564bc84d-j54hk 1/1 Running 0 26s 10.107.24.81 k8s-worker-node1 <none> <none> See detailed log >> /var/log/kubeinstall.log 2.4 验证Docker容器启动状态[root@master ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 992e282b87bc 8d147537fb7d "/coredns -conf /etc…" 4 minutes ago Up 4 minutes k8s_coredns_coredns-78fcd69978-hq69g_kube-system_826a525e-72ce-4cbd-90e5-fdca4b2fab32_0 5a85366c9f9b 8d147537fb7d "/coredns -conf /etc…" 4 minutes ago Up 4 minutes k8s_coredns_coredns-78fcd69978-49kgg_kube-system_3fccb231-ee10-4976-b81f-24d63aacd08a_0 7dc7e4542e87 k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_coredns-78fcd69978-hq69g_kube-system_826a525e-72ce-4cbd-90e5-fdca4b2fab32_3 fe088504486c k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_coredns-78fcd69978-49kgg_kube-system_3fccb231-ee10-4976-b81f-24d63aacd08a_3 d6c22b0b9f01 404fc3ab6749 "/opt/bin/flanneld -…" 4 minutes ago Up 4 minutes k8s_kube-flannel_kube-flannel-ds-xf86g_kube-system_27967aa7-4921-4117-b512-98b39c39faf5_0 9b3495f4b962 k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_kube-flannel-ds-xf86g_kube-system_27967aa7-4921-4117-b512-98b39c39faf5_0 9859df5625ba 36c4ebbc9d97 "/usr/local/bin/kube…" 4 minutes ago Up 4 minutes k8s_kube-proxy_kube-proxy-d6xjq_kube-system_4f120047-946e-4cc4-9af0-a3d5502393eb_0 e3e8672494f2 k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_kube-proxy-d6xjq_kube-system_4f120047-946e-4cc4-9af0-a3d5502393eb_0 01b91ddb6ad2 6e002eb89a88 "kube-controller-man…" 5 minutes ago Up 5 minutes k8s_kube-controller-manager_kube-controller-manager-k8s-master-node1_kube-system_aa5c3b81774bd4cc98215b1c8732d87c_0 3fe245146e59 004811815584 "etcd --advertise-cl…" 5 minutes ago Up 5 minutes k8s_etcd_etcd-k8s-master-node1_kube-system_8d8c7b9310b33393732d993c41c7d450_0 10baaf8a7ab9 f30469a2491a "kube-apiserver --ad…" 5 minutes ago Up 5 minutes k8s_kube-apiserver_kube-apiserver-k8s-master-node1_kube-system_710a8249ad30bff927c89228973db8ac_0 a06f62ed2331 aca5ededae9c "kube-scheduler --au…" 5 minutes ago Up 5 minutes k8s_kube-scheduler_kube-scheduler-k8s-master-node1_kube-system_6ab3eb82cd0b41c3d3b546b333a12933_0 553f4038bea5 k8s.gcr.io/pause:3.5 "/pause" 5 minutes ago Up 5 minutes k8s_POD_kube-scheduler-k8s-master-node1_kube-system_6ab3eb82cd0b41c3d3b546b333a12933_0 9fd833e89902 k8s.gcr.io/pause:3.5 "/pause" 5 minutes ago Up 5 minutes k8s_POD_kube-controller-manager-k8s-master-node1_kube-system_aa5c3b81774bd4cc98215b1c8732d87c_0 f6ebe5b6fb57 k8s.gcr.io/pause:3.5 "/pause" 5 minutes ago Up 5 minutes k8s_POD_kube-apiserver-k8s-master-node1_kube-system_710a8249ad30bff927c89228973db8ac_0 7f0f2b465ec9 k8s.gcr.io/pause:3.5 "/pause" 5 minutes ago Up 5 minutes k8s_POD_etcd-k8s-master-node1_kube-system_8d8c7b9310b33393732d993c41c7d450_0 [root@node ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d619333b2d61 d3dc57185ba2 "/portainer --tunnel…" 4 minutes ago Up 4 minutes k8s_dashboard-en_dashboard-en-55596d469-lrnp9_dashboard-en_f8a4e4fc-c6c2-4dc3-95e3-bd581ea81e76_0 7d7c0eaf86f8 c0d510ae5b6e "./agent" 4 minutes ago Up 4 minutes k8s_dashboard-agent_dashboard-agent-cd88cf454-q48b4_dashboard-cn_921e034a-83ba-4a22-8029-d74ebb82c9bb_0 f69883f86cbc ff950b2c8963 "/portainer" 4 minutes ago Up 4 minutes k8s_dashboard-cn_dashboard-cn-64bd46887f-jvm4t_dashboard-cn_cf7654e0-4b77-4604-9bef-7ad37e2fff0d_0 dcfb61df7245 k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_dashboard-en-55596d469-lrnp9_dashboard-en_f8a4e4fc-c6c2-4dc3-95e3-bd581ea81e76_0 ecf3389d5a7e k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_dashboard-agent-cd88cf454-q48b4_dashboard-cn_921e034a-83ba-4a22-8029-d74ebb82c9bb_0 76d14ee95f0f k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_dashboard-cn-64bd46887f-jvm4t_dashboard-cn_cf7654e0-4b77-4604-9bef-7ad37e2fff0d_0 b2b2ce7cebdc 17c225a562d9 "/metrics-server --c…" 4 minutes ago Up 4 minutes k8s_metrics-server_metrics-server-77564bc84d-j54hk_kube-system_662e9598-c936-4cbc-ad1c-5a671133da4b_0 b99a8d500109 k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_metrics-server-77564bc84d-j54hk_kube-system_662e9598-c936-4cbc-ad1c-5a671133da4b_0 8b9548e04848 404fc3ab6749 "/opt/bin/flanneld -…" 4 minutes ago Up 4 minutes k8s_kube-flannel_kube-flannel-ds-9lnld_kube-system_b285135a-5a60-4060-9aa3-ace5c83222cf_0 0dc6fc7a3554 k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_kube-flannel-ds-9lnld_kube-system_b285135a-5a60-4060-9aa3-ace5c83222cf_0 f9a9b3929d68 36c4ebbc9d97 "/usr/local/bin/kube…" 4 minutes ago Up 4 minutes k8s_kube-proxy_kube-proxy-2f2vj_kube-system_efd5573d-bcfc-4977-b59d-5b618f76e481_0 124eb526549d k8s.gcr.io/pause:3.5 "/pause" 4 minutes ago Up 4 minutes k8s_POD_kube-proxy-2f2vj_kube-system_efd5573d-bcfc-4977-b59d-5b618f76e481_03.其他部署3.1 在 Kubernetes 集群中完成 KubeVirt 环境的安装[root@master ~]# kubeeasy add --virt kubevirt[2023-03-20 13:40:18] INFO: [start] bash kubeeasy add --virt kubevirt [2023-03-20 13:40:18] INFO: [check] sshpass command exists. [2023-03-20 13:40:18] INFO: [check] wget command exists. [2023-03-20 13:40:19] INFO: [check] conn apiserver succeeded. [2023-03-20 13:40:19] INFO: [virt] add kubevirt [2023-03-20 13:40:19] INFO: [apply] apply kubevirt-operator.yaml file [2023-03-20 13:40:20] INFO: [apply] apply kubevirt-operator.yaml file succeeded. [2023-03-20 13:40:23] INFO: [waiting] waiting kubevirt [2023-03-20 13:40:30] INFO: [waiting] kubevirt pods ready succeeded. [2023-03-20 13:40:30] INFO: [apply] apply kubevirt-cr.yaml file [2023-03-20 13:40:30] INFO: [apply] apply kubevirt-cr.yaml file succeeded. [2023-03-20 13:41:03] INFO: [waiting] waiting kubevirt [2023-03-20 13:41:09] INFO: [waiting] kubevirt pods ready succeeded. [2023-03-20 13:41:12] INFO: [waiting] waiting kubevirt [2023-03-20 13:41:34] INFO: [waiting] kubevirt pods ready succeeded. [2023-03-20 13:41:37] INFO: [waiting] waiting kubevirt [2023-03-20 13:41:37] INFO: [waiting] kubevirt pods ready succeeded. [2023-03-20 13:41:37] INFO: [apply] apply multus-daemonset.yaml file [2023-03-20 13:41:38] INFO: [apply] apply multus-daemonset.yaml file succeeded. [2023-03-20 13:41:41] INFO: [waiting] waiting kube-multus [2023-03-20 13:41:41] INFO: [waiting] kube-multus pods ready succeeded. [2023-03-20 13:41:41] INFO: [apply] apply multus-cni-macvlan.yaml file [2023-03-20 13:41:41] INFO: [apply] apply multus-cni-macvlan.yaml file succeeded. [2023-03-20 13:41:41] INFO: [cluster] kubernetes kubevirt status + kubectl get pod -n kubevirt -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES virt-api-86f9d6d4f-dh9pv 1/1 Running 0 52s 10.244.0.6 k8s-master-node1 <none> <none> virt-api-86f9d6d4f-twn7b 1/1 Running 0 52s 10.244.1.7 k8s-worker-node1 <none> <none> virt-controller-54b79f5db-vb42b 1/1 Running 0 27s 10.244.1.9 k8s-worker-node1 <none> <none> virt-controller-54b79f5db-wtfcp 1/1 Running 0 27s 10.244.0.8 k8s-master-node1 <none> <none> virt-handler-gch9f 1/1 Running 0 27s 10.244.1.8 k8s-worker-node1 <none> <none> virt-handler-lkp2l 1/1 Running 0 27s 10.244.0.7 k8s-master-node1 <none> <none> virt-operator-6fbd74566c-756kp 1/1 Running 0 81s 10.244.0.4 k8s-master-node1 <none> <none> virt-operator-6fbd74566c-ns75v 1/1 Running 0 81s 10.244.1.6 k8s-worker-node1 <none> <none> See detailed log >> /var/log/kubeinstall.log 3.2 在 Kubernetes 集群中完成服务网格（ServiceMesh）项目 Istio 环境的安装[root@master ~]# kubeeasy add --istio istio #在 Kubernetes 集群上完成 Istio 服务网格环境的安装，然后新建命名空间 exam，为该命名空间开启自动注入 Sidecar。 #创建exam命名空间 [root@master ~]# kubectl create ns exam #通过为命名空间打标签来实现自动注入 [root@master ~]# kubectl label ns exam istio-injection=enabled[2023-03-20 13:43:39] INFO: [start] bash kubeeasy add --istio istio [2023-03-20 13:43:39] INFO: [check] sshpass command exists. [2023-03-20 13:43:39] INFO: [check] wget command exists. [2023-03-20 13:43:39] INFO: [check] conn apiserver succeeded. [2023-03-20 13:43:40] INFO: [istio] add istio ✔ Istio core installed ✔ Istiod installed ✔ Egress gateways installed ✔ Ingress gateways installed ✔ Installation complete Making this installation the default for injection and validation. Thank you for installing Istio 1.12. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/FegQbc9UvePd4Z9z7 [2023-03-20 13:43:55] INFO: [waiting] waiting istio-egressgateway [2023-03-20 13:43:55] INFO: [waiting] istio-egressgateway pods ready succeeded. [2023-03-20 13:43:58] INFO: [waiting] waiting istio-ingressgateway [2023-03-20 13:43:58] INFO: [waiting] istio-ingressgateway pods ready succeeded. [2023-03-20 13:44:01] INFO: [waiting] waiting istiod [2023-03-20 13:44:01] INFO: [waiting] istiod pods ready succeeded. [2023-03-20 13:44:05] INFO: [waiting] waiting grafana [2023-03-20 13:44:05] INFO: [waiting] grafana pods ready succeeded. [2023-03-20 13:44:08] INFO: [waiting] waiting jaeger [2023-03-20 13:44:08] INFO: [waiting] jaeger pods ready succeeded. [2023-03-20 13:44:11] INFO: [waiting] waiting kiali [2023-03-20 13:44:32] INFO: [waiting] kiali pods ready succeeded. [2023-03-20 13:44:35] INFO: [waiting] waiting prometheus [2023-03-20 13:44:35] INFO: [waiting] prometheus pods ready succeeded. [2023-03-20 13:44:35] INFO: [cluster] kubernetes istio status + kubectl get pod -n istio-system -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES grafana-6ccd56f4b6-7sfwt 1/1 Running 0 34s 10.244.0.11 k8s-master-node1 <none> <none> istio-egressgateway-7f4864f59c-qg22p 1/1 Running 0 47s 10.244.0.10 k8s-master-node1 <none> <none> istio-ingressgateway-55d9fb9f-2rp9q 1/1 Running 0 47s 10.244.1.10 k8s-worker-node1 <none> <none> istiod-555d47cb65-sj56t 1/1 Running 0 53s 10.244.0.9 k8s-master-node1 <none> <none> jaeger-5d44bc5c5d-q9vj8 1/1 Running 0 34s 10.244.1.11 k8s-worker-node1 <none> <none> kiali-9f9596d69-rv2fv 1/1 Running 0 33s 10.244.0.12 k8s-master-node1 <none> <none> prometheus-64fd8ccd65-t62tj 2/2 Running 0 33s 10.244.1.12 k8s-worker-node1 <none> <none> See detailed log >> /var/log/kubeinstall.log 3.3 平台部署–部署 Harbor 仓库及 Helm 包管理工具kubeeasy add --registry harbor[2023-03-20 13:47:23] INFO: [start] bash kubeeasy add --registry harbor [2023-03-20 13:47:23] INFO: [check] sshpass command exists. [2023-03-20 13:47:23] INFO: [check] wget command exists. [2023-03-20 13:47:23] INFO: [check] conn apiserver succeeded. [2023-03-20 13:47:23] INFO: [offline] unzip offline harbor package on local. [2023-03-20 13:47:29] INFO: [offline] installing docker-compose on local. [2023-03-20 13:47:29] INFO: [offline] Installing harbor on local. [Step 0]: checking if docker is installed ... Note: docker version: 20.10.14 [Step 1]: checking docker-compose is installed ... Note: docker-compose version: 2.2.1 [Step 2]: loading Harbor images ... [Step 3]: preparing environment ... [Step 4]: preparing harbor configs ... prepare base dir is set to /opt/harbor WARNING:root:WARNING: HTTP protocol is insecure. Harbor will deprecate http protocol in the future. Please make sure to upgrade to https Generated configuration file: /config/portal/nginx.conf Generated configuration file: /config/log/logrotate.conf Generated configuration file: /config/log/rsyslog_docker.conf Generated configuration file: /config/nginx/nginx.conf Generated configuration file: /config/core/env Generated configuration file: /config/core/app.conf Generated configuration file: /config/registry/config.yml Generated configuration file: /config/registryctl/env Generated configuration file: /config/registryctl/config.yml Generated configuration file: /config/db/env Generated configuration file: /config/jobservice/env Generated configuration file: /config/jobservice/config.yml Generated and saved secret to file: /data/secret/keys/secretkey Successfully called func: create_root_cert Generated configuration file: /compose_location/docker-compose.yml Clean up the input dir [Step 5]: starting Harbor ... [+] Running 10/10 ⠿ Network harbor_harbor Created 0.1s ⠿ Container harbor-log Started 0.7s ⠿ Container harbor-db Started 1.8s ⠿ Container registryctl Started 2.1s ⠿ Container harbor-portal Started 2.1s ⠿ Container redis Started 1.9s ⠿ Container registry Started 2.2s ⠿ Container harbor-core Started 3.1s ⠿ Container harbor-jobservice Started 4.0s ⠿ Container nginx Started 4.1s ✔ ----Harbor has been installed and started successfully.---- [2023-03-20 13:49:07] INFO: [cluster] kubernetes Harbor status + docker-compose -f /opt/harbor/docker-compose.yml ps NAME COMMAND SERVICE STATUS PORTS harbor-core "/harbor/entrypoint.…" core running (healthy) harbor-db "/docker-entrypoint.…" postgresql running (healthy) harbor-jobservice "/harbor/entrypoint.…" jobservice running (healthy) harbor-log "/bin/sh -c /usr/loc…" log running (healthy) 127.0.0.1:1514->10514/tcp harbor-portal "nginx -g 'daemon of…" portal running (healthy) nginx "nginx -g 'daemon of…" proxy running (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp redis "redis-server /etc/r…" redis running (healthy) registry "/home/harbor/entryp…" registry running (healthy) registryctl "/home/harbor/start.…" registryctl running (healthy) See detailed log >> /var/log/kubeinstall.log
Kubernetes Pod的操作指令查看默认命名空间的pod 默认命名空间： defaultkubectl get pod | pods | poNAME READY STATUS RESTARTS AGE exam 1/1 Running 0 2d1h查看指定命名空间的podkubectl get pod -n kube-systemNAME READY STATUS RESTARTS AGE coredns-78fcd69978-49kgg 1/1 Running 0 2d1h coredns-78fcd69978-hq69g 1/1 Running 0 2d1h ......查看所有命名空间podkubectl get pod -ANAMESPACE NAME READY STATUS RESTARTS AGE dashboard-en dashboard-en-55596d469-lrnp9 1/1 Running 0 2d1h default exam 1/1 Running 0 2d1h istio-system grafana-6ccd56f4b6-7sfwt 1/1 Running 0 2d1h ......查看pod详细信息kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES exam 1/1 Running 0 2d1h 10.244.1.5 k8s-worker-node1 <none> <none>实时监控pod详细kubectl get pod -wNAME READY STATUS RESTARTS AGE exam 1/1 Running 0 2d1h ^C命令行直接创建podkubectl run mariadb --image=hyperf-mariadb:v1.0模板创建podapiVersion: v1 kind: Pod metadata: name: mariadb spec: containers: - name: mariadb image: hyperf-mariadb:v1.0 ports: - containerPort: 3307create 仅仅是在不存在时创建，如果已经存在则会报错，apply在不存在时创建，在存在时更新配置kubectl create -f k8s.yml kubectl apply -f k8s.yml 删除podkubectl delete mariadbkubectl delete -f k8s.yml进入Pod中的容器# 默认进入pod中第一个容器 kubectl exec -it Pod名称 -- 命令 # 进入Pod中指定容器 kubectl exec -it Pod名称 -c 容器名称 -- 命令查看pod日志# 默认查看pod中所有容器日志 kubectl logs -f(可选，实时) pod名称 # 查看pod中单个容器日志 kubectl logs -f pod名称 -c 容器名称查看pod描述信息kubectl describe pod pod名称
CentOS7 搭建http的yum源1. 环境准备永久关闭防火墙[root@yum ~]# systemctl stop firewalld && systemctl disable firewalld Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.永久关闭selinux[root@yum ~]# setenforce 0 [root@yum ~]# sed -i 's/enforcing/disabled/g' /etc/selinux/config [root@yum ~]# cat /etc/selinux/config | grep = # SELINUX= can take one of these three values: SELINUX=disabled # SELINUXTYPE= can take one of three values: SELINUXTYPE=targeted 挂载系统镜像源[root@yum ~]# mount -o loop /dev/cdrom /mnt/ [root@yum ~]# mkdir /opt/centos [root@yum ~]# cp -rf /mnt/* /opt/centos/ [root@yum ~]# umount /mnt/备份原有yum源[root@yum ~]# mkdir yumbackup [root@yum ~]# mv /etc/yum.repos.d/* yumbackup/配置centos系统镜像源[root@yum ~]# cat << EOF > /etc/yum.repos.d/yum.repo > [centos] > name=centos > baseurl=file:///opt/centos > gpgcheck=0 > enable=1 > EOF [root@yum ~]# cat /etc/yum.repos.d/yum.repo [centos] name=centos baseurl=file:///opt/centos gpgcheck=0 enable=1 [root@yum ~]# yum clean all Loaded plugins: fastestmirror Cleaning repos: centos [root@yum ~]# yum repolist Loaded plugins: fastestmirror Determining fastest mirrors centos | 3.6 kB 00:00:00 (1/2): centos/group_gz | 153 kB 00:00:00 (2/2): centos/primary_db | 3.3 MB 00:00:00 repo id repo name status centos centos 4,070 repolist: 4,070安装工具yum install -y vim net-tools2.配置http源安装httpyum install -y httpd systemctl restart httpd systemctl enable httpd创建软连接指向源路径[root@yum html]# ln -s /opt/* /var/www/html/删除httpd默认页内容echo "" > /etc/httpd/conf.d/welcome.conf重启httpd服务systemctl restart httpd
Kubernetes集群ezdown脚本一键部署1.环境准备主机信息主机名IP地址集群服务node110.107.24.81nodeetcd、api-server、controlor-manager、schedulernode210.107.24.82nodekubelet、kube-proxy、dockermaster10.107.24.83masterkubelet、kube-proxy、docker配置hosts解析10.107.24.81 node1 10.107.24.82 node2 10.107.24.83 master生成SSH身份文件ssh-keygen 一路回车配置免密登入ssh-copy-id -i node1 ssh-copy-id -i node2 ssh-copy-id -i master测试免密登入ssh master ssh node1 ssh node2禁用交换分区swapoff -a sed -i.bak '/swap/s/^/#/' /etc/fstab关闭防火墙systemctl stop firewalld && systemctl disable firewalld安装git和wgetyum install -y git wget2.脚本安装Kubernetes下载ezdown[root@master ~]# wget https://github.com/easzlab/kubeasz/releases/download/3.5.2/ezdown [root@master ~]# chmod +x ezdown下载所需文件# 国内 [root@master ~]# ./ezdown -D # 国外 [root@master ~]# ./ezdown -D -m standard2023-03-19 14:19:49 INFO Action successed: download_all创建集群配置[root@master ~]# ./ezdown -S2023-03-19 14:20:13 INFO Action begin: start_kubeasz_docker 2023-03-19 14:20:13 INFO try to run kubeasz in a container 2023-03-19 14:20:13 DEBUG get host IP: 10.107.24.83 fc0377122adc8726397e25b6f0285e04072e6b76b9f6b9bd1a0dca3b17d6e1a2 2023-03-19 14:20:14 INFO Action successed: start_kubeasz_docker创建新的集群[root@master ~]# docker exec -it kubeasz ezctl new k8s2023-03-19 06:21:22 DEBUG generate custom cluster files in /etc/kubeasz/clusters/k8s 2023-03-19 06:21:22 DEBUG set versions 2023-03-19 06:21:22 DEBUG cluster k8s: files successfully created. 2023-03-19 06:21:22 INFO next steps 1: to config '/etc/kubeasz/clusters/k8s/hosts' 2023-03-19 06:21:22 INFO next steps 2: to config '/etc/kubeasz/clusters/k8s/config.yml'修改新的集群配置文件[root@master ~]# vim /etc/kubeasz/clusters/k8s/hosts# 'etcd' cluster should have odd member(s) (1,3,5,...) [etcd] 10.107.24.83 # master node(s), set unique 'k8s_nodename' for each node # CAUTION: 'k8s_nodename' must consist of lower case alphanumeric characters, '-' or '.', # and must start and end with an alphanumeric character [kube_master] 10.107.24.83 k8s_nodename='master' # work node(s), set unique 'k8s_nodename' for each node # CAUTION: 'k8s_nodename' must consist of lower case alphanumeric characters, '-' or '.', # and must start and end with an alphanumeric character [kube_node] 10.107.24.81 k8s_nodename='node1' 10.107.24.82 k8s_nodename='node2'一键安装docker exec -it kubeasz ezctl setup k8s allPLAY RECAP ***************************************************************************************************** 10.107.24.81 : ok=76 changed=73 unreachable=0 failed=0 skipped=129 rescued=0 ignored=1 10.107.24.82 : ok=76 changed=73 unreachable=0 failed=0 skipped=129 rescued=0 ignored=1 10.107.24.83 : ok=113 changed=105 unreachable=0 failed=0 skipped=152 rescued=0 ignored=1 localhost : ok=43 changed=40 unreachable=0 failed=0 skipped=42 rescued=0 ignored=0