1 bio
1.1 baota
01.BaoTa
a.安装
官方版
wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh
-----------------------------------------------------------------------------------------------------
纯净版
yum install -y wget && wget -O install.sh http://v7.hostcli.com/install/install_6.0.sh && sh install.sh
b.登录
外网面板地址: http://101.200.59.179:9999/4e55fa31
内网面板地址: http://192.168.2.128:8888/4033665/ 或 http://192.168.2.138:8888/01c62172
username: myslayers
password: 4033665X
c.绑定
宝塔账号:15135890769
宝塔密码:4033665X
d.远程
ssh [email protected]
XXXXXXX
e.设置
bt --超级面板
/etc/init.d/bt default --查看面板入口
rm -f /www/server/panel/data/admin_path.pl --关闭安全入口
f.卸载
wget http://download.bt.cn/install/bt-uninstall.sh
sh bt-uninstall.sh
02.BaoTa
a.位置
网站:/www/wwwroot/192.168.2.128
-----------------------------------------------------------------------------------------------------
mongodb:/www/server/mongodb
mysql:/www/server/mysql
nginx:/www/server/nginx
nvm:/www/server/nvm
php:/www/server/php
phpmyadmin:/www/server/phpmyadmin
pure-ftpd:/www/server/pure-ftpd
redis:/www/server/redis
tomcat9:/www/server/tomcat9
jdk:/usr/java/jdk1.8.0_121/
-----------------------------------------------------------------------------------------------------
jdk:/data/jdk1.8.0_202/
maven:/data/apache-maven-3.6.3/
tomcat:/data/apache-tomcat-9.0.78/
node:/data/node-v16.20.1-linux-x64/
b.安全
SSH 22
FTP 20
nginx 80
mysql 3306
redis 6379 bind 0.0.0.0
tomcat 8080
mongodb 27017
phpMyAdmin 888
全部放开 22-9999
-----------------------------------------------------------------------------------------------------
bt 8888
Portainer 9000
c.网站
略
1.2 panel
01.常用配置
a.软件
Jellyfin --多媒体
Navidrome --音乐服务器
Bitwarden --密码管理服务
Mailserver --邮件服务器
YesPlayMusic --网易云
HomeAssistant --开源家庭自动化
-----------------------------------------------------------------------------------------------------
思源笔记 --自建
Lsky-pro --图床
Easylmage --图床
ObsidianLiveSync --Obsidian在线同步插件
b.网络
frps 【√】--服务端
frpc --客户端
ddns-go 【√】--DNS动态域名解析,自动获得你的公网IPv4或IPv6地址,并解析到对应的域名服务
RustDesk --远程桌面软件
DomainAdmin --域名SSL证书监测平台
cloudflared --CloudflareTunnel客户端
-----------------------------------------------------------------------------------------------------
AList --私人网盘
SFTPGo --SFTP服务器
Seafile --支持WebDAV,支持COS存储桶
Cloudreve --支持多家云存储的云盘系统
nextcloud --支持WebDAV,支持S3对象存储,或兼容S3实现如minio、腾讯cos
c.数据库
mysql 【√】--数据库
redis 【√】--数据库
mongodb 【√】--数据库
postgresql 【√】--数据库
-----------------------------------------------------------------------------------------------------
phpMyAdmin --MySQL和MariaDB的Web界面
CloudBeaver --云数据库管理器
mongo-express --MongoDB管理界面
Redpanda Console --KafkaWeb管理工具
Redis-Commander --Redis Web管理工具
-----------------------------------------------------------------------------------------------------
RabbitMQ --中间件
Kafka --中间件
-----------------------------------------------------------------------------------------------------
DataEase --数据可视化分析工具
d.Web服务器
Go --web环境
Java --web环境
PHP8 --web环境
.NET --web环境
Python --web环境
Node.js --web环境
-----------------------------------------------------------------------------------------------------
minio --对象存储服务器
Nacos --服务发现
Jenkins --持续集成工具
Sentinel --限流、熔断降级
-----------------------------------------------------------------------------------------------------
青龙 --定时任务管理平台
KubePi --现代化的 K8s 面板
openresty 【√】--基于Nginx的高性能Web应用服务器
OpenLiteSpeed --高性能、轻量级、开源的HTTP服务器
ApacheTomcat --开源的Web月服务器和Servlet容器
NginxProxy Manager:Nginx 可视化管理工具
e.大模型
Ollama --本地运行Llama2模型
LocalAI --免费的开源原OpenAI替代品
-----------------------------------------------------------------------------------------------------
new-api --中转API
one-api --中转API
-----------------------------------------------------------------------------------------------------
MaxKB --知识库问答系统
LobeChat --客户端API
ChatGPT-Next-Web --客户端API
02.1panel面板
a.环境要求
操作系统:支持主流 Linux 发行版本(基于 Debian / RedHat,包括国产操作系统);
服务器架构:x86_64、aarch64、armv7l、ppc64le、s390x;
内存要求:建议可用内存在 1GB 以上;
浏览器要求:请使用 Chrome、FireFox、IE10+、Edge等现代浏览器;
可访问互联网。
b.安装部署
RedHat / CentOS
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sh quick_start.sh
-----------------------------------------------------------------------------------------------------
Ubuntu
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
-----------------------------------------------------------------------------------------------------
Debian
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && bash quick_start.sh
c.安装成功后,控制台会打印面板访问信息,可通过浏览器访问 1Panel:
http://目标服务器 IP 地址:目标端口/安全入口
-----------------------------------------------------------------------------------------------------
安全组规则:开放8080端口
安全入口:1pctl user-info
d.命令行工具
1Panel 默认内置了命令行运维工具 1pctl,通过执行 1pctl help,可以查看相关的命令说明。
Usage:
1pctl [COMMAND] [ARGS...]
1pctl --help
Commands:
status 查看 1Panel 服务运行状态
start 启动 1Panel 服务
stop 停止 1Panel 服务
restart 重启 1Panel 服务
uninstall 卸载 1Panel 服务
user-info 获取 1Panel 用户信息
listen-ip 切换 1Panel 监听 IP
version 查看 1Panel 版本信息
update 修改 1Panel 系统信息
reset 重置 1Panel 系统信息
restore 恢复 1Panel 服务及数据
-----------------------------------------------------------------------------------------------------
重置 1Panel 系统信息,包括取消安全入口登录,取消两步验证等
Usage:
1pctl reset [COMMAND] [ARGS...]
1pctl reset --help
Commands:
domain 取消 1Panel 访问域名绑定
entrance 取消 1Panel 安全入口
https 取消 1Panel https 方式登录
ips 取消 1Panel 授权 IP 限制
mfa 取消 1Panel 两步验证
-----------------------------------------------------------------------------------------------------
修改 1Panel 监听 IP
Usage:
1pctl listen-ip [COMMAND] [ARGS...]
1pctl listen-ip --help
Commands:
ipv4 监听 IPv4
ipv6 监听 IPv6
-----------------------------------------------------------------------------------------------------
修改 1Panel 系统信息
Usage:
1pctl update [COMMAND] [ARGS...]
1pctl update --help
Commands:
username 修改面板用户
password 修改面板密码
port 修改面板端口
-----------------------------------------------------------------------------------------------------
应用商店相关命令,包括初始化应用等
Usage:
1panel app [COMMAND] [ARGS...]
1panel app --help
Commands:
init 初始化应用
创建应用名为 app_name,版本为 v1.0.0 的应用,命令如下:
1panel app init -k app_name -v v1.0.0
03.1Panel多因素认证
a.设置流程(首次绑定)
a.路径
登录 1Panel -> 点击右上角头像 -> 安全设置 -> 两步验证。
b.操作
点击“开启两步验证”。
屏幕上会出现一个巨大的 二维码。
打开手机上的 Microsoft Authenticator App。
点击 App 里的“+”号 -> 选择“工作或学校帐户” (或其他) -> 选择“扫描二维码”。
对准屏幕扫描。
App 会显示一个 6 位数字,将其填入 1Panel 的确认框。
极其重要:1Panel 会给你一组 “应急备用码”。请抄写下来或打印,如果以后换手机或丢了手机,全靠这串码救急。
b.使用流程(动态验证)
a.登录时
浏览器输入 1Panel 地址(如 http://192.168.1.249:10086)。
输入用户名和密码。
关键点:此时不会直接进系统,而是跳出一个新界面,要求输入 “MFA 验证码”。
你打开手机 App,查看当前显示的 6 位数字(例如 839402)。
输入并回车,登录成功。
03.1panel授权
a.说明
1Panel V2 专业版 买断授权正版授权,未激活直接转赠到你帐号。官网原价 ¥1400,只卖688元,不到五折,购买立省712元。
注意:现在正式版已发布,可以稳定使用。
b.套餐内容
1台 1Panel V2 专业版永久授权(原价 ¥1200)
赠送 1 个 受管社区版节点
加送 1 个 社区版节点(原价 ¥200)
最多可同时管理 3 台服务器
节点扩容:超出部分 ¥200/个,可无限扩展
入门套餐适合90%用户,轻松管理多服务器!
c.专业功能亮点(含V1所有功能)
多机统一管理(Linux)
APP 手机端管理
节点互传、负载均衡
MySQL/PostgreSQL 主从复制支持
Redis 集群可视化管理
持续增强,稳定更新
d.购买须知
买断授权,永久可用
全新未激活,包含500条短信
确认收货后提供 ID 或手机号,直接官方转赠授权
本人是长期深度用户(V1、V2均在用),欢迎交流!
1.3 mirror
01.快速开始
a.Win10
物理机
Docker(WSL)
b.VMware
docker start mysql5
docker start mysql8
docker start redis
docker start mongo
docker start rabbit
docker start elasticsearch
c.Remote
SSH
Docker
Dockerfile
codespace
Jetbrains
d.Centos7
a.Command
01.network_bt.ova
02.network_bt_compile(mysql_redis_mongo_tomcat_nginx).ova 【NOW-bigdata01】
03.network_bt_compile(mysql_redis_mongo_tomcat_nginx)_python-3.7.2.ova
04.network_jdk_docker.ova
05.network_jdk_docker(mysql_redis_mongo_rabbitmq_es).ova
06.network_jdk_docker_remote(mysql_redis_mongo_rabbitmq_es).ova 【NOW-bigdata02】
07.network_bt_partition 【NOW-bigdata03】123456
b.Graphical
01.network_jdk_docker.ova 【NOW-bigdata04】
02.network_jdk_docker(mysql_redis_mongo_rabbitmq_es).ova
e.Debain10
a.Command
01.network.ova
02.network_bt.ova
03.network_bt_compile(mysql_redis_mongo_tomcat_nginx).ova 【NOW-debain01】
04.network_docker.ova
05.network_docker_remote(mysql_redis_mongo_rabbitmq_es).ova 【NOW-debain02】
06.network_docker_remote(mysql_redis_mongo_rabbitmq_es)_k-vim.ova
b.Graphical
01.network.ova 【NOW-debain03】
02.network_bt.ova
03.network_bt_compile(mysql_redis_mongo_tomcat_nginx).ova
f.Developer
a.Basic
07.network_bt_partition 【NOW-bigdata03】123456
b.Senior
192.168.2.128 bt_docker(portainer_rabbitmq_es)_compile(nginx_mysql_redis_mongodb_Java项目一键部署)_install(jdk_maven_tomcat)_deploy(ruoyi_ruoyi-vue)
192.168.2.129 bt_docker(Portainer_mysql_redis_mongo_rabbitmq_es)_docker(gitlab_jenkins_harbor_sonarqube)_install(git_jdk_maven_tomcat)
192.168.2.130_1 bt_docker(Portainer_mysql_redis_mongo_rabbitmq_es)_
192.168.2.130_2 bt_docker(Portainer)_deploy(ruoyi)
192.168.2.130_3 bt_docker(Portainer)_deploy(ruoyi-vue)
192.168.2.131 k8s-master
192.168.2.132 k8s-worker
02.常见镜像
a.类型
云服务器:ECS
轻量应用:SWAS
弹性容器:ECI
容器集群:ACK
对象存储:OSS
监控分组:CMS
托管实例
弹性高性能计算
b.轻量应用服务器(简化ECS):应用镜像
LAMP:linux + apache + mysql +php
LNMP:linux + nginx + mysql + php
Docker
Node.js
PhPwind
-----------------------------------------------------------------------------------------------------
Typecho
NextCloud
Cloudreve
wordPress
-----------------------------------------------------------------------------------------------------
1Panel
宝塔Linux面板
宝塔Windows面板
c.轻量应用服务器(简化ECS):系统镜像
Ubuntu
CentOS
CentOS Stream
Debian
Windows
-----------------------------------------------------------------------------------------------------
Alma Linux
Rocky Linux
Alibaba Cloud Linux
d.云服务器(标准ECS):应用管理
宝塔面板社区版 1panel运维面板社区版 Dify社区版 AutoMQ for Kafka BYOC
Java 运行环境 AutoMQ for Kafka BYOC版 Python运行环境 Docker社区版
Node.js运行环境 LNMP运行环境 WordPress社区版 LobeChat社区版
LAMP运行环境 PHP运行环境 Golang运行环境 RagFlow社区版
-------------------------------------------------------------------------------------------------
Stable diffusion DeepGPU 云XR实时渲染平台 Langflow社区版 Sky CostPilot
ChatGPTNextWeb社区版 MySQL社区版 ComfyUIDeepGPU加速社区版 Zabbix社区版
ChatGPT-on-WeChat社区版 Flowise社区版 JumpServer社区版 HeyForm社区版
Appsmith社区版 OneAPI社区版 NebulaGraph社区版 Jenkins社区版
-------------------------------------------------------------------------------------------------
OpenWebUI社区版 LibreChat社区版 Metabase社区版 Yunikorn社区版
MongoDB社区版 Waline社区版 Gitlab社区版 Discuz社区版
翼龙面板社区版 Maybe社区版 Prometheus社区版 Halo社区版
FaceChain社区版 ArgoWorkflows社区版 Authorizer社区版 Jupyterhub社区版
-------------------------------------------------------------------------------------------------
Websoft9多应用托管平台 Keygen社区版 Typebot社区版 PostgreSQL社区版
Bytebase社区版 Grafana社区版 Drupal社区版 Chef社区版
Puppet企业版 Typecho社区版 SaltStack社区版 Ansible Semaphore社区版
e.云服务器(标准ECS):计算巢
DeepSeekR1 宝塔面板社区版 幻兽帕鲁-快速部署 幻兽帕鲁-迁移到计算巢
1panel运维面板社区版 Dify社区版 AutoMQ for Kafka BBYOC 雾锁王国-迁移到计算巢
Java运行环境 我的世界-快速部署 AutoMQ for Kafka BYOC版 Python运行环境
2048小程序一键部署 Docker社区版 Node.js运行环境 TuGraph高性能图数据库
LNMP运行环境 七日杀-快速部署 WordPress社区版 LobeChat社区版
LAMP运行环境 悦数图数据库 PHP运行环境 灵魂面甲-快速部署
Stable Diffusion社区版 SQLynx 雾锁王国-快速部署 Golang运行环境
RagFlow社区版 基于NVIDIA NIM快速部署LLM模型 LLM Riddles社区版 夜族崛起-快速部署
Stable diffusion DeepGPU 站式企业专属Chatbot ChatTTS社区版 云XR实时渲染平台
计算巢SaaSBoost社区版 Langflow社区版 Sky CostPilot ChatGPTNextWeb社区版
Volcano社区版 MySQL社区版 neo4j社区版 TOPIAM数字身份管控平台-社区版
Cloudreve社区版 MaxKB社区版 ComfyUIDeepGPU加速社区版 JHGitLab
ChatGPT-on-WeChat社区版 Zabbix社区版 Flowise社区版 Hologres+PAI5分钟一键部署企业级
MemVerge MMCloud V3 Nocobase社区版 数擎全量预置服务 AlphaFold2社区版
JumpServer社区版 HeyForm社区版 OneAPI社区版 NebulaGraph社区版
Jenkins社区版 LAMMPS社区版 EMQX Enterprise Cluster Appsmith社区版
Open WebUI社区版 LibreChat社区版 九象(SkyDataPilot) Alluxio分布式超大规模数据编排系统
Metabase社区版 企业建站系统WordPress Yunikorn社区版 MongoDB社区版
Waline社区版 Xinference社区版 Qdrant社区版 Gitlab社区版
Discuz!社区版 Istio社区版 通义千问-开源大模型 翼龙面板社区版
达梦数据库DM8社区版 MAPPIC-密态计算云平台 CoAI社区版 Nextcloud社区版
ChaosMesh社区版 Maybe社区版 Jupyter Notebook社区版 Prometheus社区版
Halo社区版 WPS文档中台-长虹佳华 PAI+NAS搭建企业级AIGC绘画 FaceChain社区版
ArgoCD社区版 ArgoWorkflows社区版 Authorizer社区版 在线文件管理/云存储系统Nextcloud
Jupyterhub社区版 Moodle在线学习管理系统 宝塔Linux面板 Teable社区版
DataEase社区版 云数据库TiDB 五子棋网页游戏 扫雷网页游戏
Websoft9多应用托管平台 云数据库Klustron harbor社区版 万博云迁移
turtle画布 飞塔FortinettSDWAN Keycloak社区版21.1.2 OpenFOAM社区版
云数据库StoneDB软件 Walrus社区版 AutoDockVina社区版 Redis社区版
Java运行环境(CentOS7.9ARM版) MappingSpace 用友U9 cloud 宝塔Llnux面板-7.9.9倚天版
Tapdata Cloud Agent 用友U8 cloud Keygen社区版 Nginx-单机部署
03.常用部署
a.vercel
a.分类1
Angular
CreateReactApp
-------------------------------------------------------------------------------------------------
Hexo
Hugo
Jekyll
Next.js
Nuxt.js
Preact
-------------------------------------------------------------------------------------------------
Vite
VitePress
Vue.js
VuePress
Other
b.分类2
Astro
Blitz.js(Legacy)
Brunch
Docusaurus(v1)
Docusaurus(v2)
Dojo
Eleventy
Ember.js
FastHTML(Experimental)
-------------------------------------------------------------------------------------------------
Gatsby.js
Gridsome
Hydrogen (v1)
lonicAngular
lonic React
Middleman
Parcel
Polymer
ReactRouter
RedwoodJS
Remix
-------------------------------------------------------------------------------------------------
Saber
Sanity
Sanity (v3)
Sapper
Scully
SolidStart (vO)
SolidStart (v1)
Stencil
Storybook
Svelte
SvelteKit (vO)
SvelteKit (v1)
UmiJS
Zola
b.zeabur
a.价格
免费试用计划
一键部署任何服务,无需信用卡
Google Cloud 的免费部署体验
无需信用卡
项目将在 24 小时后自动删除
社区支持
-------------------------------------------------------------------------------------------------
开发者计划
从每月开始:5美元
部署无服务器和容器化服务并提供优先支持。
部署任何类型的服务
服务数据自动备份
部署预构建映像
优先技术支持
-------------------------------------------------------------------------------------------------
Free Trial
HongKong
Tokyo, Japan
Taipei, Taiwan
Shanghai, China
Frankfurt, Germany
California, United States
Singapore、
-------------------------------------------------------------------------------------------------
Node.js:Astro、Express、NestS、Next.js、Nue、Nuxt、Qwik、Remix、Svelte Kit、Umi、Vite、Waku
Bun:ElysiaJS、Hono
Java:Spring Boot
PHP:Laravel、Symfony
Python:Django、Flask、Reflex
Go
Deno:Fresh、TypeScript
Rust
Swift:Vapor
Dart:Flutter
静态网站:Hugo、MkDocs
.NET
b.分类1
Halo
Hexo
Gblog
WordPress
RSSHub
Wechat2RSS
wechat_gpt
wechat-server
-------------------------------------------------------------------------------------------------
n8n
Frp
v2ray
Nginx
Supabase
-------------------------------------------------------------------------------------------------
Alist
Pintree
Cloudreve
Nextcloud
SiYuanNote
Vaultwarden
c.分类2
Dify
MaxKB
Ollama
-------------------------------------------------------------------------------------------------
VoAPI
NewAPI
OneAPI
MaxAPI
OneHub
-------------------------------------------------------------------------------------------------
LobeChat
NextChat
LibreChat
-------------------------------------------------------------------------------------------------
ChatNio
chat2api
search2ai
ChatGPTPlus
ChatGPT-Mirror
ChatGPT-Next-Web
ChatGPT-Midjourney
d.分类3
MySQL
LibSQL
MariaDB
PostgreSQL
-------------------------------------------------------------------------------------------------
Redis
Kafka
MongoDB
RabbitMQ
-------------------------------------------------------------------------------------------------
SurrealDB
Dragonfly
ClickHouse
e.分类4
Gin-Starter
FastAPI-Starter
FastAPl-PostgreSQL
Express.js Starter
Kotlin Spring Boot Starter
1.4 storage
01.OSS对象存储
a.RAM 访问控制
用户:管理对急存储服务(OSS)权限、只读访问对象存储服务(OSS的权限)、管理云盒OSS的权限
用户组:管理对象存储服务(OSS)权限、只读访问对象存储服务(OSS)的权限
b.每个Bucket都需要单独设置跨越、授权策略,如troyekk-beijing、troyekk-zhangjiakou
跨越设置:app://obsidian.md、capacitor://localhost、http://localhost;GET、POST、PUT、DELETE、HEAD
授权策略:所有账号、读/写
02.客户端
a.OSS Browser
Endpoint:默认(公共云)、HTTPS加密(勾选)
-----------------------------------------------------------------------------------------------------
预设OSS路径:无
备注:无
b.S3 Browser
Display name:troyekk-beijing
Account type:S3 Compatible Storage
REST Endpoint:oss-cn-beijing.aliyuncs.com
Encrypt Access Keys with a password:不勾选
Use secure transfer(SSL/TLS):勾选
-----------------------------------------------------------------------------------------------------
Display name:troyekk-zhangjiakou
Account type:S3 Compatible Storage
REST Endpoint:oss-cn-zhangjiakou.aliyuncs.com
Encrypt Access Keys with a password:不勾选
Use secure transfer(SSL/TLS):勾选
-----------------------------------------------------------------------------------------------------
由于OSS仅支持S3的virtual hosted style访问方式,也是S3推荐方式,而目前S3 Browser默认使用的是Path style
因此,需要【Advanced S3-compatible storage settings】->【Addressing model:Virtual hosted style】
c.Remotely Save
服务地址(Endpoint):oss-cn-beijing.aliyuncs.com --外网访问
区域(Region):oss-cn-beijing-internal.aliyuncs.com --ECS的经典网络访问(内网)
存储桶(Bucket)的名字:troyekk-beijing
-----------------------------------------------------------------------------------------------------
自动运行:每1分钟
启动后自动运行一次:启动后第1秒运行一次
d.FolderSync
连接地址:oss-cn-beijing.aliyuncs.com
区域:ChinaBeijing
e.Cloudberry Edxplorer
Select Cloud Storage:Alibaba
Display name:troyekk-beijing
-----------------------------------------------------------------------------------------------------
由于OSS仅支持S3的virtual hosted style访问方式,也是S3推荐方式,而目前S3 Browser默认使用的是Path style
因此,需要打开【C:\Users\mysla\AppData\Local\CloudBerryLab\CloudBerry Explorer\settings.list】
打开配置文件将对应用户的RequestStyle标签改为VHost,如下图所示,保存退出后重启CloudBerry即可生效。
1.5 docker-cli
01.开启Docker-Engine远程访问的支持
a.配置:找到 ExecStart,增加 -H tcp://0.0.0.0:2375
vi /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H fd:// --containerd=/run/containerd/containerd.sock
b.重启
systemctl daemon-reload && service docker restart
c.防火墙
firewall-cmd --zone=public --add-port=2375/tcp --permanent
firewall-cmd --reload
firewall-cmd --zone=public --list-ports
02.下载和配置docker-cli-builder
a.安装
https://github.com/StefanScherer/docker-cli-builder/releases/
b.配置
docker context create bigdata01 --docker "host=ssh://192.168.2.128" --连接远程节点1(SSH)
docker context create bigdata01 --docker "host=tcp://192.168.2.128:2375" --连接远程节点1(TCP)
docker context update bigdata01 --docker "host=tcp://192.168.2.128:2375" --更新远程节点1(TCP)
docker context ls --查看全部节点
docker context rm -f bigdata01 --移除节点1
docker context use bigdata01 --切换节点1
c.导入与导出
docker context export bigdata01 --导出节点1
cat bigdata01.dockercontext --查看配置1
docker context import bigdata01 bigdata01.dockercontext --将配置1导入到节点1
d.使用
docker info --查看容器信息
docker ps -a --查看全部镜像
03.使用远程容器开发
a.远程主机上创建项目
a.新建一个目录,例如 ~/newproj, 并编写如下Dockerfile:
FROM python
ENV DEBIAN_FRONTEND=noninteractive
apt-get update
b.先创建镜像,再启动容器(tail -f:容器保持运行)
docker build . -t <image tag>
docker run -d --name <container name> -v ~/newproj:/workspaces/newproj <image tag> tail -f /dev/null
b.本地访问远程容器
a.切换节点
Docker Contexts: Use
b.选择节点中需要使用的容器
Remote-Containers: Attach to Running Container
1.6 codespace
01.原则
a.创建代码空间
①将虚拟机和存储分配给代码空间
②创建容器:默认使用默认映像,自定义【.devcontainer文件夹下的devcontainer.json、Dockerfile】
③连接到代码空间:打开【浏览器】或【本地开发】
④创建后设置:调用dotfile仓库,可以实现【个性化CodeSpace】
b.生命周期
①在代码空间中保存文件:默认几秒钟保存一次,没有交互30分钟后自动关闭
②关闭或停止代码空间:关闭【浏览器】或【本地开发】
③运行应用程序:默认所有端口都是私有,可以设置公有访问网址
c.开发容器
a.使用默认开发容器配置
GitHub 使用默认 Linux 映像创建代码空间,适用于【临时修改文件】;
直接使用【codespace】打开【repo】,在【Terminal】仍可检测到【java -version、mvn -v、node -v】
-------------------------------------------------------------------------------------------------
devcontainer-info content-url 默认linux配置
-------------------------------------------------------------------------------------------------
java -version 17.0.2
mvn -v 3.8.5
gradle -v 7.4.2
gcc 9.4.0
curl www.baidu.com -i | iconv -f utf-8 -t gbk html
-------------------------------------------------------------------------------------------------
node -v 16.14.2
yarn -v 1.22.15
-------------------------------------------------------------------------------------------------
go version 1.18.2
pip --version 22.1.1
python --version 3.10.4
-------------------------------------------------------------------------------------------------
mysql -V 无
redis-cli.exe -h 127.0.0.1 -p 6379 -a myslayers 无
mongo 无
b.使用预定义的开发容器配置
Ctrl+Shift+P
-> Codespaces: Add Development Container Configuration Files...
-> Show All Definitions...
-> Java 8
-> Install Maven
-> Rebuild now
c.创建自定义开发容器配置
https://github.com/halavah/demo
-> Configure and create codespace
-> Dev container configuration:.devcontainer.json 默认配置
-> Dev container configuration:.devcontainer/devcontainer.json 默认配置
-> Dev container configuration:.devcontainer/teamA/devcontainer.json
-> Dev container configuration:.devcontainer/teamB/devcontainer.json
或
https://github.com/settings
-> CodeSpaces
-> Dotfiles:Automatically install dotfiles
-> GPG verification
-> Access and security
d.将配置更改应用于代码空间
Ctrl+Shift+P
-> Codespaces: Rebuild Container 代码空间:【重启】
d.插件引导学习
a.开始:打开演练
Ctrl+Shift+P
-> Get Started:Open Walkthrough...
b.Learn the Fundamentals 学习基础知识
Redefine your editing skills 重新定义编辑技能
Limitless extensibility 无限的可扩展性
Tune your settings 调整您的设置
Lean back and learn 精益求精学习
c.Boost your Productivity(提高工作效率)
Side by side editing 并排编辑
Watch your code in action 观察代码的运行情况
Track your code with Git 使用 Git 跟踪您的代码
Automate your project tasks 自动化项目任务
Customize your shortcuts 自定义快捷键
d.Get Started with VS Code in the Web(开始使用 Web 的 VS Code)
Choose the look you want 选择您想要的外观
Sync to and from other devices 从其他设备同步
One shortcut to access everything 一个快捷键访问全部内容
Just the right amount of Ul 切换菜单栏
Rich support for all your languages 对语言丰富的支持
Quickly navigate between your files 在文件之间快速导航
02.配置
a.插件
浏览器:CODESPACES INSTALLED 48
浏览器:BROWSER INSTALLED 00
浏览器:RECOMMENDED 02
-----------------------------------------------------------------------------------------------------
本地开发:CODESPACES INSTALLED 57
本地开发:BROWSER INSTALLED 48
本地开发:RECOMMENDED 05
b.快捷键
浏览器:如需跟本地一致,必须覆盖配置文件
浏览器:并不会自动设置【Settings 程序配置文件】、【Keyboard Shortcuts 键盘配置文件】,均为默认
-----------------------------------------------------------------------------------------------------
本地开发:会自动读取【Settings 程序配置文件】、【Keyboard Shortcuts 键盘配置文件】,均为自定义
本地开发:若【Open in VS Code】,注意!!!此时【浏览器】就会拉取本地配置,与本地保持一致
c.优先级
如果在多个作用域中定义了设置,工作区设置优先级最高,远程 [Codespaces] 次之,最后是用户
您可以在两个地方定义 VS 代码 的默认编辑器设置
一是,在存储库的 .vscode/settings.json 文件中定义的编辑器设置将作为代码空间中工作区范围的设置进行应用
二是,devcontainer.json 文件的 settings 键中定义的编辑器设置在代码空间中用作 Remote Codespaces 范围的设置
03.使用
a.文件位置
浏览器:均为github repo内的文件
本地开发:均为github repo内的文件
b.编辑文件
1个仓库,1个配置
文件都在远程,【浏览器】与【本地】通过port进行相连
打开 package.json 插入任意文字,无论从本地还是浏览器均会【及时响应】
c.运行文件
浏览器:调用【https://halavah-demo-x6x4qppw2vr55-3000.githubpreview.dev/】中的【3000端口】
本地开发:调用【http://127.0.0.1:3000/】中的【3000端口】
d.识别JAVA环境
必须为纯净的Java项目,项目最好不要嵌套
04.VScode开发Java项目
a.准备
a.Extension Pack for Java
Maven for Java --Java:扩展(无)
Java Test Runner --Java:测试器(无)
Debugger for Java --Java:调试器(无)
Java Dependency Viewer --Java:依赖查看(无)
Visual Studio IntelliCode --Java:代码提示(无)
Language Support for Java(TM) by Red Hat --JAVA:代码导航、自动补全、重构、代码片段(无)
b.Spring Boot Extension Pack
Spring Boot Tools --SpringBoot:工具(无)
Spring Boot Dashboard --SpringBoot:仪表盘(launch.json)(无)
Concourse CI Pipeline Editor --SpringBoot:对项目文件提供支持(无)
Spring Initializr Java Support --SpringBoot:项目生成器(无)
Cloudfoundry Manifest YML Support --SpringBoot:对YML文件提供支持(无)
b.新建Java工程
a.命令
Java: New Java Class --Java: 创建Java类
Java: Create Java Project... --Java: 创建Java项目…
Java: Open Java Extension Log File --Java: 打开Java插件日志文件
Java: Open Java Formatter Settings --Java: 打开Java格式设置
Java: Open Java Language Server Log File --Java: 打开Java语言服务器日志文件
Java: Open All Log Files --Java: 打开所有日志文件
Java: Switch to Standard Mode --Java: 切换到标准模式
Java: Clean Java Language Server Workspace --Java: 清理Java语言服务器工作区
Java: Show Build Job Status --Java: 显示工作状态
Java: Debug Tests --Java: 调试测试用例
Java: Run Tests --Java: 运行测试用例
Java: Configure Classpath
Java: Configure Java Runtime
Java: Extensions Guide
Java: Help Center
Java: Install New JDK
Java: Open Java Formatter Settings with Preview
Java: Overview
Java: Show Release Notes
Java: Tips for Beginners
b.使用
Java: Create Java Project...
-> Maven
-> archetype-quickstart-jdk8
-> Relaunch
c.新建SpringBooot工程
a.命令
Spring Boot Dashboard: Debug ..
Spring Boot Dashboard: Run ..
Spring Boot Dashboard: Show All Beans
Spring Boot Dashboard: Show All Endpoints
Spring Boot Dashboard: Show Defined Beans
Spring Boot Dashboard: Show Defined Endpoints
Spring Boot Dashboard: Stop ..
Spring Boot: Manage Live Spring Boot Process Connections
Spring Initializr: Add Starters...
Spring Initializr: Create a Gradle Project...
Spring Initializr: Create a Maven Project...
Spring: Focus on Beans View
Spring: Focus on Endpoint Mappings View
Spring: Focus on Spring Boot Dashboard View
b.使用
Java: Create Java Project...
-> SpringBoot
-> Maven Project
-> SpringBoot 2.7.0
-> Java
-> org.myslayers
-> Jar
-> Java 8
-> Selected 6 dependencies:Lombok、Spring Web、...
-> OK
c.编写测试
@RestController
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@GetMapping("/hello")
public String hello() {
return "hello world" + LocalDate.now();
}
}
2 docker
2.1 [1]basic
01.介绍
a.CPU架构与ABI(Application binary interface)
a.对应关系
CPU架构(纵)\API(横) armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64
ARMv5 支持
ARMv7 支持 支持
x86 支持 支持 支持
x86_64 支持 支持 支持
ARMv8 支持 支持 支持
MIPS 支持
MIPS64 支持
b.具体介绍
x86:平板、模拟器
x86_64:64位平板
armeabi:第5代、第6代的ARM处理器,早期手机较多
armeabiv-v7a:第7代及以上的ARM处理器,2011年15月生产的Android设备
arm64-v8a:第8代、64位ARM处理器,目前比较常见
c.为什么叫x86为32位系统呢?
8086微处理器,英特尔出了划时代的8086之后,后来使用该架构出了80286、80386等,
这一系列CPU就称作x86,正式一点称作IA-32(Intel Architecture 32-bit)
-------------------------------------------------------------------------------------------------
x86架构的特点是cpu的寄存器是32位的,因此也叫32位cpu
基于32位cpu开发的操作系统就叫32位操作系统,因为目前x86架构在32位cpu的知名度,32位也被称为x86系统
d.x86_64与amd64
由于32位系统x86架构的种种限制,包括速度,性能等方面,Intel开始向64位架构发展,那么有两个选择:
一是,向下兼容x86;二是,完全重新设计指令集,不兼容x86
-------------------------------------------------------------------------------------------------
结果AMD领先,比Intel率先制造出了商用的兼容x86的CPU,AMD称之为AMD64,抢了64位PC市场,得到了用户的认同
而Intel选择了设计一种不兼容x86的全新64为指令集,称之为IA-64,但是比amd晚了一步,
微软把intel给忽悠了,承诺了会出安腾版windows server版,但是迟迟拿不出东西,
后来,微软也开始支持【AMD64的指令集】,但是换了个名字,叫x86_64,表示是x86指令集的64扩展
-------------------------------------------------------------------------------------------------
总结1:86_64、x64、AMD64基本上是同一个东西,现在用的intel/amd的桌面级CPU基本上都是x86_64
总结2:i386被用来作为对Intel 32位微处理器的统称,更多时候,我们公认i386为32位系统,其实就是x86
b.Dokcer运行模式
a.两种模式
一是(WSL2模式的Linux容器);二是(Hyper-V模式的Linux容器还是Windows容器)
b.资源分配
CPU:默认情况下,Docker Desktop设置为使用主机上可用处理器数量的一半
内存:默认情况下,Docker Desktop设置为使用2GB运行时内存,该内存是从计算机上的总可用内存中分配的
交换:根据需要配置交换文件的大小。默认值为1 GB
磁盘映像大小:指定磁盘映像的大小
磁盘映像位置:指定Linux卷的容器和映像的存储位置。
c.文件共享
“文件共享”选项卡仅在Hyper-V模式下可用,因为在WSL 2模式和Windows容器模式下,Windows将自动共享所有文件
d.Switch to windows containers
Windows container 分为两大部分:windows container on windows,linux container on windows
两种运行时不能同时使用,可以切换,切换过程中数据是不会丢失的
你不可以在 windows container 环境下操作 linux container 的镜像与容器
更不能在 linux container 环境 下操作 windows container 的镜像和容器,两者架构上不一致
-------------------------------------------------------------------------------------------------
尽管两者在技术架构上有差异,但是 docker 的基本操作都是适用的,如果你的磁盘不够大网速不够好,
不建议直接在自己电脑上尝试 windows container,windows container 大部分是基于 windows-sever 的镜像,
动则十几个G,下载镜像都不一定能下载成功。
e.总结
Docker近几年发展中,停止了一些以往内容的维护,如Docker Machine、Docker toolbox...
默认Docker for windows版本,分为WSL2、Hyper-V两种,默认WSL2,名字为【docker-desktop】
默认Docker分为两种容器,分为Linux、Windows两种,即【基于Linux的镜像,无法在Windows使用】
c.镜像、容器、数据卷、仓库、核心组成模块
a.镜像
Linux内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像,就相当于是一个root文件系统
-------------------------------------------------------------------------------------------------
Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,
还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。
-------------------------------------------------------------------------------------------------
分层存储:每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,额外东西应该在该层构建结束前清理掉
分层存储的特征还使得镜像的复用、定制变的更为容易。
甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
b.容器
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,
镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
-------------------------------------------------------------------------------------------------
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
-------------------------------------------------------------------------------------------------
容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。
-------------------------------------------------------------------------------------------------
一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,
我们可以称这个为容器运行时读写而准备的存储层为【容器存储层】。
-------------------------------------------------------------------------------------------------
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。
因此,任何保存于容器存储层的信息都会随容器删除而丢失。
c.数据卷
容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。
所有的文件写入操作,都应该使用【数据卷】或者【绑定宿主目录】,
在这些位置的【读写会跳过容器存储层】,直接对宿主(或网络存储)发生读写,其性能和稳定性更高
-------------------------------------------------------------------------------------------------
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。
因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
d.仓库
一个 Docker Registry 中可以包含多个 仓库(Repository);
每个仓库可以包含多个 标签(Tag);
每个标签对应一个镜像
-------------------------------------------------------------------------------------------------
Docker Registry 公开服务:开放给用户使用、允许用户管理镜像的 Registry 服务。
如:官方Docker Hub,Red Hat的Quay.io,Google的Google Container Registry,GitHub推出的ghcr.io
-------------------------------------------------------------------------------------------------
Docker Registry 私有服务:官方提供了 Docker Registry 镜像,不包含图形界面,以及镜像维护、用户管理等
如:官方Docker Registry,Harbor,Sonatype Nexus
e.核心组成模块
Docker的两个主要组成模块是: Docker Daemon 和 Docker CLI
Docker CLI:一个用来与 Docker 守护进程进行交互的 Docker 命令行客户端,也就是 Docker 命令
Docker Daemon:一个常驻的后台进程,帮助管理和创建 Docker 镜像、容器、网络和存储卷
Docker Engine REST API:一个应用程序用来与 Docker 守护进程进行交互的 API;通过 HTTP 客户端访问它
d.常见术语
a.Docker Engine
人们说“Docker”时,通常指的是Docker Engine,由Docker守护程序组成的客户端-服务器应用程序,指定用于与
守护程序交互的接口的REST API和与守护程序进行对话的命令行界面(CLI)客户端(通过REST API包装器)
Docker Enginedocker从CLI接受命令,例如 docker run <image>,docker ps列出正在运行的容器等
d.Docker Machine
Docker Machine 是一种在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机
c.Docker Compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具
Compose使用的三个步骤:
使用 Dockerfile 构建镜像的文本文件,定义应用程序的环境
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行
最后,执行 docker-compose up 命令来启动并运行整个应用程序
d.Docker Swarm
Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机
-------------------------------------------------------------------------------------------------
Docker Swarm 独立于Docker engine
需要额外的KV存储(也可以用Docker Hub的token)
没有服务模型
与Docker machine的集成
使用Docker CLI
Swarmkit 在Docker 1.12 RC之前,Docker 发布了 Swarmkit
这是一个独立的、开源的容器编排项目
使用自己的CLI(swarmd负责管理,swarmctl用于控制)
没有服务发现、负载均衡和路由功能
提供编排和调度服务
是Swarm mode的基础
Swarm mode 集成到了Docker engine中(docker swarm子命令)
不需要额外的KV存储
支持服务模型(及task概念)
支持扩容缩容、服务发现、滚动升级、路由和负载均衡
加密通信
还没有和Docker machine与Docker compose集成
使用Docker CLI
Swarm mode基于Swarmkit编写
-------------------------------------------------------------------------------------------------
总结:忘记Docker Swarm吧,知道有个Swarmkit,要用就用Docker Swarm Mode
e.Kubernetes
一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
由Google与RedHat公司共同主导的开源“容器编排”项目,它起源于Google公司的Borg系统。
打败了Docker推出的容器编排解决方案(Compose+Swarm),从而成为了容器编排领域事实上的标准。
02.Docker for windows
a.常用信息1
a.默认用户和密码
用户 密码 进入方式
docker tcuser ssh
root command:sudo -i (docker用户下执行)
b.环境变量
C:\ProgramData\DockerDesktop\version-bin
C:\Program Files\Docker\Docker\resources\bin
c.路径解读
C:\Users\mysla\.docker --配置+常见配置文件
C:\Program Files\Docker --安装
C:\ProgramData\DockerDesktop\ --配置
C:\Users\mysla\AppData\Roaming\Docker --配置
C:\Users\mysla\AppData\Local\Docker\wsl --WSL发行版默认位置
C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx --WSL运行数据、镜像文件
C:\Users\mysla\AppData\Local\Docker\wsl\distro\ext4.vhdx --WSL运行数据、镜像文件
b.常用信息2
a.服务
WSL进程:Vmmem.exe
注册名称:Docker Desktop Service
注册服务:C:\Program Files\Docker\Docker\com.docker.service
b.版本信息
Version 4.10.1(82475)
Engine 20.10.17
Compose v2.6.1
Credential Helper v0.6.4
Kubernetes v1.24.1
Snyk v1.827.0
-------------------------------------------------------------------------------------------------
CS Docker Engine 最版本已移除
Docker (1.13 and earlier) 最版本已移除
Docker Machine 最版本已移除
Docker Swarm (standalone) 最版本已移除
Docker Toolbox (legacy) 最版本已移除
Kitematic
c.扩展
Ambassador Telepresence Kubernetes:支持快速本地到远程开发和测试循环的工具
anchore 对images的内容和安全分析
Aqua Trivy 对远程或本地存储的images进行无限制的漏洞扫描。
Ddosify 高性能、开源、简单的负载测试工具
Disk Usage 查看Docker使用的磁盘空间 【安装】
Epinio 一键将Source端推送到Kubernetes
Gosh 使用 Docker 和 Git 构建分散且安全的软件供应链
JFrog 使用 JFrog Xray 扫描您的 Docker 映像以查找漏洞
Lacework Scanner 用于 Docker 桌面的 Lacework Scanner 集成
Lens 在 Docker 桌面上运行 Lens Kubernetes
Logs Explorer 在 Logs 查看所有容器日志,以便您进行调试 【安装】
Meshery 使用可扩展的设计和操作您的云原生部署
Okteto Docker Compose 的远程开发
OpenShift 将Docker镜像部署到OpenShift
Portainer Docker图形化界面 【安装】
Slim.Al Slim 让您能够更快地创建安全容器
Snyk Snyk Container 扩展使您能够扫描远程或本地images
Tailscale 虚拟组网工具,基于WireGuard
Uffizzi Uffizzi 让您可以从 Docker 在云中创建和管理全栈预览
VMware Tanzu Community Edition 将Kubernetes集群部署VMware Tanzu Community Edition
b.镜像存储位置
a.Linux
镜像: /var/lib/docker/image
容器: /var/lib/docker/containers
b.Mac
~/Library/Containers/com.docker.docker/Data/vms/0/~
c.Windows
C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx --WSL运行数据、镜像文件
C:\Users\mysla\AppData\Local\Docker\wsl\distro\ext4.vhdx --WSL运行数据、镜像文件
03.Docker根目录内部结构
a.根目录
/var/lib/docker为根目录,储存如下内容:容器数据、卷、构建文件、网络文件和集群数据
-----------------------------------------------------------------------------------------------------
$ ls -la /var/lib/docker
drwx------ 2 root root 4096 May 20 2019 builder
drwx------ 4 root root 4096 May 20 2019 buildkit
drwx------ 3 root root 4096 May 20 2019 containerd
drwx------ 2 root root 12288 Feb 3 19:35 containers --容器
drwx------ 3 root root 4096 May 20 2019 image --镜像
drwxr-x--- 3 root root 4096 May 20 2019 network
drwx------ 6 root root 77824 Feb 3 19:37 overlay2 --存储驱动
drwx------ 4 root root 4096 May 20 2019 plugins
drwx------ 2 root root 4096 Feb 1 13:09 runtimes
drwx------ 2 root root 4096 May 20 2019 swarm
drwx------ 2 root root 4096 Feb 3 19:37 tmp
drwx------ 2 root root 4096 May 20 2019 trust
drwx------ 15 root root 12288 Feb 3 19:35 volumes --卷
b.镜像(images)
最大的文件通常是镜像。默认overlay2存储驱动,镜像会保存在/var/lib/docker/overlay2
-----------------------------------------------------------------------------------------------------
$ docker image pull nginx
$ docker image inspect nginx
[
{
"Id": "sha256:207...6e1",
"RepoTags": [
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:ad5...c6f"
],
"Parent": "",
"Architecture": "amd64",
"Os": "linux",
"Size": 126698063,
"VirtualSize": 126698063,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/585...9eb/diff: --LowerDir只读层
/var/lib/docker/overlay2/585...9eb/diff",
"MergedDir": "/var/lib/docker/overlay2/585...9eb/merged",
"UpperDir": "/var/lib/docker/overlay2/585...9eb/diff",
"WorkDir": "/var/lib/docker/overlay2/585...9eb/work" --MergedDir运行容器
},
}
]
c.卷(Volumes)
持久化容器内的数据,容器和宿主机之间、容器和容器之间也可以通过共享卷来共享数据,即【卷=数据】
-----------------------------------------------------------------------------------------------------
$ docker run --name nginx_container -v /var/log nginx --通过-v参数,容器挂载卷
$ docker inspect nginx_container -查看挂载的卷的位置
"Mounts": [
{
"Type": "volume",
"Name": "1e4...d9c",
"Source": "/var/lib/docker/volumes/1e4...d9c/_data",
"Destination": "/var/log",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
04.VMware、WSL、Hyper-V、Dokcer兼容
a.Docker
a.Docker for windows两种运行方式
第一种,基于WSL2的Docker
第二种,基于Hyper-V的Docker
-------------------------------------------------------------------------------------------------
C:\Users\mysla>wsl -l -v
NAME STATE VERSION
* docker-desktop Stopped 2 --运行Docker引擎
docker-desktop-data Stopped 2 --存储容器和图像
b.说明
Docker Desktop与WSL2分发版本进行了集成,无需在WSL中安装docker;
当然,也可以选择不与Docker Desktop集成,直接在WSL中运行docker;
默认Docker for windows使用WSL2,如果不使用WSL2,手动【打开Docker设置】中更改为【Hyper-V虚拟机】运行
Docker -> Settings -> General -> Use the WSL 2 based engine
Docker -> Settings -> Resources -> WSL INTEGRATION -> Enable integration with my default WSL distro
-------------------------------------------------------------------------------------------------
启用或关闭Windows功能 -> 适用于Linux的Windows子系统 --开启WSL
启用或关闭Windows功能 -> Hyper-V --开启Hyper-V
启用或关闭Windows功能 -> 虚拟机平台 --开启Hyper-V
b.Vmware
a.说明
默认,VMware 15.x 与 WSL1 兼容
默认,VMware 15.x 与 WSL2 不兼容
默认,VMware 15.x 与 Hyper-V 不兼容
默认,WSL1、WSL2 与 Hyper-V 不兼容
-------------------------------------------------------------------------------------------------
默认,VMware 16 Pro 与 Hyper-V、WSL2 共存,无需任何设置
-------------------------------------------------------------------------------------------------
默认,虚拟化Intel VT-x/EPT或AMD-V/RVI(V) 与 Hyper-V 不兼容
默认,虚拟化CPU性能计数器(U) 与 Hyper-V 不兼容
默认,虚拟化IOMMU(O内存管理单元)(I) 与 Hyper-V 不兼容
b.解决方法
a.方法一
将WSL2降级成WSL1
b.方法二
启动哪个,输入哪个命令
bcdedit /set hypervisorlaunchtype off --启用VMware
bcdedit /set hypervisorlaunchtype auto --启用WSL
c.Vmware 15.x 兼容Hyper-v+WSL2+Docker,要求环境如下:
a.步骤1
Windows10(版本最低必须为19041)
下载好的 VMware Workstation Pro Tech Preview 20H1 版本(默认提供试用229天)
Windows10在BIOS中开启VT虚拟化
Intel Haswell or newer CPU 或者 AMD Bulldozer or newer CPU
b.步骤2
网站:https://docs.microsoft.com/zh-cn/windows/wsl/install-win10
问题:为什么不直接设置成【wsl --set-default-version 2】默认安装WSL2呢?
回答:上述造成报错【WslRegisterDistribution failed with error: 0x80370102】,必须WSL1升WSL2
---------------------------------------------------------------------------------------------
PS C:\Users\enen> wsl -l -v
NAME STATE VERSION
* Ubuntu-18.04 Running 1
---------------------------------------------------------------------------------------------
# 用管理员模式启动PowerShell然后运行
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
---------------------------------------------------------------------------------------------
# 这两个安装完成直接 重启 !!!!!!!!!重启!!!!!!
# 这里的<Distro>就是你安装的WSL1的名称
wsl --set-version <Distro> 2
wsl -l -v
c.步骤3
安装VMware20H1,开启Hyper-v后,创建启动一个虚拟机发现正常(Vmware 15.x 提示不兼容的)
c.WSL1 对比 WSL2
a.命令
wsl -l -v --查看WSL版本
wsl --list --online --列出可用的 Linux 发行版
wsl --list --verbose --列出已安装的 Linux 发行版
wsl --status --检查WSL状态
wsl --update --更新WSL
wsl -u <Username>`, `wsl --user <Username> --以特定用户的身份运行
<DistributionName> config --default-user <Username> --更改发行版的默认用户
-------------------------------------------------------------------------------------------------
wsl --set-default-version 2 --将WSL默认为【WSL2】,2代表WSL2
wsl --set-version Debian 1 --将WSL切换为【Debian+WSL1】
wsl --set-version Debian 2 --将WSL切换为【Debian+WSL2】
-------------------------------------------------------------------------------------------------
wsl --install -d Debian --安装该发行版
wsl --install -d Ubuntu-18.04 --安装该发行版
b.切换
wsl --list --查看WSL可更换默认版本
适用于 Linux 的 Windows 子系统分发版:
docker-desktop (默认)
docker-desktop-data
Debian
-------------------------------------------------------------------------------------------------
wsl --set-default docker-desktop --切换WSL默认为docker-desktop
wsl.exe --验证
c.WSL1
WSL 1用的是Windows内核模拟的各种系统接口。
虽然可以运行大部分Linux应用,但还是有不少依赖于内核的应用是无法正常运行的—,例如Docker。
WSL 1和Windows共用文件系统、网络,有些时候会比较头疼
-------------------------------------------------------------------------------------------------
WSL1没有Linux内核,不支持docker
d.WSL2
WSL 2/Docker本质上都是Hyper-V。WSL 2是一个轻量级的Hyper-V VM;
Docker for Windows如果要跑Linux镜像,安装运行一台运行Linux的Hyper-V虚拟机,用Hyper-V管理工具可以看到
-------------------------------------------------------------------------------------------------
WSL2是有Linux内核的轻量化虚拟机,支持docker,与WSL1不同的是,WSL2采用在Hyper-V虚拟机中运行的方案
WSL2 Docker和宿主机Win10共享network,宿主机Win10使用【localhost:端口号】来访问【Container中的服务】
05.报错汇总
a.报错1
报错:WSL 2 installation is incomplete.
解决:wsl2版本过老,需要手动更新【wsl_update_x64.msi】
b.报错2
报错:VMware出现Device Guard不相容错误
解决:第一步,更新版本以上,Windows10 2004 / build 19041.264、VMware Workstation 15.5.5
解决:第二步,VMware -> 虚拟化Intel VT-x/EPT或AMD-V/RVI(V)、 虚拟化CPU性能计数器(U) -> 关闭
c.报错3
报错:error during connect: This error may indicate that the docker daemon is not running
解决:cd "C:\Program Files\Docker\Docker" && DockerCli.exe -SwitchDaemon --第1步
解决:net stop com.docker.service --第2步
解决:net start com.docker.service --第3步
解决:Docker Desktop.exe --第4步
解决:Expose daemon on tcp://localhost:2375 without TLS --第5步(开启守护进程)
d.报错4
报错:vmmem进程占用内存情况为15.9/16GB,死循环尝试连接 -> 失败 -> 尝试连接
解决:wsl --shutdown
2.2 [1]install
00.Docker镜像
a.配置
https://docker.rainbond.cc
https://mirror.baidubce.com
https://hub-mirror.c.163.com
https://almtd3fa.mirror.aliyuncs.com
b.阿里云
https://6juphqlo.mirror.aliyuncs.com
-----------------------------------------------------------------------------------------------------
当前仅支持阿里云用户使用具备公网访问能力的阿里云产品进行镜像加速,且仅限于特定范围内的容器镜像。详情请见公告
c.2025-01-01
https://docker.hpcloud.cloud
https://docker.m.daocloud.io
https://docker.unsee.tech
https://docker.1panel.live
http://mirrors.ustc.edu.cn
https://docker.chenby.cn
http://mirror.azure.cn
https://dockerpull.org
https://dockerhub.icu
https://hub.rat.dev
https://proxy.1panel.live
https://docker.1panel.top
https://docker.m.daocloud.io
https://docker.1ms.run
https://docker.ketches.cn
01.Docker安装
a.方式一
a.安装所需的3个工具包(memory > 2G)
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
b.配置docker安装源
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
c.安装Engine-Community
sudo yum install docker-ce docker-ce-cli containerd.io
d.启动
systemctl start docker
e.自启
systemctl enable docker
b.方式二
yum update -y \
&& yum install docker -y \
&& systemctl start docker \
&& systemctl enable docker \
&& service docker status
c.方式三
curl -sSL https://get.docker.com/ | sh
curl -fsSL https://get.docker.com -o get-docker.sh && bash get-docker.sh
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
d.配置文件
a.daemon.json
C:\Users\mysla\.docker\daemon.json --打开文件
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"features": {
"buildkit": true
},
"registry-mirrors": [
"https://mirror.baidubce.com",
"https://hub-mirror.c.163.com",
"https://almtd3fa.mirror.aliyuncs.com"
]
}
-------------------------------------------------------------------------------------------------
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://docker.rainbond.cc"
]
}
-------------------------------------------------------------------------------------------------
vi /etc/docker/daemon.json
{
"data-root":"/data/docker",
"registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"]
}
-------------------------------------------------------------------------------------------------
systemctl daemon-reload --重新加载daemon.json文件
systemctl restart docker.service --重启docker服务
docker info --验证
b.wslconfig
C:\Users\mysla -> 新建文件(.wslconfig) --打开文件
-------------------------------------------------------------------------------------------------
[wsl2]
processors=4
memory=4GB
swap=4GB
localhostForwarding=true
-------------------------------------------------------------------------------------------------
wsl --shutdown --关闭当前的子系统
Docker Desktop --重启
02.Docker使用
a.常用命令1
C:\Windows\system32>wsl --shutdown --经测试,14.5GB -> 7.57GB
-----------------------------------------------------------------------------------------------------
docker login --登录DockerHub(myslayers)
docker logout --登出DockerHub(XXXXXXXXX)
-----------------------------------------------------------------------------------------------------
docker search activemq --搜索镜像
docker pull webcenter/activemq --拉取镜像
-----------------------------------------------------------------------------------------------------
docker tag mysql:5.7.27 myslayers/mysql:dev --设置标签
docker push myslayers/mysql:dev --推送镜像
-----------------------------------------------------------------------------------------------------
docker search myslayers/mysql --测试1
docker pull myslayers/mysql:dev --测试2
b.常用命令2
docker ps --container:运行
docker ps -a --container:运行、未运行
docker ps --no-trunc --container:查看command参数
docker images --images:全部
docker volume ls --volume:全部
-----------------------------------------------------------------------------------------------------
docker version --版本
docker info --配置
docker info | grep "Docker Root Dir" --配置,Docker存放位置
-----------------------------------------------------------------------------------------------------
docker start 80576e5ea74a --启动容器
docker stop 80576e5ea74a --停止容器
docker restart 80576e5ea74a --重启容器
docker rm 80576e5ea74a --移除容器
docker logs 80576e5ea74a --查看日志
docker inspect 80576e5ea74a --查看构建
docker port myslayers-mysql5 --查看端口
docker exec -it myslayers-prtainer /bin/bash --进入容器
c.清理空间
docker system df --查看Docker磁盘大致情况
docker system df -v --查看Docker磁盘详细情况
-----------------------------------------------------------------------------------------------------
docker container prune --清理,无用的container
docker image prune --清理,无用的image
docker volume prune --清理,无用的volume
docker system prune -a --删除,无用的镜像容器缓存【慎重】
-----------------------------------------------------------------------------------------------------
docker ps -a
docker rm -f 80576e5ea74a --移除容器,-f参数:强制删除
docker images
docker rmi -f d55229deb03e --移除镜像,-f参数:强制删除
docker volume ls
docker volume rm -f d55229deb03e --移除卷,-f参数:强制删除
-----------------------------------------------------------------------------------------------------
C:\Windows\system32>wsl --shutdown --经测试,14.5GB -> 7.57GB
C:\Windows\system32>diskpart
DISKPART> select vdisk file="C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx"
DISKPART> attach vdisk readonly --连接
DISKPART> compact vdisk --压缩
DISKPART> detach vdisk --断开
DISKPART> exit
-----------------------------------------------------------------------------------------------------
docker system df; \
docker kill $(docker ps -aq); \
docker rm $(docker ps -aq); \
docker rmi $(docker images -q); \
docker volume rm $(docker volume ls -q); \
docker system df
d.卸载docker
a.查看docker版本
yum list installed | grep docker
b.卸载docker版本
yum -y remove docker-ce.x86_64
yum -y remove containerd.io.x86_64
yum -y remove docker-ce-cli.x86_64
c.删除存储目录
rm -rf /etc/docker
rm -rf /run/docker
rm -rf /var/lib/dockershim
rm -rf /var/lib/docker
d.若发现删除,需要先进行umount操作
umount /var/lib/docker/devicemapper
e.设置容器开机自启动
a.开启
docker update --restart=always Portainer
b.关闭
docker update --restart=no Portainer
03.Docker Compose使用
a.安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
b.版本
[root@bigdata01 ~]# sudo chmod +x /usr/local/bin/docker-compose --授予当前用户执行权限
[root@bigdata01 ~]# docker-compose version --版本
docker-compose version 1.25.0, build 0a186604
docker-py version: 4.1.0
CPython version: 3.7.4
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
c.操作
docker search gitlab --查看gitlab镜像
docker pull gitlab/gitlab-ce:latest --拉取gitlab镜像
d.创建文件夹
[root@bigdata01 ~]# cd /usr/local
[root@bigdata01 local]# mkdir docker
[root@bigdata01 local]# cd docker/
[root@bigdata01 docker]# mkdir gitlab_docker
[root@bigdata01 docker]# cd gitlab_docker/
[root@bigdata01 gitlab_docker]# pwd
/usr/local/docker/gitlab_docker
e.创建docker-compose.yml文件
cd /usr/local/docker/gitlab_docker
vi docker-compose.yml
-----------------------------------------------------------------------------------------------------
version: '3.1'
services:
gitlab:
image: 'gitlab/gitlab-ce:latest'
container_name: gitlab
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.2.128:8929'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
ports:
- '8929:8929'
- '2224:2224'
volumes:
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
f.启动docker-compose
cd /usr/local/docker/gitlab_docker
docker-compose up -d --启动
docker-compose logs -f --日志
g.访问
http://192.168.2.128:8929 --访问
root
glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
h.获取默认密码
[root@bigdata01 gitlab_docker]# docker exec -it gitlab bash --进入容器
root@f48f17cf9d8a:/# cat /etc/gitlab/initial_root_password --查看密码
# WARNING: This value is valid only in the following conditions
# 1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
# 2. Password hasn't been changed manually, either via UI or via command line.
#
# If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.
Password: glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
root@f48f17cf9d8a:/#
i.修改密码
http://192.168.2.128:8929/-/profile/password/edit --修改密码
当前密码:glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
新密码:12345678
04.Docker数据卷
a.数据卷
a.介绍
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
数据卷可以在容器之间共享和重用
对数据卷的修改会立马生效
对数据卷的更新,不会影响镜像
数据卷默认会一直存在,即使容器被删除
-------------------------------------------------------------------------------------------------
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷,
并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。
b.命令
docker run -p 80:80 -v /data:/data -d nginx:latest --创建一个数据卷:-v(volume)
Mounts:/data/ --【√】,/data目录
-------------------------------------------------------------------------------------------------
docker inspect nginx --查看数据卷信息
-------------------------------------------------------------------------------------------------
docker exec -it nginx mkdir /mnt/web/test --方式一:不进入容器,新增数据
docker exec -it nginx /bin/bash --方式二:进入容器,新增数据
mkdir /mnt/web/test --方式二:进入容器,新增数据
c.同步性测试
a.本机文件可以同步到容器
在本机/tmp/data1目录中新建hello.txt文件
touch /tmp/data1/hello.txt
ls /tmp/data1/
hello.txt
---------------------------------------------------------------------------------------------
hello.txt文件在容器/tmp/data2/目录中可见
docker exec test ls /tmp/data2/
hello.txt
---------------------------------------------------------------------------------------------
可知,在本机目录/tmp/data1/的修改,可以同步到容器目录/tmp/data2/中
b.容器文件可以同步到主机
在容器/tmp/data2目录中新建world.txt文件
docker exec test touch /tmp/data2/world.txt
docker exec test ls /tmp/data2/
hello.txt
world.txt
---------------------------------------------------------------------------------------------
world.txt文件在主机/tmp/data1/目录中可见
ls /tmp/data1/
hello.txt world.txt
---------------------------------------------------------------------------------------------
可知,在容器目录/tmp/data2/的修改,可以同步到主机目录/tmp/data1/中
b.数据卷容器
a.介绍
如果你有一些【持续更新的数据】需要在容器之间【共享】,最好创建数据卷容器。
数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
b.命令
docker run -d -v /dbdata --name dbdata training/postgres --【√】,/var/lib/docker随机目录
Mounts:/var/lib/docker/volumes/0b0968dcb12f39/_data
docker run -d -v workspace_data:/dbdata --name dbdata training/postgres
Mounts:/var/lib/docker/volumes/workspace_data/_data --【√】,/var/lib/docker指定目录
-------------------------------------------------------------------------------------------------
docker run -d -v /workspace_data:/dbdata --name dbdata training/postgres
Mounts:无 --【√】,/workspace_data目录
docker run -d -v /root/test:/dbdata --name dbdata training/postgres
Mounts:/root/test --【√】,/root/test目录
-------------------------------------------------------------------------------------------------
docker run -d --volumes-from dbdata --name db1 training/postgres --创建db1容器,从dbdata挂载
docker run -d --volumes-from dbdata --name db2 training/postgres --创建db2容器,从dbdata挂载
docker run -d --volumes-from dbdata --name db3 training/postgres --创建db3容器,从dbdata挂载
c.备份、恢复
a.备份
docker run -itd --name nginx -v web:/mnt/web nginx --挂载卷web:/mnt/web
Mounts:/var/lib/docker/volumes/web/_data
-------------------------------------------------------------------------------------------------
docker volume ls --查看卷web
DRIVER VOLUME NAME
local web
-------------------------------------------------------------------------------------------------
docker exec -it nginx /bin/bash --进入容器
root@826f13832ca6:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
root@826f13832ca6:/mnt/web# ls
TODO1.txt TODO2.txt TODO3.txt
-------------------------------------------------------------------------------------------------
docker run -it \
--volumes-from nginx \
-v /root/test:/backup \
nginx \
tar cvf /backup/web.tar /mnt/web --备份
---------------------------------------------------------------------------------------------
nginx基础镜像新建一个临时的容器(不放入后台运行,但会【随机创建类似exciting_ride的容器】)
数据共享容器nginx的数据卷web
-v 指定将本机的/root/test目录挂载到临时容器的/backup目录
tar 执行备份命令将临时容器的/mnt/web目录打包压缩到/backup目录下名为web.tar的备份文件
---------------------------------------------------------------------------------------------
①数据卷web挂载到了nginx容器的/mnt/web目录
②而临时容器又共享了nginx容器的数据卷web,因此直接打包容器的/mnt/web目录
③本机的/root/test目录挂载到了临时容器的/backup目录
所以,直接在本机的/root/test目录中查找备份文件web.tar
---------------------------------------------------------------------------------------------
映射关系:/root/test 映射 /backup
/backup/web.tar 备份 /mnt/web文件夹
/mnt/web文件夹 对应 共享数据卷web
b.恢复
docker run -itd --name nginxback -v webdata:/mnt/web nginx
--用nginx基础镜像新启动一个带有【空数据卷webdata】的【容器nginxback】
-------------------------------------------------------------------------------------------------
docker volume ls --查看卷web
DRIVER VOLUME NAME
local web
local webdata(恢复卷)
-------------------------------------------------------------------------------------------------
docker exec -it nginxback /bin/bash --进入容器
root@826f13832ca6:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
root@826f13832ca6:/mnt/web# ls
无
-------------------------------------------------------------------------------------------------
docker run -it \
--volumes-from nginxback \
-v /root/test:/backup \
nginx \
tar xvf /backup/web.tar --恢复
---------------------------------------------------------------------------------------------
nginx基础镜像新建一个临时的容器(不放入后台运行,但会【随机创建类似exciting_ride的容器】)
数据共享容器nginxback的数据卷webdata(作用是将web.tar文件数据恢复至数据卷webdata)
-v 指定将本机的/root/test目录挂载到临时容器的/backup目录
tar 将临时容器的/backup目录下名为web.tar的备份文件恢复至nginxback容器的数据卷webdata
---------------------------------------------------------------------------------------------
①数据卷web挂载到了nginx容器的/mnt/web目录
②而临时容器又共享了nginx容器的数据卷web,因此直接打包容器的/mnt/web目录
③本机的/root/test目录挂载到了临时容器的/backup目录
所以,直接在本机的/root/test目录中查找备份文件web.tar
---------------------------------------------------------------------------------------------
映射关系:/root/test 映射 /backup
/backup/web.tar 备份 /mnt/web文件夹
/mnt/web文件夹 对应 共享数据卷web
c.验证
a.验证nginxback是否与nginx数据卷一致
root@debian01:~# docker exec -it nginx ls /mnt/web --原nginx
TODO1.txt TODO2.txt TODO3.txt
root@debian01:~# docker exec -it nginxback ls /mnt/web --现nginx
TODO1.txt TODO2.txt TODO3.txt
b.为了验证web数据卷备份恢复到webdata数据卷的数据,再启动一个新容器挂载webdata数据卷查看数据
root@debian01:~# docker run -itd --name nginxtest -v webdata:/mnt/web nginx
f7b57a0a6ce82f078bba4cf9011d000ba1bf15c7d1994b2b69588e929ecd8abc
root@debian01:~# docker exec -it nginxtest ls /mnt/web --新nginx
TODO1.txt TODO2.txt TODO3.txt
d.MySQL的备份与恢复
a.mysql容器
docker run -itd --name myslayers-mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=4033665 \
-v /docker/mysql/data/:/var/lib/mysql/ \
-v /docker/mysql/conf.d:/etc/mysql/conf.d \
-v mysql8_data:/var/lib/mysql \
mysql:latest
-------------------------------------------------------------------------------------------------
docker exec -it myslayers-mysql8 /bin/bash --进入容器
mysql -u root -p --测试(用户root密码4033665)
b.备份
docker run -it \
--volumes-from myslayers-mysql8 \
-v /root/test:/backup \
mysql \
tar cvf /backup/test.tar /var/lib/mysql
c.mysql_back容器
docker run -itd \
--name mysql_back \
-e MYSQL_ROOT_PASSWORD=4033665 \
-v mysql8_data_back:/var/lib/mysql \
mysql:latest
d.恢复
docker run -it \
--volumes-from mysql_back \
-v /root/test:/backup \
mysql \
tar xvf /backup/test.tar -C /var/lib/mysql
05.Docker制作镜像
a.方式一:从已经创建的容器中更新镜像,并提交这个镜像
docker run -t -i ubuntu:15.10 /bin/bash --进入容器
-----------------------------------------------------------------------------------------------------
docker commit -m="has update" -a="myslayers" e218edb10161 runoob/ubuntu:v2 --更新镜像
-m: 提交的描述信息
-a: 指定镜像作者
e218edb10161:容器 ID
runoob/ubuntu:v2: 指定要创建的目标镜像名
-----------------------------------------------------------------------------------------------------
docker images --查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
runoob/ubuntu v2 70bf1840fd7c 15 seconds ago 158.5 MB
-----------------------------------------------------------------------------------------------------
docker tag mysql:5.7.27 myslayers/mysql:dev --设置标签
docker push myslayers/mysql:dev --推送镜像
-----------------------------------------------------------------------------------------------------
docker search myslayers/mysql --测试1
docker pull myslayers/mysql:dev --测试2
b.方式二:使用 Dockerfile 指令来创建一个新的镜像
cat Dockerfile --查看Dockerfile
-----------------------------------------------------------------------------------------------------
FROM centos:6.7
MAINTAINER Fisher "[email protected] "
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
-----------------------------------------------------------------------------------------------------
docker build -t runoob/centos:6.7 . --build构建镜像
-t :指定要创建的目标镜像名
. :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
-----------------------------------------------------------------------------------------------------
docker images --查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
runoob/centos 6.7 860c279d2fec About a minute ago 190.6 MB
-----------------------------------------------------------------------------------------------------
docker tag mysql:5.7.27 myslayers/mysql:dev --设置标签
docker push myslayers/mysql:dev --推送镜像
-----------------------------------------------------------------------------------------------------
docker search myslayers/mysql --测试1
docker pull myslayers/mysql:dev --测试2
2.3 [1]backup
01.Docker备份
a.Windows
a.位置
C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx --WSL运行数据、镜像文件
C:\Users\mysla\AppData\Local\Docker\wsl\distro\ext4.vhdx --WSL运行数据、镜像文件
b.docker-desktop-data 对应 data
# 停止docker,在任务栏中手动停止
# data文件夹下的ext4.vhdx为1.12GB
# 导出 docker-desktop-data
wsl --export docker-desktop-data "D:\\docker-desktop-data.tar"
# 注销 docker-desktop-data
wsl --unregister docker-desktop-data
# 导入 docker-desktop
wsl --import docker-desktop-data "F:\\docker\\wsl\\data" "D:\\docker-desktop-data.tar" --version 2
c.docker-desktop 对应 distro
# 停止docker,在任务栏中手动停止
# distro文件夹下的ext4.vhdx为127MB
# 导出 docker-desktop
wsl --export docker-desktop "D:\\docker-desktop.tar"
# 注销 docker-desktop
wsl --unregister docker-desktop
# 导入 docker-desktop
wsl --import docker-desktop "F:\\docker\\wsl\\distro" "D:\\docker-desktop.tar" --version 2
d.切换WSL
C:\Users\mysla> wsl --list --查看WSL可更换默认版本
适用于 Linux 的 Windows 子系统分发版:
docker-desktop (默认)
docker-desktop-data
Debian
-------------------------------------------------------------------------------------------------
C:\Users\mysla> wsl --set-default docker-desktop --切换WSL默认为docker-desktop
C:\Users\mysla> wsl --list --验证
wsl.exe --验证
b.Linux
a.总结
a.三组命令
sava与load
export与import
checkpoint与reestore
b.文件大小不同
export 导出的镜像文件体积小于 save 保存的镜像
c.是否可以对镜像重命名
docker import 可以为镜像指定新名称
docker load 不能对载入的镜像重命名
d.是否可以同时将多个镜像打包到一个文件中
docker export 不支持
docker save 支持
e.是否包含镜像历史
docker import 是根据容器拿到的镜像,可以【给容器数据打快照】,推荐
docker save 直接根据镜像来进行报错,无法【给数据打快照】
若是只想备份images,使用save、load即可
若是在启动容器后,容器内容有变化,需要备份,则使用export、import
b.sava-load
a.操作1
docker save mysql:5.7.27 > mysql_5.7.27.tar --save:导出镜像(单个)
docker load < /root/mysql_5.7.27.tar --load:导入镜像(单个)
b.操作2
docker save mysql:5.7.27 mysql:latest > mysql_5.7.27_latest.tar --save:导出镜像(多个合并为单个)
docker save -o mysql_5.7.27_latest.tar mysql:5.7.27 mysql:latest--save:导出镜像(多个合并为单个)
docker load < /root/mysql:5.7.27_latest.tar --load:导入镜像(多个合并为单个)
c.运行image为container
末尾无需跟参数:【docker ps --no-trunc -> COMMAND】
docker run -itd --name myslayers-mysql5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=4033665 mysql:5.7.25
c.export-import
a.操作
docker export myslayers-mysql5 > mysql_5.7.27.tar --export:容器导出镜像(仅单个)
docker import - mysql:5.7.27 < mysql_5.7.27.tar --import:导入镜像(仅单个)
b.运行image为container
末尾必须跟参数:【docker ps --no-trunc -> COMMAND】
docker run -itd --name myslayers-mysql5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=4033665 mysql:5.7.27 docker-entrypoint.sh mysqld
d.批量脚本
a.镜像的批量导出
#!/bin/bash
# 获取到 "image:tag" 格式的镜像名
IMG_NAME=`docker images | grep -v TAG | awk '{print $1":"$2}'`
# 定义镜像存放目录
DIR="/data/docker/image_tar"
if [ ! -d "$DIR" ]; then
echo -e "\033[34m${DIR}\033[0m 不存在"
mkdir -p "$DIR"
echo -e "\033[34m${DIR}\033[0m 已创建"
else
echo -e "\033[34m${DIR}\033[0m 已存在"
fi
echo ""
for IMAGE in $IMG_NAME
do
echo -e "正在保存 \033[33m${IMAGE}\033[0m"
SAVE_NAME=`echo $IMAGE | awk -F: '{print $1"_"$2}' | sed 's/\//_/g'`
docker save $IMAGE -o ${DIR}/${SAVE_NAME}.tar
echo -e "已保存到 \033[34m${DIR}/\033[31m${SAVE_NAME}.tar\033[0m"
echo ""
done
b.镜像的批量导入
for i in `ls /data/docker/image_tar/*`;do docker load <$i;done
02.Docker释放
a.查看Docker大小
$ cd /var/lib/docker
$ du -h --max-depth=1 * --当前目录下各文件、文件夹的大小
$ du -h --max-depth=0 * --子目录文件及文件夹大小统计
$ du –sh --查看指定目录的总大小
-----------------------------------------------------------------------------------------------------
docker system df --查看Docker磁盘使用情况
docker system df -v --查看Docker磁盘详细情况
-----------------------------------------------------------------------------------------------------
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 376.1MB 0B (0%)
Containers 1 1 63B 0B (0%)
Local Volumes 1 1 43.39MB 0B (0%)
Build Cache 0 0 0B 0B
b.清理Docker空间
docker system df --查看Docker磁盘使用情况
docker container prune --清理,无用的container
docker image prune --清理,无用的image
docker volume prune --清理,无用的volume
docker system prune -a --删除,无用的镜像容器缓存【慎重】
-----------------------------------------------------------------------------------------------------
docker system df --查看Docker磁盘使用情况
docker ps -a
docker ps --no-trunc
docker rm -f 80576e5ea74a --移除容器,-f参数:强制删除
docker images
docker rmi -f d55229deb03e --移除镜像,-f参数:强制删除
docker volume ls
docker volume rm -f d55229deb03e --移除卷,-f参数:强制删除
-----------------------------------------------------------------------------------------------------
docker system df --查看Docker磁盘使用情况
docker kill $(docker ps -aq) --清除全部文件,包括正在运行
docker rm $(docker ps -aq)
docker rmi $(docker images -q)
docker volume rm $(docker volume ls -q)
-----------------------------------------------------------------------------------------------------
docker system df --查看Docker磁盘使用情况
docker rm $(docker ps -aq) --保留正在运行的XXX,其他全部清除
docker rmi $(docker images -q)
docker volume rm $(docker volume ls -q)
c.清理WSL空间
a.说明
WSL2使用虚拟硬盘(VHD)存储linux下的文件,最大限制256G
但是,在Linux中减少文件占用,WSL却没有相应的减少硬盘空间的占用,需要手动释放这部分空间
b.操作
C:\Windows\system32>wsl --shutdown --经测试,14.5GB -> 7.57GB
C:\Windows\system32>diskpart
DISKPART> select vdisk file="C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx"
DISKPART> attach vdisk readonly --连接
DISKPART> compact vdisk --压缩
DISKPART> detach vdisk --断开
DISKPART> exit
d.卸载docker
a.查看docker版本
yum list installed | grep docker
b.卸载docker版本
yum -y remove docker-ce.x86_64
yum -y remove containerd.io.x86_64
yum -y remove docker-ce-cli.x86_64
c.删除存储目录
rm -rf /etc/docker
rm -rf /run/docker
rm -rf /var/lib/dockershim
rm -rf /var/lib/docker
d.若发现删除,需要先进行umount操作
umount /var/lib/docker/devicemapper
03.Docker扩容
a.方式一:软链接
a.说明
挂载新的分区到该目录,在原有系统空间不变的情况下,采用【软链接:修改镜像和容器的存放路径】的方式
b.操作
systemctl stop docker --停掉Docker服务
mv /var/lib/docker /data/docker --移动
ln -sf /data/docker /var/lib/docker --软链接(显示/var/lib/docker,实际/data/docker)
b.方式二:docker.service
a.修改
vi /etc/default/docker --配置文件(Ubuntu 18)
vi /usr/lib/systemd/system/docker.service --配置文件(CentOS 7)
配置如下:
ExecStart=/usr/bin/dockerd --graph="/data/docker"--说明 --graph 指定镜像和容器存放路径
b.修改daemon.json
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
"graph": "/data/docker"
}
c.重启
systemctl daemon-reload --重新加载daemon.json文件
systemctl restart docker.service --重启docker服务
docker info | grep "Docker Root Dir" --配置,Docker存放位置
c.方式三:docker.service.d 文件夹下的 docker.conf
a.修改
mkdir /etc/systemd/system/docker.service.d/ --默认 docker.service.d 文件夹不存在
配置如下:
$ sudo vi /etc/systemd/system/docker.service.d/docker.conf
[Service]
ExecStart=/usr/bin/dockerd --graph="/data/docker" --storage-driver=devicemapper --参数覆盖
b.修改daemon.json
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
"graph": "/data/docker"
}
c.重启
systemctl daemon-reload --重新加载daemon.json文件
systemctl restart docker.service --重启docker服务
docker info | grep "Docker Root Dir" --配置,Docker存放位置
2.4 [1]network
01.介绍
a.回送地址
默认:192.168.65.0/28
说明:127.0.0.1也称为回送地址,因为它连接到本地系统而不是远程系统上。
IP地址范围127.0.0.1/8已完全注册用于回送,这意味着在127.0.0.1 – 127.0.1.255之间注册了环回接口
b.Docker端口映射
端口映射可使用-p、-P来实现:
-p指定要映射的端口,一个指定端口上只可以绑定一个容器
-P将容器内部开放的网络端口随机映射到宿主机的一个端口上
-----------------------------------------------------------------------------------------------------
默认情况下 -p 和 -P 绑定的都是 tcp 协议端口
如果要绑定 udp 协议端口,只能使用 -p 参数,且在最后添加 /udp 字符串
如:docker run -d -p 127.0.0.1:5553:5000/udp jcdemo/flaskapp
-----------------------------------------------------------------------------------------------------
多次使用 -p 参数可以映射多个端口
如:docker run -d -p 5552:5000 -p 5551:5001 jcdemo/flaskapp
端口映射支持的格式:
ip:hostport:containerport #指定ip、指定宿主机port、指定容器port
ip::containerport #指定ip、未指定宿主机port(随机)、指定容器port
hostport:containerport #未指定ip、指定宿主机port、指定容器port
-----------------------------------------------------------------------------------------------------
端口的映射有以下五种方法:
方法一:将容器暴露的所有端口,都随机映射到宿主机上(不推荐使用)
docker run -P -it ubuntu /bin/bash
方法二:将容器指定端口随机映射到宿主机一个端口上
docker run -P 80 -it ubuntu /bin/bash
方法三:将容器指定端口指定映射到宿主机的一个端口上
docker run -p 8000:80 -it ubuntu /bin/bash --将容器的80端口映射到宿主机的8000端口
方法四:将容器ip和端口,随机映射到宿主机上
docker run -P 192.168.0.100::80 -it ubuntu /bin/bash
方法五:将容器ip和端口,指定映射到宿主机上
docker run -p 192.168.0.100:8000:80 -it ubuntu /bin/bash
02.设置固定ip地址
a.说明
a.默认
说明:使用默认bridge网络进行固定IP地址创建时会报错,只有在自定义halavah网络下才可设置固定IP
示例:docker run -itd --net bridge --ip 172.17.0.10 nginx:latest /bin/bash
报错:user specified IP address is supported on user defined networks only.
-------------------------------------------------------------------------------------------------
说明:只允许一个“主机”网络实例
报错:only one instance of "host" network is allowed
b.分类
a.bridge:桥接网络
默认情况下启动的Docker容器,都是使用bridge,Docker安装时创建的桥接网络,
每次Docker容器重启时,会按照顺序获取对应的IP地址,这个就导致重启下,Docker的IP地址就变了
b.none:无指定网络
使用--network=none,容器就不会分配局域网的IP
c.host:主机网络
使用--network=host,Docker容器的网络会附属在主机上,两者是互通的
例如,在容器中运行一个Web服务,监听8080端口,则主机的8080端口就会自动映射到容器中
b.系统进程
a.Windows
ipconfig --查看IPV4
netstat -ano --查看全部端口
netstat -aon|findstr 135 --查看某个端口
taskkill -f -pid 135 --删除某个端口
tasklist|findstr 12088 --根据pid查看应用程序
b.Centos
ip a / ip addr / ip address --查看IPV4
hostname -I --查看IPV4
install net-tools && ifconfig -a --查看IPV4
-------------------------------------------------------------------------------------------------
ps --查看全部进程
pkill -9 python --结束name为python的全部进程
-------------------------------------------------------------------------------------------------
netstat -nap --查看正常使用的端口以及关联的进程
netstat -ntulp | grep 8080 --查看8080端口
lsof -i 8080 --查看8080端口
ps [pid] --查看8080端口对应的pid进程
kill -9 [pid] --关闭8080端口对应的pid进程
c.操作
a.汇总
docker network connect --将容器连接到网络
docker network create --创建一个网络
docker network disconnect --断开容器的网络
docker network inspect --显示一个或多个网络的详细信息
docker network ls --列出网络
docker network prune --删除所有未使用的网络
docker network rm --删除一个或多个网络
-------------------------------------------------------------------------------------------------
--driver host --driver指定类型
--subnet=192.168.3.0/16 --subnet指定ip段
--gateway=192.168.3.1 --gateway指定网关
--network halavah --ip 172.17.0.10 --network指定网络类型
b.查看
$ docker network ls
c.增加+创建绑定
docker network create \
--subnet=192.168.3.0/16 \
--gateway=192.168.3.1 \
halavah --创建halavah网络
-------------------------------------------------------------------------------------------------
docker network inspect halavah --查看halavah网络
-------------------------------------------------------------------------------------------------
docker run -itd \
--name nginx01 \
--network halavah \
--ip 192.168.3.128 \
nginx --绑定nginx01容器
docker inspect nginx01 | grep -i “network” --查看nginx01网络
-------------------------------------------------------------------------------------------------
docker run -itd \
--name nginx02 \
--network halavah \
--ip 192.168.3.129 \
nginx --绑定nginx02容器
docker inspect nginx02 | grep -i “network” --查看nginx02网络
d.删除
$ docker network rm halavah
e.更改
docker network disconnect halavah nginx01 --解除容器(nginx01)绑定网络
docker network rm halavah --删除原先的网络
-------------------------------------------------------------------------------------------------
docker network create --subnet=192.168.3.0/16 myslayers --重新创建容器网络
docker network connect myslayer test01 --为容器重新指定网络
docker container restart test01 --重新启动容器
03.容器访问
a.外部访问容器
a.端口映射基础
基本语法:
docker run -p 宿主机端口:容器端口 镜像名 --映射指定端口
docker run -P 镜像名 --随机映射所有暴露端口
-------------------------------------------------------------------------------------------------
示例1:映射单个端口
docker run -d -p 8080:80 nginx --宿主机8080映射到容器80
-------------------------------------------------------------------------------------------------
示例2:指定IP绑定
docker run -d -p 127.0.0.1:8080:80 nginx --只允许本机访问
docker run -d -p 192.168.1.10:8080:80 nginx --指定IP访问
-------------------------------------------------------------------------------------------------
查看端口映射:
docker port 容器名/ID --查看容器端口映射
docker ps --查看所有容器端口映射
b.多端口映射
映射多个端口:
docker run -d \
-p 8080:80 \
-p 8443:443 \
nginx --同时映射80和443端口
-------------------------------------------------------------------------------------------------
映射端口范围:
docker run -d -p 8000-8010:8000-8010 myapp --映射端口段
c.指定协议
TCP协议(默认):
docker run -d -p 8080:80/tcp nginx --TCP协议
-------------------------------------------------------------------------------------------------
UDP协议:
docker run -d -p 5353:53/udp bind9 --UDP协议
-------------------------------------------------------------------------------------------------
同时映射TCP和UDP:
docker run -d \
-p 8080:80/tcp \
-p 5353:53/udp \
myapp
d.动态端口映射
使用-P参数自动映射:
docker run -d -P nginx --自动映射所有EXPOSE端口
-------------------------------------------------------------------------------------------------
查看映射的端口:
docker port 容器ID --查看具体映射
-------------------------------------------------------------------------------------------------
示例输出:
80/tcp -> 0.0.0.0:32768
443/tcp -> 0.0.0.0:32769
e.访问测试
本机访问:
curl http://localhost:8080 --访问映射的端口
-------------------------------------------------------------------------------------------------
远程访问:
curl http://服务器IP:8080 --从其他机器访问
-------------------------------------------------------------------------------------------------
检查端口监听:
netstat -tlnp | grep 8080 --查看端口监听状态
ss -tlnp | grep 8080 --使用ss命令查看
b.容器互联
a.默认bridge网络
同一网络下的容器可以互相通信:
docker run -d --name web1 nginx --创建容器1
docker run -d --name web2 nginx --创建容器2
-------------------------------------------------------------------------------------------------
容器间通信:
docker exec web1 ping web2 --通过容器名ping(需要自定义网络)
docker exec web1 ping 172.17.0.3 --通过IP ping
b.自定义网络互联
创建自定义网络:
docker network create mynet --创建网络
docker network create --subnet=172.20.0.0/16 mynet --指定子网
-------------------------------------------------------------------------------------------------
使用自定义网络:
docker run -d --name web1 --network mynet nginx --加入mynet网络
docker run -d --name web2 --network mynet nginx --加入mynet网络
-------------------------------------------------------------------------------------------------
容器间通信:
docker exec web1 ping web2 --直接通过容器名通信
docker exec web1 curl http://web2 --HTTP访问
c.网络别名
为容器设置别名:
docker run -d --name web1 --network mynet --network-alias webapp nginx
-------------------------------------------------------------------------------------------------
通过别名访问:
docker exec web2 ping webapp --使用别名访问
d.连接多个网络
将容器连接到多个网络:
docker network create net1 --创建网络1
docker network create net2 --创建网络2
-------------------------------------------------------------------------------------------------
docker run -d --name web1 --network net1 nginx --容器加入net1
docker network connect net2 web1 --同时连接到net2
-------------------------------------------------------------------------------------------------
查看容器网络:
docker inspect web1 | grep -i network --查看网络配置
e.容器link(已废弃)
传统link方式(不推荐):
docker run -d --name db mysql --创建数据库容器
docker run -d --name web --link db:database nginx --link到db容器
-------------------------------------------------------------------------------------------------
环境变量传递:
docker exec web env | grep DATABASE --查看注入的环境变量
-------------------------------------------------------------------------------------------------
推荐使用:建议使用自定义网络替代link
f.跨主机容器通信
使用overlay网络(Docker Swarm):
docker network create --driver overlay myoverlay --创建overlay网络
docker service create --name web --network myoverlay nginx --创建服务
-------------------------------------------------------------------------------------------------
使用macvlan网络:
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 macvlan_net --创建macvlan网络
04.数据管理
a.数据卷(Volume)
a.创建和使用数据卷
创建数据卷:
docker volume create mydata --创建名为mydata的卷
-------------------------------------------------------------------------------------------------
挂载数据卷:
docker run -d --name web -v mydata:/usr/share/nginx/html nginx --挂载到容器
-------------------------------------------------------------------------------------------------
匿名卷:
docker run -d -v /usr/share/nginx/html nginx --自动创建匿名卷
b.查看数据卷信息
docker volume ls --列出所有卷
docker volume inspect mydata --查看卷详细信息
-------------------------------------------------------------------------------------------------
输出示例:
[
{
"CreatedAt": "2023-12-16T10:00:00Z",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/mydata/_data",
"Name": "mydata"
}
]
c.删除数据卷
docker volume rm mydata --删除指定卷
docker volume prune --删除所有未使用的卷
-------------------------------------------------------------------------------------------------
强制删除:
docker volume rm -f mydata --强制删除
d.数据卷容器
创建数据卷容器:
docker run -d --name datastore -v /data busybox --创建数据容器
-------------------------------------------------------------------------------------------------
其他容器使用:
docker run -d --name web1 --volumes-from datastore nginx --共享数据卷
docker run -d --name web2 --volumes-from datastore nginx --共享数据卷
-------------------------------------------------------------------------------------------------
多个容器共享同一数据卷
b.绑定挂载(Bind Mount)
a.挂载主机目录
基本挂载:
docker run -d -v /host/path:/container/path nginx --挂载主机目录
-------------------------------------------------------------------------------------------------
实例:
docker run -d -v /data/nginx:/usr/share/nginx/html nginx --挂载网站目录
docker run -d -v /var/logs:/var/log/nginx nginx --挂载日志目录
b.挂载单个文件
docker run -d -v /host/nginx.conf:/etc/nginx/nginx.conf:ro nginx --挂载配置文件
-------------------------------------------------------------------------------------------------
注意:挂载文件时建议使用绝对路径
c.只读挂载
docker run -d -v /data:/data:ro nginx --只读挂载
docker run -d -v /data:/data:rw nginx --读写挂载(默认)
d.挂载权限问题
设置权限:
chmod 755 /host/path --修改主机目录权限
chown -R 1000:1000 /host/path --修改所有者
-------------------------------------------------------------------------------------------------
容器内指定用户:
docker run -d --user 1000:1000 -v /data:/data nginx --指定运行用户
c.tmpfs挂载
a.tmpfs基本使用
docker run -d --tmpfs /tmp nginx --创建tmpfs挂载
docker run -d --tmpfs /tmp:rw,size=100m nginx --指定大小和权限
b.tmpfs应用场景
存储临时文件
存储敏感信息(重启后自动清除)
需要高速读写的场景
d.数据备份和恢复
a.备份数据卷
docker run --rm -v mydata:/data -v $(pwd):/backup busybox \
tar czf /backup/mydata-backup.tar.gz /data --备份数据卷
b.恢复数据卷
docker run --rm -v mydata:/data -v $(pwd):/backup busybox \
tar xzf /backup/mydata-backup.tar.gz -C / --恢复数据卷
c.容器间数据迁移
导出数据:
docker run --rm -v olddata:/from -v newdata:/to busybox \
cp -av /from/. /to --复制数据到新卷
2.5 [2]terminal
00.汇总
a.镜像
Linux内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像,就相当于是一个root文件系统
-------------------------------------------------------------------------------------------------
Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,
还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。
-------------------------------------------------------------------------------------------------
分层存储:每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,额外东西应该在该层构建结束前清理掉
分层存储的特征还使得镜像的复用、定制变的更为容易。
甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
b.容器
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,
镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
-------------------------------------------------------------------------------------------------
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
-------------------------------------------------------------------------------------------------
容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。
-------------------------------------------------------------------------------------------------
一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,
我们可以称这个为容器运行时读写而准备的存储层为【容器存储层】。
-------------------------------------------------------------------------------------------------
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。
因此,任何保存于容器存储层的信息都会随容器删除而丢失。
c.数据卷
容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。
所有的文件写入操作,都应该使用【数据卷】或者【绑定宿主目录】,
在这些位置的【读写会跳过容器存储层】,直接对宿主(或网络存储)发生读写,其性能和稳定性更高
-------------------------------------------------------------------------------------------------
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。
因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
d.仓库
一个 Docker Registry 中可以包含多个 仓库(Repository);
每个仓库可以包含多个 标签(Tag);
每个标签对应一个镜像
-------------------------------------------------------------------------------------------------
Docker Registry 公开服务:开放给用户使用、允许用户管理镜像的 Registry 服务。
如:官方Docker Hub,Red Hat的Quay.io,Google的Google Container Registry,GitHub推出的ghcr.io
-------------------------------------------------------------------------------------------------
Docker Registry 私有服务:官方提供了 Docker Registry 镜像,不包含图形界面,以及镜像维护、用户管理等
如:官方Docker Registry,Harbor,Sonatype Nexus
e.核心组成模块
Docker的两个主要组成模块是: Docker Daemon 和 Docker CLI
Docker CLI:一个用来与 Docker 守护进程进行交互的 Docker 命令行客户端,也就是 Docker 命令
Docker Daemon:一个常驻的后台进程,帮助管理和创建 Docker 镜像、容器、网络和存储卷
Docker Engine REST API:一个应用程序用来与 Docker 守护进程进行交互的 API;通过 HTTP 客户端访问它
01.常用信息1
a.常用命令1
C:\Windows\system32>wsl --shutdown --经测试,14.5GB -> 7.57GB
-----------------------------------------------------------------------------------------------------
docker login --登录DockerHub(myslayers)
docker logout --登出DockerHub(XXXXXXXXX)
-----------------------------------------------------------------------------------------------------
docker search activemq --搜索镜像
docker pull webcenter/activemq --拉取镜像
-----------------------------------------------------------------------------------------------------
docker tag mysql:5.7.27 myslayers/mysql:dev --设置标签
docker push myslayers/mysql:dev --推送镜像
-----------------------------------------------------------------------------------------------------
docker search myslayers/mysql --测试1
docker pull myslayers/mysql:dev --测试2
b.常用命令2
docker ps --container:运行
docker ps -a --container:运行、未运行
docker ps --no-trunc --container:查看command参数
docker images --images:全部
docker volume ls --volume:全部
-----------------------------------------------------------------------------------------------------
docker version --版本
docker info --配置
docker info | grep "Docker Root Dir" --配置,Docker存放位置
-----------------------------------------------------------------------------------------------------
docker start 80576e5ea74a --启动容器
docker stop 80576e5ea74a --停止容器
docker restart 80576e5ea74a --重启容器
docker rm 80576e5ea74a --移除容器
docker logs 80576e5ea74a --查看日志
docker inspect 80576e5ea74a --查看构建
docker port myslayers-mysql5 --查看端口
docker exec -it myslayers-prtainer /bin/bash --进入容器
c.清理空间
docker system df --查看Docker磁盘大致情况
docker system df -v --查看Docker磁盘详细情况
-----------------------------------------------------------------------------------------------------
docker container prune --清理,无用的container
docker image prune --清理,无用的image
docker volume prune --清理,无用的volume
docker system prune -a --删除,无用的镜像容器缓存【慎重】
-----------------------------------------------------------------------------------------------------
docker ps -a
docker rm -f 80576e5ea74a --移除容器,-f参数:强制删除
docker images
docker rmi -f d55229deb03e --移除镜像,-f参数:强制删除
docker volume ls
docker volume rm -f d55229deb03e --移除卷,-f参数:强制删除
-----------------------------------------------------------------------------------------------------
C:\Windows\system32>wsl --shutdown --经测试,14.5GB -> 7.57GB
C:\Windows\system32>diskpart
DISKPART> select vdisk file="C:\Users\mysla\AppData\Local\Docker\wsl\data\ext4.vhdx"
DISKPART> attach vdisk readonly --连接
DISKPART> compact vdisk --压缩
DISKPART> detach vdisk --断开
DISKPART> exit
-----------------------------------------------------------------------------------------------------
docker system df; \
docker kill $(docker ps -aq); \
docker rm $(docker ps -aq); \
docker rmi $(docker images -q); \
docker volume rm $(docker volume ls -q); \
docker system df
02.常用信息2
a.卸载docker
a.查看docker版本
yum list installed | grep docker
b.卸载docker版本
yum -y remove docker-ce.x86_64
yum -y remove containerd.io.x86_64
yum -y remove docker-ce-cli.x86_64
c.删除存储目录
rm -rf /etc/docker
rm -rf /run/docker
rm -rf /var/lib/dockershim
rm -rf /var/lib/docker
d.若发现删除,需要先进行umount操作
umount /var/lib/docker/devicemapper
b.设置容器开机自启动
a.开启
docker update --restart=always Portainer
b.关闭
docker update --restart=no Portainer
2.6 [2]compose
00.图示
特性 Dockerfile Docker Compose
用途 构建单个容器 镜像编排多容器应用
文件格式 文本文件,包含指令 YAML文件,定义服务、网络和卷
使用场景 创建自定义镜像 管理多容器应用(如Web+DB+Cache)
核心命令 docker build docker-compose up
依赖关系 无 可以定义服务之间的依赖关系
典型使用 构建镜像 启动、停止和管理多容器应用
01.简单说明
a.定义
Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具
它通过一个 YAML 文件(通常是 docker-compose.yml)来配置多个服务、网络和存储卷,从而实现一键启动整个应用
b.核心作用
a.编排多容器应用
在实际项目中,一个应用往往由多个服务组成,比如 Web 服务器、数据库、缓存服务等
Docker Compose 可以轻松管理这些服务之间的依赖关系
b.简化开发环境
通过一个命令(docker-compose up),你可以启动整个应用栈,而不需要手动启动每个容器
c.环境一致性
Docker Compose 确保开发、测试和生产环境的一致性,避免了“在我机器上能运行”的问题
c.配置
version:指定 Docker Compose 文件的版本
services:定义各个服务(容器)
build:指定 Dockerfile 路径来构建镜像
image:使用现成的镜像
ports:映射主机端口到容器端口
volumes:挂载数据卷
depends_on:定义服务之间的依赖关系
d.示例
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
-----------------------------------------------------------------------------------------------------
web:使用当前目录下的 Dockerfile 构建镜像,并将主机的 5000 端口映射到容器的 5000 端口
redis:直接使用官方的 Redis 镜像。
e.启动
docker-compose up --build -d
02.基本步骤
a.顶层关键字
version: "3.8" --(可选)指定 Compose 文件格式版本
services: --定义所有服务(容器)的根键
networks: --定义自定义网络的根键
volumes: --定义命名卷的根键
b.services 服务内常用配置
image: myapp:latest --使用指定的镜像
build: . --使用当前目录的 Dockerfile 构建镜像
container_name: my-webapp --指定容器名称
command: "bundle exec thin -p 3000" --覆盖镜像的默认 CMD
entrypoint: ["/docker-entrypoint.sh"] --覆盖镜像的默认 ENTRYPOINT
ports: --端口映射 "主机端口:容器端口"
- "8080:80"
volumes: --卷挂载 "主机路径:容器路径" 或 "命名卷:容器路径"
- ./data:/app/data
- db-data:/var/lib/mysql
environment: --设置环境变量
- RACK_ENV=development
env_file: --从文件加载环境变量
- .env
depends_on: --定义服务依赖关系(控制启动顺序)
- redis
restart: always --重启策略: no | always | on-failure | unless-stopped
networks: --将服务连接到指定网络
- my-net
healthcheck: --定义服务健康检查
test: ["CMD", "curl", "-f", "http://localhost"]
c.docker-compose CLI 常用命令
docker-compose up --创建并启动所有服务
docker-compose up -d --在后台创建并启动所有服务
docker-compose up --build --在启动前强制重新构建镜像
docker-compose down --停止并移除所有服务、网络
docker-compose down -v --同时移除定义的命名卷【慎重】
-----------------------------------------------------------------------------------------------------
docker-compose ps --查看所有服务的状态
docker-compose logs --查看所有服务的日志
docker-compose logs -f --持续跟踪(follow)日志输出
docker-compose config --验证并查看最终的配置信息
-----------------------------------------------------------------------------------------------------
docker-compose start --启动已存在的服务
docker-compose stop --停止正在运行的服务
docker-compose restart --重启服务
docker-compose rm --删除已停止的服务容器
-----------------------------------------------------------------------------------------------------
docker-compose build --构建或重新构建所有服务的镜像
docker-compose pull --拉取所有服务所需的镜像
docker-compose exec <service_name> /bin/bash --进入指定服务容器并执行命令
docker-compose run --rm <service_name> /bin/ls --在指定服务上运行一个一次性命令
03.SpringBoot3与Docker-Compose整合
a.说明
SpringBoot3整合Docker-Compose的主要优势在于约定大于配置。
使用Docker-Compose时,配置可以被SpringBoot3自动发现,从而减少手动配置。
例如,常见的MySQL、Redis等服务的配置可以省略,SpringBoot3会自动处理。
b.添加依赖
a.SpringBoot3依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
b.Docker-Compose依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
c.MySQL依赖
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
d.Redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
c.Compose推荐配置
a.配置说明
在使用Docker-Compose时,注意skip需要在start_only模式下才能正常执行。
在start_and_stop模式下,应用启动后会启动容器,然后关闭容器,skip参数将无效。
b.示例配置
spring:
docker:
compose:
profiles:
active: dev # 指定当前运行环境
enabled: true # 开启compose
start:
skip: if_running # 如果容器在运行就不再去再启动了
lifecycle-management: start_only # 这个参数不会在停机后关闭容器
services:
mysql:
image: 'mysql:latest'
restart: always
environment:
- MYSQL_DATABASE=root
- MYSQL_ROOT_PASSWORD=123456
ports:
- '3306:3306'
profiles:
- dev
labels:
org.springframework.boot.jdbc.parameters: useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8&useSSL=false
redis:
image: 'redis:latest'
restart: always
environment:
- 'REDIS_PASSWORD=redis'
ports:
- '6379:6379'
profiles:
- dev
04.Docker-Compose生命周期管理
a.管理器介绍
org.springframework.boot.docker.compose.lifecycle.DockerComposeLifecycleManager
负责整合后的Compose生命周期管理,包括容器创建、启动、停止,以及配置自动发现
b.配置自动发现
在容器启动完成后,会发布DockerComposeServicesReadyEvent事件。
DockerComposeServiceConnectionsApplicationListener监听到该事件后开始注册配置。
-----------------------------------------------------------------------------------------------------
private void registerConnectionDetails(BeanDefinitionRegistry registry, List<RunningService> runningServices) {
for (RunningService runningService : runningServices) {
DockerComposeConnectionSource source = new DockerComposeConnectionSource(runningService);
this.factories.getConnectionDetails(source, false).forEach((connectionDetailsType, connectionDetails) -> {
register(registry, runningService, connectionDetailsType, connectionDetails);
this.factories.getConnectionDetails(connectionDetails, false)
.forEach((adaptedType, adaptedDetails) -> register(registry, runningService, adaptedType,
adaptedDetails));
});
}
}
c.注意事项
skip需要搭配lifecycle-management使用。
常规的environment参数由SpringBoot自动发现,一些特殊参数(如MySQL连接参数)可以放到labels下,
格式类似于org.springframework.boot.jdbc.parameters。
2.7 [2]dockerfile
00.图示
特性 Dockerfile Docker Compose
用途 构建单个容器 镜像编排多容器应用
文件格式 文本文件,包含指令 YAML文件,定义服务、网络和卷
使用场景 创建自定义镜像 管理多容器应用(如Web+DB+Cache)
核心命令 docker build docker-compose up
依赖关系 无 可以定义服务之间的依赖关系
典型使用 构建镜像 启动、停止和管理多容器应用
01.简单说明
a.定义
Dockerfile 是一个文本文件,包含了一系列指令,用于定义如何构建一个 Docker 镜像
你可以把它想象成一个“菜谱”,告诉 Docker 如何从零开始制作一个容器镜像
比如,选择基础镜像、安装依赖、复制文件、设置环境变量等
b.作用
a.构建镜像
Dockerfile 是构建 Docker 镜像的基础
通过 docker build 命令,Docker 会按照 Dockerfile 中的指令一步步生成镜像
b.定制化环境
你可以基于官方镜像(如 Ubuntu、Python、Node.js)进行扩展
添加自己的应用代码和配置,从而创建一个完全符合需求的镜像
c.指令
FROM:指定基础镜像
RUN:执行命令,比如安装软件包
COPY:将本地文件复制到镜像中
WORKDIR:设置工作目录
EXPOSE:声明容器运行时监听的端口
CMD:指定容器启动时运行的命令
d.示例
# 使用官方 Python 镜像作为基础
FROM python:3.8-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 5000
# 运行应用
CMD ["python", "app.py"]
02.基本步骤
a.第一步:编写 Dockerfile
# 使用官方的 Node.js 18 轻量级镜像作为基础
FROM node:18-alpine
# 在镜像内创建 /app 目录作为工作区
WORKDIR /app
# 复制 package.json 等依赖描述文件,并安装依赖
# 这样做可以利用 Docker 缓存,如果依赖没变,无需重复安装
COPY package*.json ./
RUN npm install
# 将项目所有文件复制到工作区
COPY . .
# 声明容器将暴露 3000 端口
EXPOSE 3000
# 定义容器启动时执行的默认命令
CMD [ "node", "server.js" ]
-----------------------------------------------------------------------------------------------------
基础与元数据
FROM ubuntu:20.04 --指定基础镜像
LABEL maintainer="Your Name <[email protected] >" --为镜像添加元数据(作者、描述等)
-----------------------------------------------------------------------------------------------------
文件与工作目录
WORKDIR /app --指定后续命令的工作目录
COPY . . --将构建上下文中的文件/目录复制到镜像中(推荐)
ADD package.tar.gz /tmp --复制文件,可自动解压压缩包或下载URL文件
-----------------------------------------------------------------------------------------------------
构建时执行命令
RUN apt-get update && apt-get install -y vim --构建镜像时执行命令,如安装软件
RUN ["/bin/bash", "-c", "echo hello"] --RUN指令的Exec格式
-----------------------------------------------------------------------------------------------------
容器运行时配置
CMD ["node", "app.js"] --容器启动时默认执行的命令(可被覆盖)
ENTRYPOINT ["java", "-jar", "app.jar"] --容器启动时执行的命令(不会被覆盖,而是追加参数)
EXPOSE 8080 --声明容器计划暴露的端口(文档作用)
ENV APP_VERSION=1.0 --设置环境变量
ARG BUILD_VERSION=1.0 --设置构建时变量(仅build时有效)
VOLUME ["/data"] --创建一个匿名卷挂载点,用于持久化数据
USER node --指定运行后续命令和容器的用户
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ --定义容器健康检查
ONBUILD COPY . /app/src --当此镜像作为基础镜像时,在其下游镜像构建时执行
b.第二步:构建镜像
# 在 Dockerfile 所在目录执行
docker build -t my-nodejs-app:1.0 .
-----------------------------------------------------------------------------------------------------
build: 构建命令。
-t my-nodejs-app:1.0: 为镜像打上一个易于识别的标签(名称:版本)。
.: 指示 Docker 使用当前目录作为构建上下文(包括 Dockerfile 和应用代码)。
c.第三步:运行容器
docker run -d -p 8080:3000 --name my-app-instance my-nodejs-app:1.0
-----------------------------------------------------------------------------------------------------
run: 运行命令。
-d: 在后台(detached)模式下运行容器。
-p 8080:3000: 将主机的 8080 端口映射到容器的 3000 端口。
--name my-app-instance: 为这个运行的容器起一个名字。
my-nodejs-app:1.0: 指定要使用的镜像。
03.发布流程
a.构建Docker镜像
a.编写Dockerfile
# 使用官方的OpenJDK 8基础镜像
FROM openjdk:8-jdk
# 设置工作目录
WORKDIR /app
# 将当前目录的内容复制到容器的/app目录
COPY . /app
# 暴露应用程序运行的端口(如果需要)
# EXPOSE 8080
# 设置默认命令(如果需要)
# CMD ["java", "-jar", "your-application.jar"]
b.构建
docker build -t your-repo/your-image-name:your-tag .
--your-repo/your-image-name:your-tag 是你为镜像指定的名称和标签
--. 表示Dockerfile所在的当前目录
b.推送镜像到Docker私有仓库
a.登录到私有仓库
docker login your-private-registry.com
b.给镜像打标签以匹配私有仓库
docker tag your-repo/your-image-name:your-tag your-private-registry.com/your-repo/your-image-name:your-tag
c.推送镜像到私有仓库
docker push your-private-registry.com/your-repo/your-image-name:your-tag
c.启动自定义镜像
a.拉取镜像
docker pull your-private-registry.com/your-repo/your-image-name:your-tag
b.启动容器
docker run -d --name your-container-name your-private-registry.com/your-repo/your-image-name:your-tag
2.8 [3]dockge
01.官方
a.地址
https://github.com/louislam/dockge
https://github.com/TWO-ICE/Awesome-NAS-Docker
b.要求
Docker版本>=20或使用Podman
支持的操作系统包括:Ubuntu/Debian/Raspbian/CentOS/Fedora/ArchLinux
支持的架构包括:armv7, arm64, amd64
c.安装
# Create directories that store your stacks and stores Dockge's stack
mkdir /opt/homebrew/Cellar/dockge
mkdir /opt/homebrew/Cellar/dockge/data
mkdir /opt/homebrew/Cellar/dockge/stacks
cd /opt/homebrew/Cellar/dockge
# Download the compose.yaml
curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml
# Start the server
docker compose up -d
d.compose.yaml
services:
dockge:
image: louislam/dockge:1
restart: unless-stopped
ports:
# Host Port : Container Port
- 5001:5001
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
# If you want to use private registries, you need to share the auth file with Dockge:
# - /root/.docker/:/root/.docker
# Stacks Directory
# ⚠️ READ IT CAREFULLY. If you did it wrong, your data could end up writing into a WRONG PATH.
# ⚠️ 1. FULL path only. No relative path (MUST)
# ⚠️ 2. Left Stacks Path === Right Stacks Path (MUST)
- /opt/homebrew/Cellar/dockge/stacks:/opt/stacks
environment:
# Tell Dockge where is your stacks directory
- DOCKGE_STACKS_DIR=/opt/homebrew/Cellar/dockge/stacks
e.访问
http://127.0.0.1:5001
admin
dljxxxxxxx
02.部署
a.地址
https://github.com/SillyTavern/SillyTavern
b.操作
打开Dockge面板 -> 创建堆栈 -> 设置堆栈名称 -> 粘贴compose代码 -> 30秒启动成功!
c.compose
version: "3"
services:
sillytavern:
image: ghcr.io/sillytavern/sillytavern:latest
container_name: sillytavern
restart: unless-stopped
ports:
- "8730:8000"
volumes:
- "./config:/home/node/app/config"
- "./data:/home/node/app/data"
- "./plugins:/home/node/app/plugins"
- "./extensions:/home/node/app/public/scripts/extensions/third-party"
d.访问
http://127.0.0.1:8730
2.9 [3]portainer
01.官方
a.镜像
docker search portainer
docker pull portainer/portainer
b.本机模式
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock --restart=always --name prtainer portainer/portainer
c.远程模式
docker run -d -p 9000:9000 --restart=always --name prtainer portainer/portainer
d.运行
docker start 80576e5ea74a --启动容器
docker stop 80576e5ea74a --停止容器
docker restart 80576e5ea74a --重启容器
docker rm 80576e5ea74a --移除容器
docker logs 80576e5ea74a --查看日志
docker exec -it portainer /bin/bash --进入容器
http://127.0.0.1:9000 --测试(admin,12345678)
02.汉化
a.镜像
docker search portainer
docker pull 6053537/portainer-ce
b.x86一键安装
docker run -d --restart=always --name="portainer" -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data 6053537/portainer-ce
c.x86一键更新
sh -c "$(curl -kfsSl https://gitee.com/expin/public/raw/master/onex86.sh)"
d.运行
docker start 80576e5ea74a --启动容器
docker stop 80576e5ea74a --停止容器
docker restart 80576e5ea74a --重启容器
docker rm 80576e5ea74a --移除容器
docker logs 80576e5ea74a --查看日志
docker exec -it portainer /bin/bash --进入容器
http://127.0.0.1:9000 --测试(admin,12345678)
e.设置容器开机自启动
a.开启
docker update --restart=always portainer
b.关闭
docker update --restart=no portainer
3 kubernetes
3.1 [1]basic
01.介绍
a.什么是Kubernetes
a.定义
Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序
名字来源于希腊语,意为"舵手"或"领航员",K8s中的8代表中间的8个字母ubernete
由Google于2014年开源,基于其内部使用15年以上的Borg系统经验开发
现由Cloud Native Computing Foundation(CNCF)维护
b.核心功能
服务发现和负载均衡:K8s可以使用DNS名称或IP地址暴露容器,并在流量较高时进行负载均衡
存储编排:自动挂载存储系统,包括本地存储、公共云提供商等
自动部署和回滚:描述已部署容器的所需状态,K8s会以受控速率更改实际状态
自动装箱:提供一个节点集群运行容器化任务,告诉K8s每个容器需要多少CPU和内存
自我修复:重新启动失败的容器、替换容器、杀死不响应健康检查的容器
密钥和配置管理:存储和管理敏感信息,无需重新构建镜像即可部署和更新密钥
b.为什么需要Kubernetes
a.容器编排的必要性
单机Docker:适合开发测试,生产环境需要多主机管理
容器数量激增:微服务架构下,一个应用可能包含数十个容器
高可用需求:容器故障后需要自动重启和迁移
弹性伸缩:根据负载自动调整容器数量
服务发现:容器IP动态变化,需要统一的服务发现机制
b.K8s与Docker对比
Docker:解决了"如何打包和运行应用"的问题
K8s:解决了"如何管理大规模容器集群"的问题
关系:K8s使用Docker(或containerd、CRI-O等)作为容器运行时
c.K8s与其他编排工具对比
Docker Swarm 简单易用,但功能相对简单
适合小规模集群
与Docker原生集成
Kubernetes 功能强大,生态丰富
适合大规模生产环境
社区活跃,已成为事实标准
Apache Mesos 通用资源调度框架
支持容器和非容器工作负载
学习曲线陡峭
c.Kubernetes架构
a.集群架构
Kubernetes集群由Master节点(控制平面)和Worker节点(工作节点)组成
Master节点负责管理整个集群,Worker节点负责运行实际的应用容器
-------------------------------------------------------------------------------------------------
Master节点组件:
API Server:集群的统一入口,提供RESTful API
etcd:分布式键值存储,保存集群所有数据
Scheduler:负责资源调度,将Pod分配到合适的节点
Controller Manager:运行控制器进程,如节点控制器、副本控制器等
Cloud Controller Manager:与云提供商交互的控制器
-------------------------------------------------------------------------------------------------
Worker节点组件:
kubelet:运行在每个节点上的代理,负责维护容器的生命周期
kube-proxy:维护节点上的网络规则,实现服务的负载均衡
Container Runtime:容器运行时(Docker、containerd、CRI-O等)
b.工作流程
用户通过kubectl或API提交应用部署请求
API Server接收请求并存储到etcd
Scheduler监听API Server,发现未调度的Pod,选择合适的节点
kubelet监听API Server,发现调度到本节点的Pod,调用容器运行时创建容器
kube-proxy配置网络规则,实现服务的负载均衡
Controller Manager持续监控集群状态,确保实际状态与期望状态一致
c.架构图示
+---------------------+
| kubectl/API |
+----------+----------+
|
+----------v----------+
| API Server |
+----------+----------+
|
+----------v----------+
| etcd |
+---------------------+
+---------------------+ +---------------------+
| Scheduler | | Controller Manager |
+---------------------+ +---------------------+
+--------------------------------------------------+
| Worker Node 1 |
| +----------+ +----------+ +----------+ |
| | kubelet | |kube-proxy| |Container | |
| +----------+ +----------+ | Runtime | |
| +----------+ |
| +--------------------------------------+ |
| | Pods | |
| +--------------------------------------+ |
+--------------------------------------------------+
02.核心概念
a.Pod
a.定义
Pod是K8s中最小的部署单元,不是容器本身
一个Pod可以包含一个或多个容器,这些容器共享网络和存储
Pod中的容器共享同一个IP地址和端口空间
同一Pod中的容器可以通过localhost互相访问
b.为什么需要Pod
原因1:容器之间需要紧密协作(如应用容器+日志收集容器)
原因2:容器之间需要共享数据(通过Volume)
原因3:容器之间需要共享网络(通过Pod IP)
c.Pod的生命周期
Pending:Pod已被K8s接受,但容器镜像尚未创建
Running:Pod已绑定到节点,所有容器都已创建,至少一个容器正在运行
Succeeded:Pod中所有容器都成功终止,不会重启
Failed:Pod中所有容器都已终止,至少一个容器失败
Unknown:无法获取Pod状态,通常是节点通信问题
d.示例
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
b.Deployment
a.定义
Deployment为Pod和ReplicaSet提供声明式更新
用于管理无状态应用,是最常用的工作负载资源
提供滚动更新、回滚、扩缩容等功能
b.核心功能
副本管理:确保指定数量的Pod副本始终运行
滚动更新:逐步替换旧版本Pod,实现零停机更新
版本回滚:记录更新历史,支持快速回滚到之前版本
扩缩容:手动或自动调整Pod副本数量
c.工作原理
Deployment创建ReplicaSet
ReplicaSet创建和管理Pod
更新Deployment时,创建新的ReplicaSet,逐步扩容新RS,缩容旧RS
d.示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 --副本数量
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
c.Service
a.定义
Service是一种抽象,定义了一组Pod的访问策略
为动态变化的Pod提供稳定的网络访问入口
通过Label Selector选择后端Pod
b.为什么需要Service
问题1:Pod IP会动态变化(Pod重启后IP改变)
问题2:多个Pod副本需要负载均衡
问题3:需要统一的服务发现机制
解决:Service提供固定的ClusterIP,自动负载均衡到后端Pod
c.Service类型
ClusterIP(默认) 分配集群内部IP,仅集群内部可访问
用于集群内部服务间通信
NodePort 在每个节点上开放端口,集群外部可通过<NodeIP>:<NodePort>访问
端口范围:30000-32767
LoadBalancer 创建外部负载均衡器(需要云提供商支持)
自动分配外部IP
ExternalName 将服务映射到外部DNS名称
返回CNAME记录
d.示例
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: ClusterIP --服务类型
selector:
app: nginx --选择标签为app=nginx的Pod
ports:
- protocol: TCP
port: 80 --Service端口
targetPort: 80 --Pod端口
d.Namespace
a.定义
Namespace是K8s中的虚拟集群,用于资源隔离
一个物理集群可以划分为多个虚拟集群(Namespace)
不同Namespace中的资源名称可以相同
b.默认Namespace
default 默认命名空间,未指定Namespace的资源创建在此
kube-system K8s系统组件使用的命名空间
kube-public 所有用户可读的命名空间,通常用于集群信息
kube-node-lease 节点心跳信息的命名空间(K8s 1.13+)
c.使用场景
场景1:多租户隔离(开发、测试、生产环境)
场景2:资源配额管理(限制每个团队的资源使用)
场景3:访问控制(不同团队有不同权限)
d.示例
apiVersion: v1
kind: Namespace
metadata:
name: dev
-------------------------------------------------------------------------------------------------
kubectl create namespace dev --创建Namespace
kubectl get namespaces --查看Namespace
kubectl get pods -n dev --查看指定Namespace的Pod
e.Volume(数据卷)
a.定义
Volume是Pod中能够被多个容器访问的共享目录
解决容器数据持久化和容器间数据共享问题
Volume的生命周期与Pod相同
b.Volume类型
emptyDir 临时目录,Pod删除时数据也删除
用于临时存储,如缓���、临时文件
hostPath 挂载主机目录到Pod
用于访问宿主机文件系统
nfs 挂载NFS网络文件系统
用于跨节点共享数据
persistentVolumeClaim 使用PVC挂载PV
用于持久化存储
configMap 挂载ConfigMap作为文件
用于配置文件注入
secret 挂载Secret作为文件
用于敏感信息注入
c.示例(emptyDir)
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: cache-volume
mountPath: /cache
volumes:
- name: cache-volume
emptyDir: {} --临时卷
d.示例(hostPath)
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: host-volume
mountPath: /data
volumes:
- name: host-volume
hostPath:
path: /opt/data --宿主机路径
type: DirectoryOrCreate
03.核心组件详解
a.API Server
a.功能
提供RESTful API,是集群的统一入口
处理所有对集群资源的CRUD操作
认证、授权、准入控制
与etcd交互,实现资源的持久化
b.工作流程
客户端发送请求(kubectl、客户端库等)
认证:验证用户身份(证书、Token、ServiceAccount等)
授权:检查用户是否有权限执行操作(RBAC、ABAC等)
准入控制:执行准入控制器(Mutating、Validating)
数据持久化:将资源存储到etcd
返回响应
c.访问方式
kubectl 命令行工具,最常用
REST API 直接调用HTTP API
客户端库 各语言SDK(Go、Python、Java等)
kubectl proxy 本地代理,简化API访问
b.etcd
a.功能
分布式键值存储,保存集群所有配置和状态数据
使用Raft协议保证数据一致性
支持Watch机制,实时监听数据变化
b.存储内容
所有K8s资源对象:Pod、Service、ConfigMap等
集群配置信息
集群状态信息
c.高可用
建议部署奇数个节点(3、5、7)
超过半数节点存活即可提供服务
定期备份etcd数据
d.常用命令
etcdctl member list --查看集群成员
etcdctl endpoint status --查看状态
etcdctl snapshot save snapshot.db --备份
etcdctl snapshot restore snapshot.db --恢复
c.Scheduler
a.功能
监听API Server,发现未调度的Pod
根据调度算法为Pod选择最合适的节点
将调度结果写回API Server
b.调度过程
预选(Filtering):过滤掉不满足条件的节点
资源是否充足(CPU、内存)
节点是否就绪
Pod亲和性/反亲和性
污点和容忍度
优选(Scoring):对预选节点打分,选择最优节点
资源平衡
亲和性优先
最少请求数优先
c.调度策略
nodeSelector 通过标签选择节点
nodeAffinity 节点亲和性,支持硬性/软性要求
podAffinity Pod亲和性,Pod倾向于调度在一起
podAntiAffinity Pod反亲和性,Pod倾向于分散调度
taints and tolerations 污点和容忍度,防止Pod调度到特定节点
d.Controller Manager
a.功能
运行各种控制器,确保集群实际状态与期望状态一致
每个控制器是一个独立的进程,但为了降低复杂性,编译到同一个二进制文件
通过API Server监听资源变化,执行相应操作
b.常见控制器
Node Controller 监控节点状态,处理节点故障
Replication Controller 维护指定数量的Pod副本
Endpoints Controller 维护Service和Pod的对应关系
ServiceAccount Controller 为Namespace创建默认ServiceAccount
Deployment Controller 管理Deployment和ReplicaSet
StatefulSet Controller 管理有状态应用
DaemonSet Controller 确保每个节点运行指定Pod
Job Controller 管理一次性任务
CronJob Controller 管理定时任务
c.工作机制
控制器通过List-Watch机制监听资源变化
发现实际状态与期望状态不一致时,执行调谐操作
调谐是持续进行的,确保集群始终处于期望状态
e.kubelet
a.功能
运行在每个Worker节点上的代理
负责维护容器的生命周期
接收PodSpec,确保容器按照PodSpec运行
定期向API Server报告节点和Pod状态
b.主要职责
Pod管理:创建、启动、停止、删除容器
容器健康检查:执行Liveness、Readiness、Startup探针
资源监控:监控节点和容器资源使用情况
Volume管理:挂载和卸载Volume
镜像管理:拉取容器镜像
c.工作流程
监听API Server,获取调度到本节点的Pod
调用容器运行时(CRI)创建容器
执行健康检查,不健康时重启容器
定期上报节点和Pod状态
f.kube-proxy
a.功能
运行在每个节点上,维护网络规则
实现Service的负载均衡
支持三种代理模式:userspace、iptables、ipvs
b.代理模式
userspace模式 K8s早期版本,性能较差,已废弃
kube-proxy在用户空间监听端口,转发流量
iptables模式 默认模式,性能较好
使用iptables规则实现负载均衡
随机选择后端Pod
ipvs模式 高性能模式,支持更多负载均衡算法
支持rr、lc、dh、sh、sed、nq等算法
需要加载ipvs内核模块
c.工作原理
监听API Server,获取Service和Endpoints变化
根据Service配置,创建或更新iptables/ipvs规则
客户端访问Service时,通过规则转发到后端Pod
04.常见术语
a.Label(标签)
a.定义
Label是附加到K8s资源对象上的键值对
用于标识和选择资源对象
一个对象可以有多个Label
b.使用场景
环境标识:env=prod、env=dev
版本标识:version=v1.0、version=v2.0
应用标识:app=nginx、app=redis
团队标识:team=frontend、team=backend
c.Label Selector
等式选择器:env=prod(选择env为prod的资源)
集合选择器:env in (prod,dev)(选择env为prod或dev的资源)
d.示例
metadata:
labels:
app: nginx
env: prod
version: v1.0
b.Annotation(注解)
a.定义
Annotation也是键值对,但不用于标识和选择资源
用于存储非标识性的元数据
可以存储更长的、非结构化的数据
b.使用场景
构建信息:build_id、git_commit
负责人信息:maintainer、contact
工具信息:ingress配置、监控配置
c.示例
metadata:
annotations:
kubernetes.io/change-cause: "Update to version 1.21"
maintainer: "[email protected] "
c.ConfigMap
a.定义
ConfigMap用于存储非敏感的配置数据
以键值对形式存储
可以作为环境变量、命令行参数或配置文件使用
b.使用方式
环境变量注入
命令行参数注入
Volume挂载为文件
c.示例
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8080
log.level=INFO
database.url: "mysql://localhost:3306/mydb"
d.Secret
a.定义
Secret用于存储敏感信息,如密码、Token、密钥
数据以Base64编码存储(不是加密)
使用方式与ConfigMap类似
b.Secret类型
Opaque 默认类型,用于存储任意数据
kubernetes.io/service-account-token ServiceAccount Token
kubernetes.io/dockerconfigjson Docker镜像仓库认证信息
kubernetes.io/tls TLS证书和密钥
c.示例
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= --admin的Base64编码
password: MWYyZDFlMmU2N2Rm --密码的Base64编码
e.Ingress
a.定义
Ingress是集群外部访问集群内部服务的HTTP/HTTPS路由规则
提供负载均衡、SSL终止、基于名称的虚拟主机
需要Ingress Controller才能工作(如Nginx Ingress、Traefik等)
b.功能
域名路由:不同域名路由到不同Service
路径路由:同一域名不同路径路由到不同Service
TLS/SSL:配置HTTPS证书
负载均衡:多个Pod间负载均衡
c.示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
f.Helm
a.定义
Helm是K8s的包管理工具,类似于yum、apt
简化K8s应用的部署和管理
使用Chart打包K8s资源
b.核心概念
Chart Helm包,包含运行应用所需的所有资源定义
Release Chart的运行实例
Repository 存储和分享Chart的仓库
c.基本命令
helm search 搜索Chart
helm install 安装Chart
helm upgrade 升级Release
helm rollback 回滚Release
helm uninstall 卸载Release
3.2 [1]install
01.环境准备
a.系统要求
a.操作系统
Ubuntu 20.04/22.04 LTS
CentOS 7.9+/8.x
Debian 10/11
RHEL 7.9+/8.x
b.硬件要求
Master节点 最低:2核CPU、2GB内存、20GB硬盘
推荐:4核CPU、8GB内存、50GB硬盘
Worker节点 最低:2核CPU、2GB内存、30GB硬盘
推荐:4核CPU、16GB内存、100GB硬盘
c.网络要求
所有节点网络互通
所有节点能访问外网(拉取镜像)
关闭防火墙或开放必要端口
确保MAC地址和product_uuid唯一
b.版本选择
a.K8s版本
稳定版 选择最新的稳定版本(如1.28.x)
LTS版本 长期支持版本(如1.27.x)
测试版 不推荐生产环境使用
b.容器运行时
containerd 推荐,CNCF项目,性能好
CRI-O RedHat维护,OCI标准
Docker(通过cri-dockerd) 需要额外适配器,不推荐
c.版本兼容性
K8s 1.24+版本移除了对dockershim的支持
如果使用Docker,需要安装cri-dockerd
建议直接使用containerd或CRI-O
c.端口要求
a.Master节点端口
6443 Kubernetes API Server
2379-2380 etcd server client API
10250 Kubelet API
10259 kube-scheduler
10257 kube-controller-manager
b.Worker节点端口
10250 Kubelet API
30000-32767 NodePort Services
02.kubeadm安装(推荐)
a.准备工作(所有节点)
a.关闭swap
swapoff -a --临时关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab --永久关闭
free -h --验证
b.关闭防火墙
systemctl stop firewalld --CentOS/RHEL
systemctl disable firewalld
-------------------------------------------------------------------------------------------------
ufw disable --Ubuntu/Debian
c.关闭SELinux
setenforce 0 --临时关闭
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config --永久关闭
d.配置内核参数
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
-------------------------------------------------------------------------------------------------
modprobe overlay --加载模块
modprobe br_netfilter
-------------------------------------------------------------------------------------------------
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
-------------------------------------------------------------------------------------------------
sysctl --system --应用配置
e.配置主机名和hosts
hostnamectl set-hostname k8s-master --设置主机名
-------------------------------------------------------------------------------------------------
cat >> /etc/hosts << EOF
192.168.1.10 k8s-master
192.168.1.11 k8s-node1
192.168.1.12 k8s-node2
EOF
b.安装容器运行时(containerd)
a.安装containerd(Ubuntu/Debian)
apt-get update
apt-get install -y containerd
-------------------------------------------------------------------------------------------------
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml
-------------------------------------------------------------------------------------------------
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sed -i 's#registry.k8s.io/pause:3.6#registry.aliyuncs.com/google_containers/pause:3.9#' /etc/containerd/config.toml
-------------------------------------------------------------------------------------------------
systemctl restart containerd
systemctl enable containerd
systemctl status containerd --验证
b.安装containerd(CentOS/RHEL)
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y containerd.io
-------------------------------------------------------------------------------------------------
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml
-------------------------------------------------------------------------------------------------
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sed -i 's#registry.k8s.io/pause:3.6#registry.aliyuncs.com/google_containers/pause:3.9#' /etc/containerd/config.toml
-------------------------------------------------------------------------------------------------
systemctl restart containerd
systemctl enable containerd
systemctl status containerd --验证
c.配置镜像加速
vim /etc/containerd/config.toml
-------------------------------------------------------------------------------------------------
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.mirrors.ustc.edu.cn"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
endpoint = ["https://registry.aliyuncs.com/google_containers"]
-------------------------------------------------------------------------------------------------
systemctl restart containerd
c.安装kubeadm、kubelet、kubectl
a.Ubuntu/Debian
apt-get update
apt-get install -y apt-transport-https ca-certificates curl
-------------------------------------------------------------------------------------------------
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
-------------------------------------------------------------------------------------------------
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
-------------------------------------------------------------------------------------------------
apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl --锁定版本
-------------------------------------------------------------------------------------------------
systemctl enable kubelet
systemctl start kubelet
b.CentOS/RHEL
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
-------------------------------------------------------------------------------------------------
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet
systemctl start kubelet
c.验证安装
kubeadm version --查看kubeadm版本
kubelet --version --查看kubelet版本
kubectl version --client --查看kubectl版本
d.初始化Master节点
a.生成初始化配置
kubeadm config print init-defaults > kubeadm-init.yaml
-------------------------------------------------------------------------------------------------
vim kubeadm-init.yaml
修改以下内容:
advertiseAddress: 192.168.1.10 --改为Master节点IP
imageRepository: registry.aliyuncs.com/google_containers --改为阿里云镜像
kubernetesVersion: v1.28.0 --指定K8s版本
networking:
podSubnet: 10.244.0.0/16 --Pod网络CIDR
serviceSubnet: 10.96.0.0/12 --Service网络CIDR
b.预拉取镜像
kubeadm config images pull --config kubeadm-init.yaml --提前拉取镜像
-------------------------------------------------------------------------------------------------
或使用阿里云镜像:
kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
c.初始化集群
kubeadm init \
--apiserver-advertise-address=192.168.1.10 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
-------------------------------------------------------------------------------------------------
初始化成功后,会输出类似信息:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d.配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
-------------------------------------------------------------------------------------------------
kubectl get nodes --验证
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane 1m v1.28.0
-------------------------------------------------------------------------------------------------
注意:状态为NotReady是正常的,因为还未安装网络插件
e.安装网络插件(Master节点)
a.Flannel(推荐新手)
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
-------------------------------------------------------------------------------------------------
或使用国内镜像:
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
sed -i 's#docker.io#docker.mirrors.ustc.edu.cn#g' kube-flannel.yml
kubectl apply -f kube-flannel.yml
-------------------------------------------------------------------------------------------------
kubectl get pods -n kube-flannel --验证
kubectl get nodes --节点状态变为Ready
b.Calico(推荐生产环境)
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
-------------------------------------------------------------------------------------------------
kubectl get pods -n kube-system | grep calico --验证
c.Weave Net
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
-------------------------------------------------------------------------------------------------
kubectl get pods -n kube-system | grep weave --验证
f.加入Worker节点
a.获取join命令
在Master节点执行:
kubeadm token create --print-join-command --生成join命令
-------------------------------------------------------------------------------------------------
输出示例:
kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
b.Worker节点加入
在Worker节点执行上述join命令:
kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-------------------------------------------------------------------------------------------------
加入成功后,在Master节点验证:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 10m v1.28.0
k8s-node1 Ready <none> 2m v1.28.0
k8s-node2 Ready <none> 1m v1.28.0
c.Token过期处理
Token默认24小时过期,如果过期需要重新生成:
kubeadm token create --创建新Token
kubeadm token list --查看Token
-------------------------------------------------------------------------------------------------
获取CA证书哈希:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
-------------------------------------------------------------------------------------------------
手动拼接join命令:
kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
03.���进制安装(高级)
a.准备工作
a.下载二进制文件
访问:https://github.com/kubernetes/kubernetes/releases
下载对应版本的二进制文件(kubernetes-server-linux-amd64.tar.gz)
b.解压
tar -xzf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin
-------------------------------------------------------------------------------------------------
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
cp kubelet kube-proxy /usr/local/bin/
b.生成证书
a.安装cfssl
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
-------------------------------------------------------------------------------------------------
chmod +x cfssl*
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
b.生成CA证书
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
-------------------------------------------------------------------------------------------------
cat > ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
-------------------------------------------------------------------------------------------------
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
c.生成API Server证书
cat > server-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"10.0.0.1",
"127.0.0.1",
"192.168.1.10",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
-------------------------------------------------------------------------------------------------
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
c.配置etcd
a.下载etcd
wget https://github.com/etcd-io/etcd/releases/download/v3.5.9/etcd-v3.5.9-linux-amd64.tar.gz
tar -xzf etcd-v3.5.9-linux-amd64.tar.gz
cp etcd-v3.5.9-linux-amd64/etcd* /usr/local/bin/
b.创建systemd服务
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/local/bin/etcd \\
--name=etcd01 \\
--data-dir=/var/lib/etcd \\
--listen-client-urls=https://192.168.1.10:2379,http://127.0.0.1:2379 \\
--advertise-client-urls=https://192.168.1.10:2379 \\
--listen-peer-urls=https://192.168.1.10:2380 \\
--initial-advertise-peer-urls=https://192.168.1.10:2380 \\
--initial-cluster=etcd01=https://192.168.1.10:2380 \\
--initial-cluster-token=etcd-cluster-token \\
--initial-cluster-state=new
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
-------------------------------------------------------------------------------------------------
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
systemctl status etcd --验证
d.配置API Server
略(二进制安装较复杂,生产环境建议使用kubeadm)
04.Minikube安装(本地开发)
a.安装Minikube(macOS)
brew install minikube --使用Homebrew安装
-------------------------------------------------------------------------------------------------
或手动安装:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64
sudo install minikube-darwin-amd64 /usr/local/bin/minikube
b.安装Minikube(Linux)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
c.安装Minikube(Windows)
下载安装包:https://github.com/kubernetes/minikube/releases/latest
或使用Chocolatey:
choco install minikube
d.启动Minikube
minikube start --使用默认驱动(Docker)
minikube start --driver=virtualbox --使用VirtualBox驱动
minikube start --driver=hyperv --使用Hyper-V驱动
minikube start --cpus=4 --memory=8192 --指定资源
-------------------------------------------------------------------------------------------------
minikube status --查看状态
kubectl get nodes --验证
e.常用命令
minikube stop --停止集群
minikube delete --删除集群
minikube pause --暂停集群
minikube unpause --恢复集群
minikube dashboard --打开Dashboard
minikube ssh --SSH到节点
minikube addons list --查看插件列表
minikube addons enable ingress --启用Ingress插件
05.Kind安装(本地开发)
a.安装Kind(macOS/Linux)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
-------------------------------------------------------------------------------------------------
或使用包管理器:
brew install kind --macOS
go install sigs.k8s.io/[email protected] --Go安装
b.创建集群
kind create cluster --创建单节点集群
kind create cluster --name my-cluster --指定集群名称
-------------------------------------------------------------------------------------------------
使用配置文件创建多节点集群:
cat > kind-config.yaml << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
-------------------------------------------------------------------------------------------------
kind create cluster --config kind-config.yaml
c.常用命令
kind get clusters --查看集群列表
kind delete cluster --删除默认集群
kind delete cluster --name my-cluster --删除指定集群
kind load docker-image my-image:latest --加载镜像到集群
kubectl cluster-info --context kind-my-cluster --查看集群信息
06.K3s安装(轻量级)
a.安装K3s
curl -sfL https://get.k3s.io | sh - --一键安装
-------------------------------------------------------------------------------------------------
指定版本:
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.28.0+k3s1 sh -
-------------------------------------------------------------------------------------------------
验证:
systemctl status k3s --查看服务状态
kubectl get nodes --查看节点
b.配置kubectl
mkdir -p $HOME/.kube
sudo cp /etc/rancher/k3s/k3s.yaml $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
c.添加Worker节点
在Master节点获取Token:
cat /var/lib/rancher/k3s/server/node-token
-------------------------------------------------------------------------------------------------
在Worker节点执行:
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.10:6443 K3S_TOKEN=<token> sh -
d.卸载K3s
/usr/local/bin/k3s-uninstall.sh --Master节点
/usr/local/bin/k3s-agent-uninstall.sh --Worker节点
07.常见问题
a.镜像拉取失败
问题:国内无法访问gcr.io、k8s.gcr.io等镜像仓库
解决:使用阿里云镜像:registry.aliyuncs.com/google_containers
b.节点NotReady
问题:节点状态一直是NotReady
解决:检查网络插件是否正常运行(kubectl get pods -n kube-system)
c.coredns CrashLoopBackOff
问题:coredns容器一直重启
解决:检查/etc/resolv.conf,确保DNS配置正确
d.端口被占用
问题:6443端口已被占用
解决:lsof -i:6443 查看占用进程,kill掉或更换端口
e.kubelet启动失败
问题:kubelet服务无法启动
解决:查看日志 journalctl -xeu kubelet,根据错误信息排查
3.3 [1]backup
01.etcd备份
a.备份方式
a.快照备份
etcd的数据以快照形式保存
使用etcdctl snapshot save命令备份
备份文件包含完整的集群状态数据
b.定时备份
使用cron定时任务自动备份
建议每天至少备份一次
保留最近7天的备份文件
c.备份位置
本地备份 存储在Master节点本地磁盘
远程备份 存储在NAS、对象存储(如S3、OSS)
多地备份 同时存储在多个位置,提高可靠性
b.备份命令
a.查看etcd信息
kubectl get pods -n kube-system | grep etcd --查看etcd Pod
-------------------------------------------------------------------------------------------------
etcd Pod名称通常为:etcd-<master-hostname>
etcd数据目录:/var/lib/etcd
b.使用etcdctl备份(kubeadm安装)
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /backup/etcd-snapshot-$(date +%Y%m%d-%H%M%S).db
-------------------------------------------------------------------------------------------------
验证备份文件:
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot-20231216-100000.db
c.使用kubectl exec备份
kubectl exec -n kube-system etcd-k8s-master -- sh -c \
"ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /tmp/etcd-snapshot.db"
-------------------------------------------------------------------------------------------------
kubectl cp kube-system/etcd-k8s-master:/tmp/etcd-snapshot.db ./etcd-snapshot.db
d.检查备份文件
ls -lh /backup/etcd-snapshot-*.db --查看备份文件大小
-------------------------------------------------------------------------------------------------
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot-20231216-100000.db --write-out=table
输出示例:
+----------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 12345678 | 10000 | 1234 | 5.2 MB |
+----------+----------+------------+------------+
c.自动化备份脚本
a.创建备份脚本
cat > /usr/local/bin/etcd-backup.sh << 'EOF'
#!/bin/bash
# etcd自动备份脚本
# 配置变量
BACKUP_DIR="/backup/etcd"
ETCD_ENDPOINTS="https://127.0.0.1:2379"
ETCD_CACERT="/etc/kubernetes/pki/etcd/ca.crt"
ETCD_CERT="/etc/kubernetes/pki/etcd/server.crt"
ETCD_KEY="/etc/kubernetes/pki/etcd/server.key"
RETENTION_DAYS=7
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/etcd-snapshot-${DATE}.db"
# 创建备份目录
mkdir -p ${BACKUP_DIR}
# 执行备份
echo "开始备份 etcd..."
ETCDCTL_API=3 etcdctl \
--endpoints=${ETCD_ENDPOINTS} \
--cacert=${ETCD_CACERT} \
--cert=${ETCD_CERT} \
--key=${ETCD_KEY} \
snapshot save ${BACKUP_FILE}
# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "备份成功: ${BACKUP_FILE}"
# 验证备份文件
ETCDCTL_API=3 etcdctl snapshot status ${BACKUP_FILE}
else
echo "备份失败!"
exit 1
fi
# 清理过期备份(保留最近7天)
echo "清理 ${RETENTION_DAYS} 天前的备份..."
find ${BACKUP_DIR} -name "etcd-snapshot-*.db" -mtime +${RETENTION_DAYS} -delete
# 显示当前备份文件
echo "当前备份文件:"
ls -lh ${BACKUP_DIR}/etcd-snapshot-*.db
echo "备份完成!"
EOF
-------------------------------------------------------------------------------------------------
chmod +x /usr/local/bin/etcd-backup.sh
b.测试备份脚本
/usr/local/bin/etcd-backup.sh --手动执行测试
c.配置定时任务
crontab -e
-------------------------------------------------------------------------------------------------
添加以下内容(每天凌晨2点执行备份):
0 2 * * * /usr/local/bin/etcd-backup.sh >> /var/log/etcd-backup.log 2>&1
-------------------------------------------------------------------------------------------------
查看定时任务:
crontab -l
d.远程备份脚本(上传到对象存储)
cat > /usr/local/bin/etcd-backup-s3.sh << 'EOF'
#!/bin/bash
# etcd备份并上传到S3
BACKUP_DIR="/backup/etcd"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/etcd-snapshot-${DATE}.db"
S3_BUCKET="s3://my-k8s-backup"
# 执行备份
/usr/local/bin/etcd-backup.sh
# 上传到S3
if [ -f ${BACKUP_FILE} ]; then
echo "上传备份到 S3..."
aws s3 cp ${BACKUP_FILE} ${S3_BUCKET}/etcd/
if [ $? -eq 0 ]; then
echo "上传成功!"
else
echo "上传失败!"
exit 1
fi
fi
EOF
-------------------------------------------------------------------------------------------------
chmod +x /usr/local/bin/etcd-backup-s3.sh
02.etcd恢复
a.恢复流程
a.恢复前准备
停止所有Master节点的K8s组件
备份当前etcd数据(防止恢复失败)
确保有可用的etcd备份文件
b.恢复步骤
第一步:停止etcd服务
第二步:清理旧数据目录
第三步:使用快照恢复数据
第四步:修改etcd配置(如果需要)
第五步:启动etcd服务
第六步:启动K8s组件
第七步:验证恢复结果
c.注意事项
恢复操作会覆盖现有数据,务必谨慎
建议在测试环境先演练恢复流程
恢复后需要重启所有K8s组件
b.恢复命令
a.停止K8s组件(kubeadm安装)
systemctl stop kubelet --停止kubelet
-------------------------------------------------------------------------------------------------
或使用静态Pod方式停止:
mv /etc/kubernetes/manifests /etc/kubernetes/manifests.bak --移走静态Pod配置
-------------------------------------------------------------------------------------------------
等待所有组件停止:
docker ps | grep k8s --确认容器已停止
b.备份当前数据
mv /var/lib/etcd /var/lib/etcd.bak --备份当前etcd数据
c.恢复快照
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot-20231216-100000.db \
--name=etcd-0 \
--initial-cluster=etcd-0=https://192.168.1.10:2380 \
--initial-cluster-token=etcd-cluster \
--initial-advertise-peer-urls=https://192.168.1.10:2380 \
--data-dir=/var/lib/etcd
-------------------------------------------------------------------------------------------------
参数说明:
--name etcd成员名称
--initial-cluster 初始集群配置
--initial-cluster-token 集群令牌
--initial-advertise-peer-urls 成员间通信地址
--data-dir 数据目录
d.修改权限
chown -R etcd:etcd /var/lib/etcd --如果使用etcd用户
-------------------------------------------------------------------------------------------------
或:
chmod 700 /var/lib/etcd
e.启动K8s组件
mv /etc/kubernetes/manifests.bak /etc/kubernetes/manifests --恢复静态Pod配置
systemctl start kubelet --启动kubelet
f.多节点恢复
# 在所有Master节点执行恢复操作
# 节点1:
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
--name=etcd-0 \
--initial-cluster=etcd-0=https://192.168.1.10:2380,etcd-1=https://192.168.1.11:2380,etcd-2=https://192.168.1.12:2380 \
--initial-cluster-token=etcd-cluster \
--initial-advertise-peer-urls=https://192.168.1.10:2380 \
--data-dir=/var/lib/etcd
-------------------------------------------------------------------------------------------------
# 节点2:
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
--name=etcd-1 \
--initial-cluster=etcd-0=https://192.168.1.10:2380,etcd-1=https://192.168.1.11:2380,etcd-2=https://192.168.1.12:2380 \
--initial-cluster-token=etcd-cluster \
--initial-advertise-peer-urls=https://192.168.1.11:2380 \
--data-dir=/var/lib/etcd
-------------------------------------------------------------------------------------------------
# 节点3:
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
--name=etcd-2 \
--initial-cluster=etcd-0=https://192.168.1.10:2380,etcd-1=https://192.168.1.11:2380,etcd-2=https://192.168.1.12:2380 \
--initial-cluster-token=etcd-cluster \
--initial-advertise-peer-urls=https://192.168.1.12:2380 \
--data-dir=/var/lib/etcd
c.验证恢复
a.检查etcd状态
kubectl get pods -n kube-system | grep etcd --查看etcd Pod状态
-------------------------------------------------------------------------------------------------
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
member list
-------------------------------------------------------------------------------------------------
输出示例:
8e9e05c52164694d, started, etcd-0, https://192.168.1.10:2380, https://192.168.1.10:2379, false
b.检查集群状态
kubectl get nodes --查看节点状态
kubectl get pods -A --查看所有Pod状态
kubectl get deployments -A --查看Deployment状态
c.检查数据完整性
kubectl get namespaces --查看命名空间
kubectl get configmaps -A --查看ConfigMap
kubectl get secrets -A --查看Secret
-------------------------------------------------------------------------------------------------
验证关键应用是否正常:
kubectl get pods -n <namespace> --检查业务Pod
03.资源备份
a.使用kubectl导出
a.导出单个资源
kubectl get deployment nginx -n default -o yaml > nginx-deployment.yaml --导出Deployment
kubectl get service nginx -n default -o yaml > nginx-service.yaml --导出Service
kubectl get configmap nginx-config -n default -o yaml > nginx-configmap.yaml --导出ConfigMap
b.导出命名空间所有资源
kubectl get all -n default -o yaml > default-namespace.yaml --导出所有资源
-------------------------------------------------------------------------------------------------
注意:get all不包括ConfigMap、Secret、PVC等资源
c.导出特定类型的所有资源
kubectl get deployments -A -o yaml > all-deployments.yaml --所有Deployment
kubectl get services -A -o yaml > all-services.yaml --所有Service
kubectl get configmaps -A -o yaml > all-configmaps.yaml --所有ConfigMap
kubectl get secrets -A -o yaml > all-secrets.yaml --所有Secret
kubectl get pvc -A -o yaml > all-pvc.yaml --所有PVC
d.批量导出脚本
cat > /usr/local/bin/k8s-export-resources.sh << 'EOF'
#!/bin/bash
# K8s资源导出脚本
BACKUP_DIR="/backup/k8s-resources"
DATE=$(date +%Y%m%d-%H%M%S)
EXPORT_DIR="${BACKUP_DIR}/${DATE}"
mkdir -p ${EXPORT_DIR}
# 导出各类资源
echo "导出Namespace..."
kubectl get namespaces -o yaml > ${EXPORT_DIR}/namespaces.yaml
echo "导出Deployments..."
kubectl get deployments -A -o yaml > ${EXPORT_DIR}/deployments.yaml
echo "导出StatefulSets..."
kubectl get statefulsets -A -o yaml > ${EXPORT_DIR}/statefulsets.yaml
echo "导出DaemonSets..."
kubectl get daemonsets -A -o yaml > ${EXPORT_DIR}/daemonsets.yaml
echo "导出Services..."
kubectl get services -A -o yaml > ${EXPORT_DIR}/services.yaml
echo "导出ConfigMaps..."
kubectl get configmaps -A -o yaml > ${EXPORT_DIR}/configmaps.yaml
echo "导出Secrets..."
kubectl get secrets -A -o yaml > ${EXPORT_DIR}/secrets.yaml
echo "导出PV..."
kubectl get pv -o yaml > ${EXPORT_DIR}/pv.yaml
echo "导出PVC..."
kubectl get pvc -A -o yaml > ${EXPORT_DIR}/pvc.yaml
echo "导出Ingress..."
kubectl get ingress -A -o yaml > ${EXPORT_DIR}/ingress.yaml
echo "导出完成! 文件保存在: ${EXPORT_DIR}"
ls -lh ${EXPORT_DIR}
EOF
-------------------------------------------------------------------------------------------------
chmod +x /usr/local/bin/k8s-export-resources.sh
b.使用Velero备份
a.安装Velero CLI
# macOS
brew install velero
-------------------------------------------------------------------------------------------------
# Linux
wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz
tar -xzf velero-v1.12.0-linux-amd64.tar.gz
sudo mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/
b.安装Velero服务端(使用Minio)
# 安装Minio作为对象存储
kubectl apply -f https://raw.githubusercontent.com/vmware-tanzu/velero/main/examples/minio/00-minio-deployment.yaml
-------------------------------------------------------------------------------------------------
# 创建凭证文件
cat > credentials-velero << EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
-------------------------------------------------------------------------------------------------
# 安装Velero
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket velero \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000
c.创建备份
velero backup create my-backup --备份所有资源
velero backup create my-backup --include-namespaces default --备份指定命名空间
velero backup create my-backup --selector app=nginx --备份指定标签的资源
-------------------------------------------------------------------------------------------------
查看备份:
velero backup get --查看所有备份
velero backup describe my-backup --查看备份详情
velero backup logs my-backup --查看备份日志
d.定时备份
velero schedule create daily-backup --schedule="0 2 * * *" --每天凌晨2点备份
velero schedule create weekly-backup --schedule="0 2 * * 0" --每周日凌晨2点备份
-------------------------------------------------------------------------------------------------
查看定时任务:
velero schedule get
e.恢复备份
velero restore create --from-backup my-backup --从备份恢复
velero restore create --from-backup my-backup --include-namespaces default --恢复指定命名空间
-------------------------------------------------------------------------------------------------
查看恢复状态:
velero restore get
velero restore describe <restore-name>
c.GitOps备份
a.使用Git存储配置
将所有K8s YAML配置存储在Git仓库
通过CI/CD自动应用配置
配置变更历史可追溯
b.目录结构示例
k8s-configs/
├── base/
│ ├── deployments/
│ │ ├── app1.yaml
│ │ └── app2.yaml
│ ├── services/
│ │ ├── app1-svc.yaml
│ │ └── app2-svc.yaml
│ └── configmaps/
│ └── app-config.yaml
├── overlays/
│ ├── dev/
│ ├── staging/
│ └── prod/
└── README.md
c.使用ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
-------------------------------------------------------------------------------------------------
创建应用:
kubectl apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-configs
targetRevision: HEAD
path: base
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
EOF
d.使用Flux
flux bootstrap github \
--owner=myorg \
--repository=k8s-configs \
--branch=main \
--path=./clusters/my-cluster \
--personal
04.灾难恢复
a.完全恢复流程
a.场景说明
整个集群损坏需要重建
从备份恢复所有数据和配置
b.恢复步骤
第一步:重新部署K8s集群(使用kubeadm init)
第二步:恢复etcd数据(从快照恢复)
第三步:验证集群基础功能
第四步:恢复网络插件配置
第五步:恢复应用资源(使用kubectl apply或Velero)
第六步:验证应用功能
第七步:恢复持久化数据(如果有)
c.完整恢复脚本
cat > /usr/local/bin/k8s-disaster-recovery.sh << 'EOF'
#!/bin/bash
# K8s灾难恢复脚本
ETCD_BACKUP="/backup/etcd/etcd-snapshot-latest.db"
RESOURCE_BACKUP="/backup/k8s-resources/latest"
echo "=== 步骤1: 恢复etcd ==="
systemctl stop kubelet
mv /etc/kubernetes/manifests /etc/kubernetes/manifests.bak
ETCDCTL_API=3 etcdctl snapshot restore ${ETCD_BACKUP} \
--name=etcd-0 \
--initial-cluster=etcd-0=https://192.168.1.10:2380 \
--initial-cluster-token=etcd-cluster \
--initial-advertise-peer-urls=https://192.168.1.10:2380 \
--data-dir=/var/lib/etcd
mv /etc/kubernetes/manifests.bak /etc/kubernetes/manifests
systemctl start kubelet
echo "等待集群就绪..."
sleep 30
echo "=== 步骤2: 恢复网络插件 ==="
kubectl apply -f /etc/kubernetes/network-plugin.yaml
echo "等待网络就绪..."
sleep 30
echo "=== 步骤3: 恢复应用资源 ==="
kubectl apply -f ${RESOURCE_BACKUP}/namespaces.yaml
kubectl apply -f ${RESOURCE_BACKUP}/configmaps.yaml
kubectl apply -f ${RESOURCE_BACKUP}/secrets.yaml
kubectl apply -f ${RESOURCE_BACKUP}/pv.yaml
kubectl apply -f ${RESOURCE_BACKUP}/pvc.yaml
kubectl apply -f ${RESOURCE_BACKUP}/deployments.yaml
kubectl apply -f ${RESOURCE_BACKUP}/statefulsets.yaml
kubectl apply -f ${RESOURCE_BACKUP}/daemonsets.yaml
kubectl apply -f ${RESOURCE_BACKUP}/services.yaml
kubectl apply -f ${RESOURCE_BACKUP}/ingress.yaml
echo "=== 恢复完成! ==="
echo "请执行以下命令验证:"
echo " kubectl get nodes"
echo " kubectl get pods -A"
EOF
-------------------------------------------------------------------------------------------------
chmod +x /usr/local/bin/k8s-disaster-recovery.sh
b.部分恢复流程
a.恢复单个命名空间
kubectl apply -f backup/namespace/my-namespace.yaml --恢复命名空间定义
kubectl apply -f backup/namespace/my-namespace/ --恢复该命名空间下所有资源
b.恢复单个应用
kubectl apply -f backup/apps/nginx/ --恢复nginx应用
c.使用Velero部分恢复
velero restore create --from-backup my-backup --include-namespaces default --只恢复default命名空间
velero restore create --from-backup my-backup --selector app=nginx --只恢复特定标签的资源
c.跨集群迁移
a.导出源集群资源
# 在源集群执行
/usr/local/bin/k8s-export-resources.sh
-------------------------------------------------------------------------------------------------
# 打包备份文件
tar -czf k8s-backup.tar.gz /backup/k8s-resources/20231216-100000/
b.导入目标集群
# 将备份文件传输到目标集群
scp k8s-backup.tar.gz user@target-cluster:/tmp/
-------------------------------------------------------------------------------------------------
# 在目标集群解压
tar -xzf /tmp/k8s-backup.tar.gz -C /tmp/
-------------------------------------------------------------------------------------------------
# 应用资源
kubectl apply -f /tmp/backup/k8s-resources/20231216-100000/
c.使用Velero跨集群迁移
# 源集群创建备份
velero backup create migration-backup
-------------------------------------------------------------------------------------------------
# 配置目标集群使用相同的对象存储
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket velero \
--secret-file ./credentials-velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000
-------------------------------------------------------------------------------------------------
# 目标集群恢复
velero restore create --from-backup migration-backup
d.注意事项
修改资源中的集群特定配置(如节点选择器、存储类)
更新DNS、负载均衡器等外部依赖
验证持久化数据是否正确迁移
测试应用功能是否正常
3.4 [1]network
01.网络模型
a.Pod网络
a.网络模型基础
每个Pod都有独立的IP地址
Pod内所有容器共享网络命名空间
Pod之间可以直接通信,无需NAT
节点和Pod之间可以直接通信
b.网络要求
所有Pod可以在不使用NAT的情况下与其他Pod通信
所有节点可以在不使用NAT的情况下与所有Pod通信
Pod看到的自己的IP地址与其他Pod看到的地址相同
c.Pod内容器通信
同一个Pod内的容器通过localhost通信
共享网络命名空间和端口空间
-------------------------------------------------------------------------------------------------
示例:
容器A监听8080端口
容器B通过localhost:8080访问容器A
d.Pod之间通信
通过PodIP直接通信
依赖CNI插件实现网络互通
跨节点通信通过overlay网络或路由实现
b.Service网络
a.ClusterIP网络
虚拟IP地址,只在集群内部可访问
通过kube-proxy实现负载均衡
默认的Service类型
b.Service网段
在kubeadm init时通过--service-cidr指定
默认为10.96.0.0/12
与Pod网段不能重叠
c.Service到Pod的映射
通过Endpoints对象关联
kube-proxy监听Service和Endpoints变化
更新iptables或IPVS规则
d.DNS解析
每个Service自动创建DNS记录
格式:<service-name>.<namespace>.svc.cluster.local
Pod内可以直接使用Service名称访问
c.CNI插件对比
a.Flannel
简单易用,适合入门
支持多种后端(VXLAN、host-gw、UDP)
不支持网络策略
性能中等
-------------------------------------------------------------------------------------------------
使用场景:开发测试环境、小型集群
b.Calico
功能强大,支持网络策略
支持BGP路由和IPIP模式
性能好,适合大规模集群
配置复杂度中等
-------------------------------------------------------------------------------------------------
使用场景:生产环境、需要网络隔离的场景
c.Weave Net
自动发现,配置简单
支持加密通信
支持网络策略
性能较好
-------------------------------------------------------------------------------------------------
使用场景:需要加密的场景
d.Cilium
基于eBPF技术,性能极好
支持高级网络策略
支持Service Mesh集成
需要较新的内核版本(4.9+)
-------------------------------------------------------------------------------------------------
使用场景:高性能要求、Service Mesh场景
e.性能对比
插件 吞吐量 延迟 CPU占用 内存占用 网络策略
Flannel 中等 低 低 低 不支持
Calico 高 低 中 中 支持
Weave Net 中等 中 中 中 支持
Cilium 极高 极低 低 中 支持
02.Service详解
a.ClusterIP
a.基本概念
默认的Service类型
只能在集群内部访问
提供一个稳定的虚拟IP
b.创建ClusterIP Service
kubectl expose deployment nginx --port=80 --target-port=80 --命令行创建
-------------------------------------------------------------------------------------------------
YAML示例:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
spec:
type: ClusterIP
selector:
app: nginx
ports:
- protocol: TCP
port: 80 # Service端口
targetPort: 80 # Pod端口
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-service.yaml
c.访问ClusterIP Service
kubectl get svc nginx-service --查看Service
-------------------------------------------------------------------------------------------------
在集群内访问:
curl http://nginx-service.default.svc.cluster.local
curl http://nginx-service --同命名空间下可省略后缀
curl http://<ClusterIP>:80
d.查看Endpoints
kubectl get endpoints nginx-service --查看后端Pod
-------------------------------------------------------------------------------------------------
输出示例:
NAME ENDPOINTS AGE
nginx-service 10.244.1.5:80,10.244.2.6:80 1m
b.NodePort
a.基本概念
在所有节点上开放一个端口
外部可以通过<NodeIP>:<NodePort>访问
端口范围:30000-32767(默认)
b.创建NodePort Service
kubectl expose deployment nginx --type=NodePort --port=80 --命令行创建
-------------------------------------------------------------------------------------------------
YAML示例:
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80 # Service端口
targetPort: 80 # Pod端口
nodePort: 30080 # 节点端口(可选,不指定则自动分配)
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-nodeport.yaml
c.访问NodePort Service
kubectl get svc nginx-nodeport --查看Service
-------------------------------------------------------------------------------------------------
外部访问:
curl http://<任意NodeIP>:30080
-------------------------------------------------------------------------------------------------
内部访问:
curl http://nginx-nodeport --通过ClusterIP访问
d.自定义端口范围
修改API Server配置:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
-------------------------------------------------------------------------------------------------
添加参数:
--service-node-port-range=20000-40000
-------------------------------------------------------------------------------------------------
重启生效
c.LoadBalancer
a.基本概念
云平台提供的负载均衡器
自动创建外部负载均衡器
需要云平台支持(AWS、GCP、Azure等)
b.创建LoadBalancer Service
YAML示例:
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-lb.yaml
c.查看LoadBalancer
kubectl get svc nginx-lb --查看Service
-------------------------------------------------------------------------------------------------
输出示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-lb LoadBalancer 10.96.100.10 203.0.113.10 80:31234/TCP 1m
-------------------------------------------------------------------------------------------------
外部访问:
curl http://203.0.113.10
d.本地测试LoadBalancer(使用MetalLB)
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.0/config/manifests/metallb-native.yaml
-------------------------------------------------------------------------------------------------
配置IP地址池:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.240-192.168.1.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
-------------------------------------------------------------------------------------------------
kubectl apply -f metallb-config.yaml
d.ExternalName
a.基本概念
将Service映射到外部DNS名称
不创建ClusterIP
通过DNS CNAME记录实现
b.创建ExternalName Service
YAML示例:
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: mysql.example.com
-------------------------------------------------------------------------------------------------
kubectl apply -f external-db.yaml
c.访问ExternalName Service
在Pod内访问:
mysql -h external-db -u user -p
-------------------------------------------------------------------------------------------------
自动解析为:mysql.example.com
d.使用场景
访问外部数据库
访问外部API服务
集群迁移时的过渡方案
03.Ingress详解
a.Nginx Ingress
a.安装Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.0/deploy/static/provider/cloud/deploy.yaml
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get pods -n ingress-nginx --查看Ingress Controller Pod
kubectl get svc -n ingress-nginx --查看Ingress Service
b.创建基本Ingress
YAML示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-ingress.yaml
c.配置多域名
YAML示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-domain-ingress
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8080
d.配置TLS/SSL
创建证书Secret:
kubectl create secret tls example-tls \
--cert=path/to/tls.crt \
--key=path/to/tls.key
-------------------------------------------------------------------------------------------------
配置HTTPS Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- www.example.com
secretName: example-tls
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
e.常用注解
nginx.ingress.kubernetes.io/rewrite-target: / --URL重写
nginx.ingress.kubernetes.io/ssl-redirect: "true" --强制HTTPS
nginx.ingress.kubernetes.io/proxy-body-size: "100m" --上传文件大小限制
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" --连接超时
nginx.ingress.kubernetes.io/proxy-send-timeout: "600" --发送超时
nginx.ingress.kubernetes.io/proxy-read-timeout: "600" --读取超时
nginx.ingress.kubernetes.io/rate-limit: "100" --限流
b.Traefik
a.安装Traefik
使用Helm安装:
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
helm install traefik traefik/traefik -n kube-system
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get pods -n kube-system | grep traefik
kubectl get svc -n kube-system | grep traefik
b.创建Traefik Ingress
YAML示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
c.配置中间件
YAML示例:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
spec:
basicAuth:
secret: authsecret
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-auth-ingress
annotations:
traefik.ingress.kubernetes.io/router.middlewares: default-auth-middleware@kubernetescrd
spec:
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 80
d.Dashboard访问
kubectl port-forward -n kube-system $(kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik -o name) 9000:9000
-------------------------------------------------------------------------------------------------
访问:http://localhost:9000/dashboard/
c.配置示例
a.基于路径的路由
YAML示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-ingress
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: default-service
port:
number: 80
b.配置基本认证
创建认证文件:
htpasswd -c auth myuser --创建密码文件
-------------------------------------------------------------------------------------------------
创建Secret:
kubectl create secret generic basic-auth --from-file=auth
-------------------------------------------------------------------------------------------------
配置Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auth-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
spec:
ingressClassName: nginx
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 80
c.配置白名单
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whitelist-ingress
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.1.0/24,10.0.0.0/8"
spec:
ingressClassName: nginx
rules:
- host: internal.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: internal-service
port:
number: 80
d.配置跨域(CORS)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cors-ingress
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
04.网络策略
a.NetworkPolicy
a.基本概念
默认情况下所有Pod之间可以互相通信
NetworkPolicy用于限制Pod之间的网络流量
需要CNI插件支持(如Calico、Weave Net)
Flannel不支持NetworkPolicy
b.策略类型
Ingress 入站流量控制
Egress 出站流量控制
c.选择器
podSelector 选择应用策略的Pod
namespaceSelector 选择允许通信的命名空间
ipBlock 选择允许的IP地址段
b.入站规则
a.默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: default
spec:
podSelector: {} --选择所有Pod
policyTypes:
- Ingress
-------------------------------------------------------------------------------------------------
kubectl apply -f deny-all-ingress.yaml
b.允许特定Pod访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
namespace: default
spec:
podSelector:
matchLabels:
app: backend --应用到backend Pod
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend --只允许frontend Pod访问
ports:
- protocol: TCP
port: 8080
c.允许特定命名空间访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-namespace
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
env: production --只允许production命名空间访问
ports:
- protocol: TCP
port: 80
d.允许特定IP段访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-external
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 192.168.1.0/24 --允许的IP段
except:
- 192.168.1.100/32 --排除的IP
ports:
- protocol: TCP
port: 80
c.出站规则
a.默认拒绝所有出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
b.允许访问特定服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-to-database
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: mysql --只允许访问mysql Pod
ports:
- protocol: TCP
port: 3306
c.允许DNS查询
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
d.组合入站和出站规则
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to: --允许DNS查询
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
05.DNS服务
a.CoreDNS配置
a.CoreDNS介绍
Kubernetes默认的DNS服务
替代了之前的kube-dns
基于插件架构,功能强大
b.查看CoreDNS配置
kubectl get configmap coredns -n kube-system -o yaml --查看配置
-------------------------------------------------------------------------------------------------
配置示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
c.自定义DNS解析
编辑CoreDNS ConfigMap:
kubectl edit configmap coredns -n kube-system
-------------------------------------------------------------------------------------------------
添加自定义域名解析:
data:
Corefile: |
.:53 {
errors
health
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
hosts { --添加自定义hosts
192.168.1.100 custom.example.com
fallthrough
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
-------------------------------------------------------------------------------------------------
重启CoreDNS:
kubectl rollout restart deployment coredns -n kube-system
d.配置上游DNS
修改forward配置:
forward . 8.8.8.8 8.8.4.4 --使用Google DNS
forward . 114.114.114.114 --使用国内DNS
b.服务发现
a.Service DNS记录
格式:<service-name>.<namespace>.svc.cluster.local
-------------------------------------------------------------------------------------------------
示例:
nginx-service.default.svc.cluster.local
mysql-service.database.svc.cluster.local
b.Pod DNS记录
格式:<pod-ip-with-dashes>.<namespace>.pod.cluster.local
-------------------------------------------------------------------------------------------------
示例:
10-244-1-5.default.pod.cluster.local
c.DNS搜索域
Pod内默认DNS搜索域:
<namespace>.svc.cluster.local
svc.cluster.local
cluster.local
-------------------------------------------------------------------------------------------------
简化访问:
同命名空间:curl http://nginx-service
跨命名空间:curl http://nginx-service.default
完整域名:curl http://nginx-service.default.svc.cluster.local
d.Headless Service
ClusterIP设置为None
返回所有Pod的IP地址
用于StatefulSet
-------------------------------------------------------------------------------------------------
示例:
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
-------------------------------------------------------------------------------------------------
DNS查询返回所有Pod IP:
nslookup nginx-headless.default.svc.cluster.local
c.DNS调试
a.测试DNS解析
创建测试Pod:
kubectl run dnsutils --image=tutum/dnsutils --command -- sleep infinity
-------------------------------------------------------------------------------------------------
进入Pod测试:
kubectl exec -it dnsutils -- /bin/bash
-------------------------------------------------------------------------------------------------
测试解析:
nslookup kubernetes.default.svc.cluster.local --解析Service
nslookup nginx-service --简短名称
dig kubernetes.default.svc.cluster.local --使用dig命令
b.查看DNS配置
kubectl exec -it dnsutils -- cat /etc/resolv.conf
-------------------------------------------------------------------------------------------------
输出示例:
nameserver 10.96.0.10 --CoreDNS Service IP
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
c.常见DNS问题
问题1:无法解析Service名称
解决:检查CoreDNS Pod是否正常运行
kubectl get pods -n kube-system | grep coredns
-------------------------------------------------------------------------------------------------
问题2:解析慢
解决:调整ndots参数,减少不必要的DNS查询
在Pod spec中设置:
dnsConfig:
options:
- name: ndots
value: "1"
-------------------------------------------------------------------------------------------------
问题3:CoreDNS CrashLoopBackOff
解决:检查/etc/resolv.conf配置
确保没有环路引用
d.性能优化
增加CoreDNS副本数:
kubectl scale deployment coredns -n kube-system --replicas=3
-------------------------------------------------------------------------------------------------
调整缓存时间:
cache 300 --缓存5分钟
-------------------------------------------------------------------------------------------------
启用自动伸缩:
kubectl autoscale deployment coredns -n kube-system --min=2 --max=10 --cpu-percent=80
3.5 [2]terminal
00.汇总
a.组件
Pod
Container(容器)
Label(label)(标签)
Replication Controller(复制控制器)
Service(enter image description here)(服务)
Node(节点)
Kubernetes Master(Kubernetes主节点)
b.容器
RunC
Docker
podman
Containerted
01.kubectl基础
a.配置管理
a.kubeconfig文件
默认位置:~/.kube/config
包含集群信息、用户凭证、上下文配置
-------------------------------------------------------------------------------------------------
查看当前配置:
kubectl config view --查看完整配置
kubectl config view --minify --查看当前上下文配置
b.集群配置
kubectl config get-clusters --查看所有集群
-------------------------------------------------------------------------------------------------
添加集群:
kubectl config set-cluster my-cluster \
--server=https://192.168.1.10:6443 \
--certificate-authority=/path/to/ca.crt
-------------------------------------------------------------------------------------------------
删除集群:
kubectl config delete-cluster my-cluster
c.用户配置
kubectl config get-users --查看所有用户
-------------------------------------------------------------------------------------------------
添加用户:
kubectl config set-credentials my-user \
--client-certificate=/path/to/client.crt \
--client-key=/path/to/client.key
-------------------------------------------------------------------------------------------------
使用Token认证:
kubectl config set-credentials my-user --token=<token>
d.合并配置文件
export KUBECONFIG=~/.kube/config:~/.kube/config2 --临时合并
-------------------------------------------------------------------------------------------------
永久合并:
KUBECONFIG=~/.kube/config:~/.kube/config2 kubectl config view --flatten > ~/.kube/merged-config
mv ~/.kube/merged-config ~/.kube/config
b.上下文切换
a.查看上下文
kubectl config get-contexts --查看所有上下文
kubectl config current-context --查看当前上下文
b.创建上下文
kubectl config set-context my-context \
--cluster=my-cluster \
--user=my-user \
--namespace=default
c.切换上下文
kubectl config use-context my-context --切换到指定上下文
-------------------------------------------------------------------------------------------------
临时使用不同上下文:
kubectl get pods --context=other-context
d.修改当前命名空间
kubectl config set-context --current --namespace=my-namespace --修改当前上下文的命名空间
e.重命名上下文
kubectl config rename-context old-name new-name
f.删除上下文
kubectl config delete-context my-context
c.命令补全
a.Bash补全
安装bash-completion:
apt-get install bash-completion --Ubuntu/Debian
yum install bash-completion --CentOS/RHEL
-------------------------------------------------------------------------------------------------
启用kubectl补全:
echo 'source <(kubectl completion bash)' >>~/.bashrc
source ~/.bashrc
-------------------------------------------------------------------------------------------------
设置别名补全:
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
b.Zsh补全
echo 'source <(kubectl completion zsh)' >>~/.zshrc
source ~/.zshrc
-------------------------------------------------------------------------------------------------
如果遇到问题,可能需要:
echo 'autoload -Uz compinit' >>~/.zshrc
echo 'compinit' >>~/.zshrc
c.Fish补全
kubectl completion fish | source
-------------------------------------------------------------------------------------------------
永久启用:
kubectl completion fish > ~/.config/fish/completions/kubectl.fish
d.常用别名
alias k='kubectl'
alias kg='kubectl get'
alias kd='kubectl describe'
alias kdel='kubectl delete'
alias kl='kubectl logs'
alias ke='kubectl edit'
alias kx='kubectl exec -it'
alias ka='kubectl apply -f'
02.资源查看
a.get命令
a.查看Pod
kubectl get pods --当前命名空间的Pod
kubectl get pods -A --所有命名空间的Pod
kubectl get pods -n kube-system --指定命名空间
kubectl get pods -o wide --详细信息(节点、IP等)
kubectl get pods -o json --JSON格式输出
kubectl get pods -o yaml --YAML格式输出
kubectl get pods --show-labels --显示标签
kubectl get pods -l app=nginx --按标签过滤
kubectl get pods --field-selector status.phase=Running --按字段过滤
kubectl get pods --sort-by=.metadata.creationTimestamp --按创建时间排序
b.查看Deployment
kubectl get deployments --查看Deployment
kubectl get deploy --缩写形式
kubectl get deploy -o wide --详细信息
kubectl get deploy nginx -o yaml --查看YAML配置
c.查看Service
kubectl get services --查看Service
kubectl get svc --缩写形式
kubectl get svc -o wide --显示Endpoints
d.查看所有资源
kubectl get all --当前命名空间所有资源
kubectl get all -A --所有命名空间
-------------------------------------------------------------------------------------------------
注意:get all不包括ConfigMap、Secret、PVC等资源
e.自定义输出
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName
-------------------------------------------------------------------------------------------------
输出示例:
NAME STATUS NODE
nginx-7c5ddbdf54-abc12 Running node1
nginx-7c5ddbdf54-def34 Running node2
f.监听资源变化
kubectl get pods -w --实时监听Pod变化
kubectl get pods -w -o wide --监听并显示详细信息
b.describe命令
a.查看Pod详情
kubectl describe pod nginx-7c5ddbdf54-abc12 --查看Pod详细信息
-------------------------------------------------------------------------------------------------
输出包含:
基本信息:名称、命名空间、标签、状态
容器信息:镜像、端口、资源限制
条件:初始化状态、就绪状态
事件:创建、调度、拉取镜像等事件
b.查看Deployment详情
kubectl describe deployment nginx --查看Deployment详情
-------------------------------------------------------------------------------------------------
输出包含:
副本信息:期望副本、当前副本、可用副本
策略配置:更新策略、滚动更新参数
Pod模板:容器配置、卷挂载
事件:扩缩容、滚动更新事件
c.查看Service详情
kubectl describe service nginx --查看Service详情
-------------------------------------------------------------------------------------------------
输出包含:
类型:ClusterIP、NodePort、LoadBalancer
IP地址:ClusterIP、ExternalIP
端口映射:Port、TargetPort、NodePort
Endpoints:后端Pod列表
d.查看Node详情
kubectl describe node node1 --查看节点详情
-------------------------------------------------------------------------------------------------
输出包含:
节点信息:操作系统、内核版本、容器运行时
资源容量:CPU、内存、Pod数量
资源分配:已分配资源、可用资源
条件:Ready、MemoryPressure、DiskPressure
运行的Pod列表
e.查看事件
kubectl describe pod nginx | grep -A 10 Events --只查看事件部分
c.logs命令
a.查看Pod日志
kubectl logs nginx-7c5ddbdf54-abc12 --查看Pod日志
kubectl logs nginx-7c5ddbdf54-abc12 -f --实时跟踪日志
kubectl logs nginx-7c5ddbdf54-abc12 --tail=100 --最后100行
kubectl logs nginx-7c5ddbdf54-abc12 --since=1h --最近1小时的日志
kubectl logs nginx-7c5ddbdf54-abc12 --since-time=2023-12-16T10:00:00Z --指定时间之后的日志
b.多容器Pod日志
kubectl logs nginx-7c5ddbdf54-abc12 -c nginx --指定容器
kubectl logs nginx-7c5ddbdf54-abc12 --all-containers=true --所有容器日志
c.查看之前容器的日志
kubectl logs nginx-7c5ddbdf54-abc12 --previous --查看崩溃前的日志
d.按标签查看日志
kubectl logs -l app=nginx --查看所有匹配标签的Pod日志
kubectl logs -l app=nginx -f --实时跟踪
e.导出日志
kubectl logs nginx-7c5ddbdf54-abc12 > nginx.log --导出到文件
kubectl logs nginx-7c5ddbdf54-abc12 --since=1h > nginx-recent.log --导出最近日志
03.资源操作
a.create/apply
a.create命令
kubectl create -f nginx.yaml --从文件创建资源
kubectl create -f ./manifests/ --从目录创建资源
kubectl create -f https://example.com/nginx.yaml --从URL创建
-------------------------------------------------------------------------------------------------
快速创建资源:
kubectl create deployment nginx --image=nginx:1.21 --创建Deployment
kubectl create service clusterip nginx --tcp=80:80 --创建Service
kubectl create configmap my-config --from-literal=key1=value1 --创建ConfigMap
kubectl create secret generic my-secret --from-literal=password=123456 --创建Secret
kubectl create namespace dev --创建命名空间
-------------------------------------------------------------------------------------------------
生成YAML模板:
kubectl create deployment nginx --image=nginx:1.21 --dry-run=client -o yaml > nginx-deploy.yaml
b.apply命令
kubectl apply -f nginx.yaml --应用配置(创建或更新)
kubectl apply -f ./manifests/ --应用目录中所有配置
kubectl apply -R -f ./manifests/ --递归应用子目录
-------------------------------------------------------------------------------------------------
声明式管理:
kubectl apply -f nginx.yaml --第一次创建
vim nginx.yaml --修改配置
kubectl apply -f nginx.yaml --第二次更新
c.create vs apply
create 命令式创建,资源必须不存在
重复执行会报错
apply 声明式管理,可重复执行
推荐使用,支持增量更新
d.从标准输入创建
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
EOF
b.edit/patch
a.edit命令
kubectl edit deployment nginx --使用默认编辑器编辑
kubectl edit deployment nginx -o yaml --强制使用YAML格式
-------------------------------------------------------------------------------------------------
设置默认编辑器:
export KUBE_EDITOR="vim" --使用vim
export KUBE_EDITOR="nano" --使用nano
-------------------------------------------------------------------------------------------------
编辑后自动应用,保存即生效
b.patch命令(JSON Patch)
kubectl patch deployment nginx -p '{"spec":{"replicas":3}}' --修改副本数
-------------------------------------------------------------------------------------------------
修改镜像:
kubectl patch deployment nginx -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.22"}]}}}}'
c.patch命令(Merge Patch)
kubectl patch deployment nginx --type merge -p '
spec:
replicas: 5
'
d.patch命令(Strategic Merge Patch)
kubectl patch deployment nginx --type strategic -p '
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.22
'
e.实用patch示例
修改副本数:
kubectl patch deployment nginx -p '{"spec":{"replicas":5}}'
-------------------------------------------------------------------------------------------------
添加标签:
kubectl patch deployment nginx -p '{"metadata":{"labels":{"env":"prod"}}}'
-------------------------------------------------------------------------------------------------
修改资源限制:
kubectl patch deployment nginx -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","resources":{"limits":{"cpu":"200m"}}}]}}}}'
c.delete命令
a.删除资源
kubectl delete pod nginx --删除Pod
kubectl delete deployment nginx --删除Deployment
kubectl delete service nginx --删除Service
kubectl delete -f nginx.yaml --根据文件删除
kubectl delete -f ./manifests/ --删除目录中所有资源
b.按标签删除
kubectl delete pods -l app=nginx --删除匹配标签的Pod
kubectl delete all -l app=nginx --删除所有匹配资源
c.删除所有资源
kubectl delete pods --all --删除当前命名空间所有Pod
kubectl delete all --all --删除当前命名空间所有资源
kubectl delete namespace dev --删除命名空间及其所有资源
d.强制删除
kubectl delete pod nginx --force --grace-period=0 --立即删除,不等待优雅终止
-------------------------------------------------------------------------------------------------
注意:强制删除可能导致数据丢失,谨慎使用
e.删除卡住的资源
kubectl delete pod nginx --grace-period=0 --force --强制删除
-------------------------------------------------------------------------------------------------
如果仍然无法删除,移除finalizer:
kubectl patch pod nginx -p '{"metadata":{"finalizers":null}}'
04.调试命令
a.exec进入容器
a.基本用法
kubectl exec -it nginx-7c5ddbdf54-abc12 -- /bin/bash --进入容器bash
kubectl exec -it nginx-7c5ddbdf54-abc12 -- sh --进入容器sh
b.多容器Pod
kubectl exec -it nginx-7c5ddbdf54-abc12 -c nginx -- /bin/bash --指定容器
c.执行单条命令
kubectl exec nginx-7c5ddbdf54-abc12 -- ls -la /etc --查看目录
kubectl exec nginx-7c5ddbdf54-abc12 -- cat /etc/nginx/nginx.conf --查看文件
kubectl exec nginx-7c5ddbdf54-abc12 -- env --查看环境变量
kubectl exec nginx-7c5ddbdf54-abc12 -- ps aux --查看进程
d.常用调试命令
kubectl exec nginx-7c5ddbdf54-abc12 -- curl localhost:80 --测试HTTP
kubectl exec nginx-7c5ddbdf54-abc12 -- netstat -tlnp --查看端口
kubectl exec nginx-7c5ddbdf54-abc12 -- df -h --查看磁盘
kubectl exec nginx-7c5ddbdf54-abc12 -- free -h --查看内存
b.port-forward端口转发
a.转发Pod端口
kubectl port-forward pod/nginx-7c5ddbdf54-abc12 8080:80 --本地8080映射到Pod的80
-------------------------------------------------------------------------------------------------
访问:http://localhost:8080
b.转发Service端口
kubectl port-forward service/nginx 8080:80 --转发Service端口
c.转发Deployment端口
kubectl port-forward deployment/nginx 8080:80 --转发Deployment端口
d.指定监听地址
kubectl port-forward --address 0.0.0.0 pod/nginx 8080:80 --允许外部访问
kubectl port-forward --address 192.168.1.10 pod/nginx 8080:80 --指定监听IP
e.后台运行
kubectl port-forward pod/nginx 8080:80 & --后台运行
-------------------------------------------------------------------------------------------------
查看后台任务:
jobs
-------------------------------------------------------------------------------------------------
停止转发:
kill %1 --结束后台任务
c.cp文件复制
a.从Pod复制到本地
kubectl cp nginx-7c5ddbdf54-abc12:/etc/nginx/nginx.conf ./nginx.conf --复制文件
kubectl cp nginx-7c5ddbdf54-abc12:/var/log/nginx/ ./logs/ --复制目录
b.从本地复制到Pod
kubectl cp ./nginx.conf nginx-7c5ddbdf54-abc12:/etc/nginx/nginx.conf --上传文件
kubectl cp ./html/ nginx-7c5ddbdf54-abc12:/usr/share/nginx/html/ --上传目录
c.多容器Pod
kubectl cp nginx-7c5ddbdf54-abc12:/app/config.yaml ./config.yaml -c nginx --指定容器
d.跨命名空间
kubectl cp -n production nginx:/app/config.yaml ./config.yaml --指定命名空间
e.注意事项
cp命令依赖tar命令,容器内必须有tar
不支持通配符
大文件传输可能较慢
05.高级命令
a.top资源监控
a.查看节点资源
kubectl top nodes --查看节点CPU和内存使用
kubectl top nodes --sort-by=cpu --按CPU排序
kubectl top nodes --sort-by=memory --按内存排序
-------------------------------------------------------------------------------------------------
输出示例:
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node1 250m 12% 2048Mi 25%
node2 180m 9% 1536Mi 19%
b.查看Pod资源
kubectl top pods --查看Pod资源使用
kubectl top pods -A --所有命名空间
kubectl top pods --containers --显示容器级别
kubectl top pods -l app=nginx --按标签过滤
kubectl top pods --sort-by=cpu --按CPU排序
kubectl top pods --sort-by=memory --按内存排序
c.要求
需要安装Metrics Server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get deployment metrics-server -n kube-system
b.rollout滚动更新
a.更新镜像
kubectl set image deployment/nginx nginx=nginx:1.22 --更新镜像
-------------------------------------------------------------------------------------------------
或使用rollout:
kubectl rollout restart deployment/nginx --重启Deployment
b.查看更新状态
kubectl rollout status deployment/nginx --查看滚动更新状态
-------------------------------------------------------------------------------------------------
输出示例:
Waiting for deployment "nginx" rollout to finish: 1 out of 3 new replicas have been updated...
deployment "nginx" successfully rolled out
c.查看历史版本
kubectl rollout history deployment/nginx --查看历史版本
kubectl rollout history deployment/nginx --revision=2 --查看指定版本详情
d.回滚
kubectl rollout undo deployment/nginx --回滚到上一版本
kubectl rollout undo deployment/nginx --to-revision=2 --回滚到指定版本
e.暂停和恢复
kubectl rollout pause deployment/nginx --暂停更新
kubectl set image deployment/nginx nginx=nginx:1.22 --修改配置(不会触发更新)
kubectl rollout resume deployment/nginx --恢复更新
c.scale扩缩容
a.手动扩缩容
kubectl scale deployment nginx --replicas=5 --扩展到5个副本
kubectl scale deployment nginx --replicas=1 --缩减到1个副本
b.按条件扩缩容
kubectl scale deployment nginx --replicas=3 --current-replicas=2 --只在当前为2个副本时执行
c.扩缩多个资源
kubectl scale deployment/nginx deployment/apache --replicas=3 --同时扩展多个
d.自动扩缩容(HPA)
kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80 --创建HPA
-------------------------------------------------------------------------------------------------
查看HPA:
kubectl get hpa
-------------------------------------------------------------------------------------------------
输出示例:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 45%/80% 2 10 3 5m
e.删除HPA
kubectl delete hpa nginx
06.常用命令汇总
a.快速查看
kubectl get pods -o wide --查看Pod详情
kubectl get nodes --查看节点
kubectl get svc --查看Service
kubectl get deploy --查看Deployment
kubectl get all -A --查看所有资源
b.快速调试
kubectl describe pod <pod-name> --查看Pod详情
kubectl logs <pod-name> -f --实时查看日志
kubectl exec -it <pod-name> -- /bin/bash --进入容器
kubectl port-forward <pod-name> 8080:80 --端口转发
c.快速操作
kubectl apply -f <file.yaml> --应用配置
kubectl delete -f <file.yaml> --删除资源
kubectl scale deployment <name> --replicas=3 --扩缩容
kubectl rollout restart deployment/<name> --重启
kubectl rollout undo deployment/<name> --回滚
d.常用组合
查看Pod并进入:
kubectl get pods
kubectl exec -it <pod-name> -- /bin/bash
-------------------------------------------------------------------------------------------------
查看日志并跟踪:
kubectl logs <pod-name> -f --tail=100
-------------------------------------------------------------------------------------------------
删除异常Pod:
kubectl get pods | grep Error
kubectl delete pod <pod-name> --force --grace-period=0
-------------------------------------------------------------------------------------------------
批量操作:
kubectl get pods -l app=nginx -o name | xargs kubectl delete
3.6 [2]resource
01.工作负载资源
a.Pod详解
a.Pod基本概念
Kubernetes中最小的调度单位
一个Pod可以包含一个或多个容器
Pod内容器共享网络命名空间和存储卷
Pod是临时性的,不会自我修复
b.创建Pod
YAML示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: default
labels:
app: nginx
env: prod
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-pod.yaml --创建Pod
c.多容器Pod
YAML示例:
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
- name: busybox
image: busybox
command: ['sh', '-c', 'while true; do echo $(date) >> /var/log/date.log; sleep 10; done']
volumeMounts:
- name: log-volume
mountPath: /var/log
volumes:
- name: log-volume
emptyDir: {}
d.Init容器
YAML示例:
apiVersion: v1
kind: Pod
metadata:
name: init-pod
spec:
initContainers:
- name: init-service
image: busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done']
containers:
- name: main-app
image: nginx:1.21
-------------------------------------------------------------------------------------------------
Init容器特点:
在主容器启动前运行
按顺序依次执行
必须全部成功才会启动主容器
适合初始化任务、等待依赖服务等场景
e.Pod生命周期
阶段说明:
Pending Pod已创建,等待调度或拉取镜像
Running 至少有一个容器正在运行
Succeeded 所有容器成功终止
Failed 至少有一个容器失败终止
Unknown 无法获取Pod状态
-------------------------------------------------------------------------------------------------
查看Pod状态:
kubectl get pods --查看Pod状态
kubectl describe pod <pod-name> --查看详细信息
f.容器探针
LivenessProbe示例:
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
containers:
- name: nginx
image: nginx:1.21
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 3
periodSeconds: 3
-------------------------------------------------------------------------------------------------
ReadinessProbe示例:
apiVersion: v1
kind: Pod
metadata:
name: readiness-pod
spec:
containers:
- name: nginx
image: nginx:1.21
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
-------------------------------------------------------------------------------------------------
StartupProbe示例:
apiVersion: v1
kind: Pod
metadata:
name: startup-pod
spec:
containers:
- name: slow-app
image: myapp:latest
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10
-------------------------------------------------------------------------------------------------
探针类型对比:
LivenessProbe 检测容器是否存活,失败则重启容器
ReadinessProbe 检测容器是否就绪,失败则从Service移除
StartupProbe 检测容器是否启动完成,适合慢启动应用
g.资源限制
requests和limits示例:
apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: app
image: myapp:latest
resources:
requests: --最小资源请求
memory: "128Mi"
cpu: "250m"
limits: --最大资源限制
memory: "256Mi"
cpu: "500m"
-------------------------------------------------------------------------------------------------
QoS等级:
Guaranteed requests == limits,最高优先级
Burstable requests < limits,中等优先级
BestEffort 未设置requests/limits,最低优先级
b.Deployment详解
a.基本概念
用于管理无状态应用
支持滚动更新和回滚
自动维护指定数量的Pod副本
通过ReplicaSet管理Pod
b.创建Deployment
YAML示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
labels:
app: nginx
spec:
replicas: 3 --副本数量
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-deployment.yaml --创建Deployment
kubectl get deployments --查看Deployment
kubectl get rs --查看ReplicaSet
kubectl get pods --查看Pod
c.更新策略
滚动更新(RollingUpdate):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 --最多超出副本数1个
maxUnavailable: 1 --最多不可用副本数1个
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22
-------------------------------------------------------------------------------------------------
重建更新(Recreate):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
strategy:
type: Recreate --先删除所有旧Pod,再创建新Pod
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22
d.滚动更新操作
kubectl set image deployment/nginx-deployment nginx=nginx:1.22 --更新镜像
kubectl rollout status deployment/nginx-deployment --查看更新状态
kubectl rollout history deployment/nginx-deployment --查看历史版本
kubectl rollout undo deployment/nginx-deployment --回滚到上一版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2 --回滚到指定版本
kubectl rollout pause deployment/nginx-deployment --暂停更新
kubectl rollout resume deployment/nginx-deployment --恢复更新
e.扩缩容
kubectl scale deployment nginx-deployment --replicas=5 --手动扩容到5个副本
kubectl scale deployment nginx-deployment --replicas=1 --手动缩容到1个副本
-------------------------------------------------------------------------------------------------
自动扩缩容(HPA):
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=80
kubectl get hpa --查看HPA状态
f.常用操作
kubectl get deployment nginx-deployment -o yaml --导出YAML配置
kubectl edit deployment nginx-deployment --在线编辑
kubectl delete deployment nginx-deployment --删除Deployment
kubectl describe deployment nginx-deployment --查看详细信息
c.StatefulSet详解
a.基本概念
用于管理有状态应用
提供稳定的网络标识符
提供稳定的持久化存储
有序的部署、扩展、删除和滚动更新
b.创建StatefulSet
YAML示例:
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
clusterIP: None --Headless Service
selector:
app: nginx-stateful
ports:
- port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-stateful
spec:
serviceName: nginx-headless --关联Headless Service
replicas: 3
selector:
matchLabels:
app: nginx-stateful
template:
metadata:
labels:
app: nginx-stateful
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-statefulset.yaml --创建StatefulSet
c.StatefulSet特性
Pod命名规则:
<statefulset-name>-0
<statefulset-name>-1
<statefulset-name>-2
-------------------------------------------------------------------------------------------------
DNS记录:
<pod-name>.<service-name>.<namespace>.svc.cluster.local
示例:
nginx-stateful-0.nginx-headless.default.svc.cluster.local
nginx-stateful-1.nginx-headless.default.svc.cluster.local
-------------------------------------------------------------------------------------------------
存储特性:
每个Pod有独立的PVC
PVC不会随Pod删除而删除
重新创建Pod会关联到相同的PVC
d.扩缩容
kubectl scale statefulset nginx-stateful --replicas=5 --扩容
kubectl scale statefulset nginx-stateful --replicas=1 --缩容
-------------------------------------------------------------------------------------------------
扩缩容特点:
按顺序创建Pod(0,1,2,3,4)
按逆序删除Pod(4,3,2,1,0)
必须等待前一个Pod就绪才会创建下一个
e.更新策略
滚动更新(RollingUpdate):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-stateful
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 2 --只更新序号>=2的Pod
replicas: 3
serviceName: nginx-headless
selector:
matchLabels:
app: nginx-stateful
template:
metadata:
labels:
app: nginx-stateful
spec:
containers:
- name: nginx
image: nginx:1.22
-------------------------------------------------------------------------------------------------
OnDelete策略:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-stateful
spec:
updateStrategy:
type: OnDelete --手动删除Pod才会更新
f.常用操作
kubectl get statefulset --查看StatefulSet
kubectl get pods -l app=nginx-stateful --查看Pod
kubectl delete statefulset nginx-stateful --删除StatefulSet
kubectl delete statefulset nginx-stateful --cascade=orphan --删除StatefulSet但保留Pod
d.DaemonSet详解
a.基本概念
在每个节点上运行一个Pod副本
新节点加入时自动创建Pod
节点移除时自动删除Pod
适合运行集群级别的守护进程
b.创建DaemonSet
YAML示例:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-daemonset
namespace: kube-system
labels:
app: fluentd
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluentd:v1.14
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
-------------------------------------------------------------------------------------------------
kubectl apply -f fluentd-daemonset.yaml --创建DaemonSet
c.节点选择
使用nodeSelector:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonset
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
disk: ssd --只在有ssd标签的节点运行
containers:
- name: nginx
image: nginx:1.21
-------------------------------------------------------------------------------------------------
使用nodeAffinity:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonset
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/worker
operator: Exists
containers:
- name: nginx
image: nginx:1.21
d.更新策略
滚动更新(RollingUpdate):
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-daemonset
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 --最多1个节点不可用
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluentd:v1.15
-------------------------------------------------------------------------------------------------
OnDelete策略:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-daemonset
spec:
updateStrategy:
type: OnDelete --手动删除Pod才会更新
e.常用场景
日志收集:
fluentd、filebeat等日志收集器
-------------------------------------------------------------------------------------------------
监控代理:
node-exporter、cAdvisor等监控工具
-------------------------------------------------------------------------------------------------
网络插件:
calico-node、kube-proxy等网络组件
-------------------------------------------------------------------------------------------------
存储插件:
ceph-osd、glusterd等存储组件
f.常用操作
kubectl get daemonset -A --查看所有DaemonSet
kubectl describe daemonset fluentd-daemonset -n kube-system --查看详细信息
kubectl delete daemonset fluentd-daemonset -n kube-system --删除DaemonSet
e.Job/CronJob详解
a.Job基本概念
用于运行一次性任务
确保Pod成功完成指定次数
支持并行执行
任务完成后Pod不会自动删除
b.创建Job
YAML示例:
apiVersion: batch/v1
kind: Job
metadata:
name: pi-job
spec:
completions: 5 --成功完成5次
parallelism: 2 --并行度为2
template:
spec:
containers:
- name: pi
image: perl:5.34
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never --失败不重启
backoffLimit: 4 --最多重试4次
-------------------------------------------------------------------------------------------------
kubectl apply -f pi-job.yaml --创建Job
kubectl get jobs --查看Job状态
kubectl get pods --查看Job的Pod
c.Job完成模式
Non-parallel Jobs:
apiVersion: batch/v1
kind: Job
metadata:
name: single-job
spec:
template:
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo Hello && sleep 30']
restartPolicy: Never
-------------------------------------------------------------------------------------------------
Parallel Jobs with fixed completion count:
apiVersion: batch/v1
kind: Job
metadata:
name: parallel-job
spec:
completions: 10 --完成10次
parallelism: 3 --同时运行3个Pod
template:
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo Processing && sleep 10']
restartPolicy: Never
-------------------------------------------------------------------------------------------------
Parallel Jobs with work queue:
apiVersion: batch/v1
kind: Job
metadata:
name: queue-job
spec:
parallelism: 5 --并行度为5
template:
spec:
containers:
- name: worker
image: myworker:latest
command: ['./worker']
restartPolicy: Never
d.CronJob基本概念
用于定时任务
基于Cron表达式调度
自动创建Job
支持任务历史记录管理
e.创建CronJob
YAML示例:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello-cronjob
spec:
schedule: "*/5 * * * *" --每5分钟执行一次
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ['sh', '-c', 'echo Hello from CronJob']
restartPolicy: OnFailure
successfulJobsHistoryLimit: 3 --保留3个成功的Job
failedJobsHistoryLimit: 1 --保留1个失败的Job
-------------------------------------------------------------------------------------------------
kubectl apply -f hello-cronjob.yaml --创建CronJob
f.Cron表达式
格式说明:
* * * * *
│ │ │ │ │
│ │ │ │ └─ 星期几 (0-6, 0表示周日)
│ │ │ └─── 月份 (1-12)
│ │ └───── 日期 (1-31)
│ └─────── 小时 (0-23)
└───────── 分钟 (0-59)
-------------------------------------------------------------------------------------------------
常用示例:
*/5 * * * * --每5分钟
0 * * * * --每小时
0 0 * * * --每天午夜
0 0 * * 0 --每周日午夜
0 0 1 * * --每月1号午夜
0 2 * * 1-5 --工作日凌晨2点
g.CronJob并发策略
Allow(默认):
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-allow
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Allow --允许并发执行
jobTemplate:
spec:
template:
spec:
containers:
- name: job
image: busybox
command: ['sh', '-c', 'sleep 120']
restartPolicy: OnFailure
-------------------------------------------------------------------------------------------------
Forbid:
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-forbid
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Forbid --禁止并发,跳过新任务
jobTemplate:
spec:
template:
spec:
containers:
- name: job
image: busybox
command: ['sh', '-c', 'sleep 120']
restartPolicy: OnFailure
-------------------------------------------------------------------------------------------------
Replace:
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-replace
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Replace --替换旧任务
jobTemplate:
spec:
template:
spec:
containers:
- name: job
image: busybox
command: ['sh', '-c', 'sleep 120']
restartPolicy: OnFailure
h.常用操作
kubectl get cronjobs --查看CronJob
kubectl get jobs --查看Job
kubectl describe cronjob hello-cronjob --查看详细信息
kubectl delete cronjob hello-cronjob --删除CronJob
02.配置资源
a.ConfigMap详解
a.基本概念
用于存储非机密的配置数据
以键值对形式存储
可以被Pod引用
支持多种使用方式
b.创建ConfigMap
从字面值创建:
kubectl create configmap app-config \
--from-literal=db_host=mysql.example.com \
--from-literal=db_port=3306 \
--from-literal=log_level=info
-------------------------------------------------------------------------------------------------
从文件创建:
echo "server {}" > nginx.conf
kubectl create configmap nginx-config --from-file=nginx.conf
-------------------------------------------------------------------------------------------------
从目录创建:
kubectl create configmap app-configs --from-file=./configs/
-------------------------------------------------------------------------------------------------
从YAML创建:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
db_host: mysql.example.com
db_port: "3306"
log_level: info
application.properties: |
server.port=8080
spring.datasource.url=jdbc:mysql://mysql:3306/mydb
-------------------------------------------------------------------------------------------------
kubectl apply -f app-config.yaml
c.使用ConfigMap
环境变量方式:
apiVersion: v1
kind: Pod
metadata:
name: config-env-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'echo DB_HOST=$DB_HOST && sleep 3600']
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: db_host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: db_port
-------------------------------------------------------------------------------------------------
全部导入环境变量:
apiVersion: v1
kind: Pod
metadata:
name: config-envfrom-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'env && sleep 3600']
envFrom:
- configMapRef:
name: app-config
-------------------------------------------------------------------------------------------------
挂载为Volume:
apiVersion: v1
kind: Pod
metadata:
name: config-volume-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
-------------------------------------------------------------------------------------------------
挂载指定key:
apiVersion: v1
kind: Pod
metadata:
name: config-item-pod
spec:
containers:
- name: nginx
image: nginx:1.21
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config-volume
configMap:
name: nginx-config
items:
- key: nginx.conf
path: nginx.conf
d.更新ConfigMap
kubectl edit configmap app-config --在线编辑
-------------------------------------------------------------------------------------------------
注意事项:
环境变量方式:需要重启Pod才能生效
Volume挂载方式:会自动更新(可能有延迟)
e.常用操作
kubectl get configmaps --查看ConfigMap列表
kubectl describe configmap app-config --查看详细信息
kubectl get configmap app-config -o yaml --导出YAML
kubectl delete configmap app-config --删除ConfigMap
b.Secret详解
a.基本概念
用于存储机密数据
数据经过Base64编码
比ConfigMap更安全
支持多种类型
b.Secret类型
Opaque 通用Secret,默认类型
kubernetes.io/service-account-token ServiceAccount令牌
kubernetes.io/dockerconfigjson Docker镜像仓库认证
kubernetes.io/tls TLS证书
kubernetes.io/basic-auth 基本认证
kubernetes.io/ssh-auth SSH认证
c.创建Secret
从字面值创建:
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=P@ssw0rd
-------------------------------------------------------------------------------------------------
从文件创建:
echo -n 'admin' > username.txt
echo -n 'P@ssw0rd' > password.txt
kubectl create secret generic db-secret \
--from-file=username=username.txt \
--from-file=password=password.txt
-------------------------------------------------------------------------------------------------
从YAML创建:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: default
type: Opaque
data:
username: YWRtaW4= --Base64编码后的admin
password: UEBzc3cwcmQ= --Base64编码后的P@ssw0rd
-------------------------------------------------------------------------------------------------
kubectl apply -f db-secret.yaml
-------------------------------------------------------------------------------------------------
使用stringData(自动编码):
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
username: admin
password: P@ssw0rd
d.创建Docker镜像仓库Secret
kubectl create secret docker-registry harbor-secret \
--docker-server=harbor.example.com \
--docker-username=admin \
--docker-password=Harbor12345 \
[email protected]
-------------------------------------------------------------------------------------------------
使用示例:
apiVersion: v1
kind: Pod
metadata:
name: private-image-pod
spec:
containers:
- name: app
image: harbor.example.com/myapp:latest
imagePullSecrets:
- name: harbor-secret
e.创建TLS Secret
kubectl create secret tls tls-secret \
--cert=path/to/tls.crt \
--key=path/to/tls.key
-------------------------------------------------------------------------------------------------
使用示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts:
- www.example.com
secretName: tls-secret
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
f.使用Secret
环境变量方式:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'echo USERNAME=$USERNAME && sleep 3600']
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
-------------------------------------------------------------------------------------------------
挂载为Volume:
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: app
image: busybox
command: ['sh', '-c', 'cat /etc/secret/username && sleep 3600']
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secret
g.常用操作
kubectl get secrets --查看Secret列表
kubectl describe secret db-secret --查看详细信息
kubectl get secret db-secret -o yaml --导出YAML
kubectl delete secret db-secret --删除Secret
c.使用示例
a.Nginx配置示例
创建ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
}
-------------------------------------------------------------------------------------------------
使用ConfigMap:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: nginx-config
configMap:
name: nginx-config
b.MySQL配置示例
创建Secret:
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
stringData:
root-password: MyR00tP@ss
user: myuser
password: MyUs3rP@ss
database: mydb
-------------------------------------------------------------------------------------------------
创建ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
my.cnf: |
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max_connections=200
default-time-zone='+8:00'
-------------------------------------------------------------------------------------------------
使用示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: root-password
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: mysql-secret
key: database
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-secret
key: user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
volumeMounts:
- name: mysql-config
mountPath: /etc/mysql/conf.d/my.cnf
subPath: my.cnf
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-config
configMap:
name: mysql-config
- name: mysql-data
emptyDir: {}
03.服务资源
a.Service详解
a.基本概念
为Pod提供稳定的网络访问入口
通过标签选择器关联Pod
支持负载均衡
有固定的ClusterIP
b.Service类型
ClusterIP 集群内部访问,默认类型
NodePort 在节点上开放端口,外部可访问
LoadBalancer 云平台负载均衡器
ExternalName 映射到外部DNS名称
c.创建ClusterIP Service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
spec:
type: ClusterIP
selector:
app: nginx
ports:
- protocol: TCP
port: 80 --Service端口
targetPort: 80 --Pod端口
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-service.yaml
kubectl get svc nginx-service
d.创建NodePort Service
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 --指定节点端口(30000-32767)
-------------------------------------------------------------------------------------------------
访问方式:
curl http://<任意NodeIP>:30080
e.会话亲和性
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: ClusterIP
sessionAffinity: ClientIP --基于客户端IP的会话保持
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 --超时时间(默认10800秒)
selector:
app: nginx
ports:
- port: 80
targetPort: 80
f.Headless Service
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
clusterIP: None --不分配ClusterIP
selector:
app: nginx
ports:
- port: 80
-------------------------------------------------------------------------------------------------
用途:
StatefulSet中使用
返回所有Pod的IP地址
客户端可以自行选择要连接的Pod
b.Endpoints详解
a.基本概念
Service与Pod之间的桥梁
记录匹配selector的所有Pod IP
自动创建和更新
可以手动创建
b.查看Endpoints
kubectl get endpoints nginx-service --查看Endpoints
kubectl describe endpoints nginx-service --查看详细信息
-------------------------------------------------------------------------------------------------
输出示例:
NAME ENDPOINTS AGE
nginx-service 10.244.1.5:80,10.244.2.6:80 1m
c.手动创建Endpoints
不使用selector的Service:
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-service
subsets:
- addresses:
- ip: 192.168.1.100
- ip: 192.168.1.101
ports:
- port: 80
-------------------------------------------------------------------------------------------------
用途:
访问集群外部服务
手动管理后端
c.Ingress详解
a.基本概念
七层负载均衡器
基于域名和路径路由
支持SSL/TLS终止
需要Ingress Controller
b.创建Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
-------------------------------------------------------------------------------------------------
kubectl apply -f nginx-ingress.yaml
c.多域名路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-domain-ingress
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8080
d.TLS配置
创建TLS Secret:
kubectl create secret tls example-tls \
--cert=tls.crt \
--key=tls.key
-------------------------------------------------------------------------------------------------
配置HTTPS Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- www.example.com
secretName: example-tls
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
04.资源配额
a.ResourceQuota
a.基本概念
限制命名空间的资源使用
可以限制CPU、内存、存储等
可以限制对象数量
需要启用admission controller
b.创建ResourceQuota
计算资源配额:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: default
spec:
hard:
requests.cpu: "10" --总请求CPU
requests.memory: 20Gi --总请求内存
limits.cpu: "20" --总限制CPU
limits.memory: 40Gi --总限制内存
-------------------------------------------------------------------------------------------------
kubectl apply -f compute-quota.yaml
kubectl get resourcequota -n default
kubectl describe resourcequota compute-quota -n default
c.对象数量配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota
namespace: default
spec:
hard:
pods: "10" --Pod数量限制
services: "5" --Service数量限制
persistentvolumeclaims: "5" --PVC数量限制
secrets: "20" --Secret数量限制
configmaps: "20" --ConfigMap数量限制
d.存储配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-quota
namespace: default
spec:
hard:
requests.storage: 100Gi --总存储请求
persistentvolumeclaims: 10 --PVC数量限制
e.查看配额使用情况
kubectl get resourcequota -n default --查看配额
kubectl describe resourcequota compute-quota -n default --查看详细使用情况
-------------------------------------------------------------------------------------------------
输出示例:
Name: compute-quota
Namespace: default
Resource Used Hard
-------- ---- ----
limits.cpu 2 20
limits.memory 4Gi 40Gi
requests.cpu 1 10
requests.memory 2Gi 20Gi
b.LimitRange
a.基本概念
限制单个资源对象的资源使用
可以设置默认值
可以设置最小和最大值
作用于命名空间
b.创建LimitRange
Pod资源限制:
apiVersion: v1
kind: LimitRange
metadata:
name: pod-limit-range
namespace: default
spec:
limits:
- max:
cpu: "2" --单个Pod最大CPU
memory: 2Gi --单个Pod最大内存
min:
cpu: "100m" --单个Pod最小CPU
memory: 100Mi --单个Pod最小内存
type: Pod
-------------------------------------------------------------------------------------------------
kubectl apply -f pod-limit-range.yaml
c.Container资源限制
apiVersion: v1
kind: LimitRange
metadata:
name: container-limit-range
namespace: default
spec:
limits:
- max:
cpu: "1" --单个容器最大CPU
memory: 1Gi --单个容器最大内存
min:
cpu: "50m" --单个容器最小CPU
memory: 50Mi --单个容器最小内存
default:
cpu: "500m" --默认limits
memory: 512Mi
defaultRequest:
cpu: "250m" --默认requests
memory: 256Mi
type: Container
d.PVC存储限制
apiVersion: v1
kind: LimitRange
metadata:
name: storage-limit-range
namespace: default
spec:
limits:
- max:
storage: 10Gi --单个PVC最大存储
min:
storage: 1Gi --单个PVC最小存储
type: PersistentVolumeClaim
e.查看LimitRange
kubectl get limitrange -n default --查看LimitRange
kubectl describe limitrange container-limit-range -n default --查看详细信息
c.最佳实践
a.资源请求和限制
为所有容器设置requests和limits
requests用于调度决策
limits用于资源限制
-------------------------------------------------------------------------------------------------
推荐设置:
生产环境:requests = limits --保证QoS为Guaranteed
开发环境:requests < limits --允许突发使用
b.命名空间隔离
为每个团队或项目创建独立命名空间
为每个命名空间设置ResourceQuota
为每个命名空间设置LimitRange
c.监控和告警
监控命名空间资源使用情况
在达到配额阈值时告警
定期review和调整配额
05.RBAC权限
a.Role/ClusterRole
a.基本概念
Role:命名空间级别的权限
ClusterRole:集群级别的权限
定义可以执行的操作
通过RoleBinding/ClusterRoleBinding绑定到用户
b.创建Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""] --核心API组用空字符串表示
resources: ["pods"] --资源类型
verbs: ["get", "watch", "list"] --允许的操作
-------------------------------------------------------------------------------------------------
kubectl apply -f pod-reader-role.yaml
c.创建ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-reader-cluster
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list"]
d.常用verbs
get 获取单个资源
list 列出资源集合
watch 监视资源变化
create 创建资源
update 更新资源
patch 部分更新资源
delete 删除资源
deletecollection 批量删除资源
e.资源示例
核心组资源:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: core-resources-manager
namespace: default
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["*"] --所有操作
-------------------------------------------------------------------------------------------------
apps组资源:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: apps-manager
namespace: default
rules:
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "list", "create", "update", "delete"]
b.RoleBinding
a.基本概念
将Role绑定到用户、组或ServiceAccount
只能绑定同命名空间的Role
可以绑定ClusterRole(限定命名空间范围)
b.创建RoleBinding
绑定到用户:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: default
subjects:
- kind: User
name: jane --用户名
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
-------------------------------------------------------------------------------------------------
kubectl apply -f read-pods-binding.yaml
c.绑定到ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sa-read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: my-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
d.绑定到组
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: group-read-pods
namespace: default
subjects:
- kind: Group
name: dev-team --组名
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
e.ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-binding
subjects:
- kind: User
name: admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin --集群管理员角色
apiGroup: rbac.authorization.k8s.io
c.ServiceAccount
a.基本概念
为Pod提供身份标识
每个命名空间都有default ServiceAccount
可以为应用创建专用ServiceAccount
自动挂载token到Pod
b.创建ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa
namespace: default
-------------------------------------------------------------------------------------------------
kubectl apply -f my-sa.yaml
kubectl get sa my-sa
c.使用ServiceAccount
apiVersion: v1
kind: Pod
metadata:
name: sa-pod
namespace: default
spec:
serviceAccountName: my-sa --指定ServiceAccount
containers:
- name: app
image: busybox
command: ['sh', '-c', 'sleep 3600']
d.禁用自动挂载token
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa
automountServiceAccountToken: false --禁用自动挂载
-------------------------------------------------------------------------------------------------
或在Pod中禁用:
apiVersion: v1
kind: Pod
metadata:
name: no-token-pod
spec:
serviceAccountName: my-sa
automountServiceAccountToken: false
containers:
- name: app
image: busybox
command: ['sh', '-c', 'sleep 3600']
e.完整示例
创建ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-role
namespace: default
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-binding
namespace: default
subjects:
- kind: ServiceAccount
name: app-sa
namespace: default
roleRef:
kind: Role
name: app-role
apiGroup: rbac.authorization.k8s.io
-------------------------------------------------------------------------------------------------
使用ServiceAccount:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
serviceAccountName: app-sa
containers:
- name: app
image: myapp:latest
f.查看权限
kubectl auth can-i get pods --as=system:serviceaccount:default:app-sa --检查权限
kubectl auth can-i create deployments --as=system:serviceaccount:default:app-sa
-------------------------------------------------------------------------------------------------
查看所有权限:
kubectl get rolebindings -n default --查看RoleBinding
kubectl get clusterrolebindings --查看ClusterRoleBinding
kubectl describe rolebinding app-binding -n default --查看详细信息
3.7 [2]storage
01.存储基础
a.Volume类型
a.Volume概述
Pod中的容器重启后数据会丢失
Volume可以在容器重启时保留数据
Volume的生命周期与Pod相同
Pod删除后Volume也会被删除(除了PV)
b.常用Volume类型
emptyDir 临时存储,Pod删除时清空
hostPath 挂载宿主机目录
nfs NFS网络存储
configMap 挂载ConfigMap
secret 挂载Secret
persistentVolumeClaim 挂载PVC
downwardAPI Pod元数据
c.Volume配置示例
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: data-volume
mountPath: /usr/share/nginx/html
- name: config-volume
mountPath: /etc/config
- name: cache-volume
mountPath: /tmp/cache
volumes:
- name: data-volume
hostPath:
path: /data
type: DirectoryOrCreate
- name: config-volume
configMap:
name: app-config
- name: cache-volume
emptyDir: {}
b.emptyDir
a.基本概念
在Pod创建时创建的空目录
Pod删除时emptyDir也会被删除
同一Pod内所有容器共享emptyDir
数据存储在节点的磁盘或内存中
b.使用场景
临时缓存数据
多容器间共享数据
检查点保存
临时文件存储
c.配置示例
基本用法:
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
containers:
- name: writer
image: busybox
command: ['sh', '-c', 'echo "Hello from writer" > /data/message && sleep 3600']
volumeMounts:
- name: shared-data
mountPath: /data
- name: reader
image: busybox
command: ['sh', '-c', 'cat /data/message && sleep 3600']
volumeMounts:
- name: shared-data
mountPath: /data
volumes:
- name: shared-data
emptyDir: {}
-------------------------------------------------------------------------------------------------
使用内存存储:
apiVersion: v1
kind: Pod
metadata:
name: emptydir-memory-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: cache
mountPath: /tmp/cache
volumes:
- name: cache
emptyDir:
medium: Memory --使用内存作为存储
sizeLimit: 1Gi --限制大小为1GB
d.注意事项
emptyDir数据不会持久化
使用Memory时会占用Pod的内存限制
节点磁盘满时可能导致Pod驱逐
c.hostPath
a.基本概念
挂载宿主机的文件或目录到Pod
Pod重启后数据不会丢失
不同节点上的hostPath路径可能不同
需要谨慎使用,可能带来安全风险
b.hostPath类型
DirectoryOrCreate 目录不存在则创建
Directory 必须存在的目录
FileOrCreate 文件不存在则创建
File 必须存在的文件
Socket UNIX套接字
CharDevice 字符设备
BlockDevice 块设备
c.配置示例
挂载目录:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
hostPath:
path: /data/nginx --宿主机路径
type: DirectoryOrCreate --目录不存在则创建
-------------------------------------------------------------------------------------------------
挂载文件:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-file-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config
hostPath:
path: /etc/nginx/nginx.conf
type: File
d.使用场景
访问Docker引擎(挂载/var/run/docker.sock)
监控节点日志(挂载/var/log)
需要访问宿主机文件系统
DaemonSet中使用
e.安全注意事项
避免挂载敏感目录(如/etc、/var/lib/kubelet)
使用只读挂载(readOnly: true)
限制Pod的安全上下文
-------------------------------------------------------------------------------------------------
只读挂载示例:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-readonly-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: data
mountPath: /data
readOnly: true --只读挂载
volumes:
- name: data
hostPath:
path: /data
type: Directory
02.持久化存储
a.PersistentVolume
a.基本概念
PV是集群级别的存储资源
由管理员创建或通过StorageClass动态创建
独立于Pod的生命周期
可以被多个Pod通过PVC使用
b.PV访问模式
ReadWriteOnce(RWO) 单节点读写
ReadOnlyMany(ROX) 多节点只读
ReadWriteMany(RWX) 多节点读写
ReadWriteOncePod(RWOP) 单Pod读写(K8s 1.22+)
c.PV回收策略
Retain 保留数据,需要手动清理
Recycle 清空数据后重新可用(已废弃)
Delete 删除PV和底层存储
d.PV状态
Available 可用状态,未被绑定
Bound 已绑定到PVC
Released PVC已删除,但资源未回收
Failed 自动回收失败
e.创建NFS类型PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi --存储容量
accessModes:
- ReadWriteMany --访问模式
persistentVolumeReclaimPolicy: Retain --回收策略
nfs:
server: 192.168.1.100 --NFS服务器地址
path: /data/nfs --NFS共享路径
-------------------------------------------------------------------------------------------------
kubectl apply -f nfs-pv.yaml
kubectl get pv --查看PV状态
f.创建HostPath类型PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: hostpath-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
hostPath:
path: /data/pv --宿主机路径
type: DirectoryOrCreate
g.PV标签和选择器
apiVersion: v1
kind: PersistentVolume
metadata:
name: labeled-pv
labels:
type: fast
tier: gold
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
server: 192.168.1.100
path: /data/fast-storage
b.PersistentVolumeClaim
a.基本概念
PVC是命名空间级别的资源
用户对存储的请求
自动绑定到满足条件的PV
Pod通过PVC使用存储
b.创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany --访问模式要匹配PV
resources:
requests:
storage: 5Gi --请求容量
-------------------------------------------------------------------------------------------------
kubectl apply -f nfs-pvc.yaml
kubectl get pvc --查看PVC状态
c.使用标签选择器
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: fast-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
selector:
matchLabels:
type: fast --匹配PV的标签
d.Pod中使用PVC
apiVersion: v1
kind: Pod
metadata:
name: pvc-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
persistentVolumeClaim:
claimName: nfs-pvc --引用PVC名称
e.PVC扩容
支持扩容的StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: expandable-storage
provisioner: kubernetes.io/aws-ebs
allowVolumeExpansion: true --允许扩容
-------------------------------------------------------------------------------------------------
扩容PVC:
kubectl edit pvc my-pvc --修改spec.resources.requests.storage
-------------------------------------------------------------------------------------------------
或使用patch:
kubectl patch pvc my-pvc -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
f.查看PVC详情
kubectl get pvc --查看PVC列表
kubectl describe pvc nfs-pvc --查看PVC详情
kubectl get pvc nfs-pvc -o yaml --查看YAML配置
c.StorageClass
a.基本概念
StorageClass定义存储类型
支持动态创建PV
不同的StorageClass对应不同的存储后端
可以定义不同的性能等级
b.创建NFS StorageClass
# 安装NFS Provisioner
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=192.168.1.100 \
--set nfs.path=/data/nfs
-------------------------------------------------------------------------------------------------
创建StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: nfs.csi.k8s.io --Provisioner类型
parameters:
server: 192.168.1.100 --NFS服务器
share: /data/nfs --NFS共享路径
reclaimPolicy: Delete --回收策略
volumeBindingMode: Immediate --绑定模式
c.创建Local StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner --不支持动态创建
volumeBindingMode: WaitForFirstConsumer --延迟绑定
d.默认StorageClass
kubectl get storageclass --查看StorageClass
-------------------------------------------------------------------------------------------------
设置默认StorageClass:
kubectl patch storageclass nfs-storage -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
-------------------------------------------------------------------------------------------------
取消默认StorageClass:
kubectl patch storageclass nfs-storage -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
e.使用StorageClass动态创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs-storage --指定StorageClass
resources:
requests:
storage: 5Gi
-------------------------------------------------------------------------------------------------
如果不指定storageClassName,会使用默认StorageClass
03.动态供应
a.NFS动态供应
a.部署NFS服务器
# 在NFS服务器节点安装NFS
apt-get install -y nfs-kernel-server --Ubuntu/Debian
yum install -y nfs-utils --CentOS/RHEL
-------------------------------------------------------------------------------------------------
# 创建共享目录
mkdir -p /data/nfs
chmod 777 /data/nfs
-------------------------------------------------------------------------------------------------
# 配置NFS导出
echo "/data/nfs *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
-------------------------------------------------------------------------------------------------
# 重启NFS服务
systemctl restart nfs-server
systemctl enable nfs-server
-------------------------------------------------------------------------------------------------
# 查看NFS导出
exportfs -v
b.安装NFS Provisioner
使用Helm安装:
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm repo update
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=192.168.1.100 \
--set nfs.path=/data/nfs \
--set storageClass.name=nfs-client \
--set storageClass.defaultClass=true
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get pods -l app=nfs-subdir-external-provisioner
kubectl get storageclass
c.测试动态创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client
resources:
requests:
storage: 1Gi
-------------------------------------------------------------------------------------------------
kubectl apply -f test-pvc.yaml
kubectl get pvc test-pvc
kubectl get pv
d.测试Pod使用PVC
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo "Hello NFS" > /data/message && sleep 3600']
volumeMounts:
- name: nfs-data
mountPath: /data
volumes:
- name: nfs-data
persistentVolumeClaim:
claimName: test-pvc
-------------------------------------------------------------------------------------------------
kubectl apply -f test-pod.yaml
kubectl exec test-pod -- cat /data/message
b.Ceph动态供应
a.Ceph RBD介绍
Ceph是分布式存储系统
RBD(RADOS Block Device)提供块存储
支持快照、克隆等高级特性
适合大规模集群
b.安装Ceph CSI
helm repo add ceph-csi https://ceph.github.io/csi-charts
helm repo update
helm install ceph-csi-rbd ceph-csi/ceph-csi-rbd \
--namespace ceph-csi-rbd \
--create-namespace
c.创建Ceph StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:
clusterID: b9127830-b0cc-4e34-aa47-9d1a2e9949a8 --Ceph集群ID
pool: kubernetes --Ceph存储池
imageFeatures: layering --RBD镜像特性
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: default
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: default
csi.storage.k8s.io/fstype: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discard
d.创建Ceph Secret
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: default
type: Opaque
stringData:
userID: admin
userKey: AQBRbmVoAAAAABAAp1234567890abcdef== --Ceph用户密钥
c.云存储动态供应
a.AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: aws-ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3 --卷类型
iops: "3000" --IOPS
throughput: "125" --吞吐量(MB/s)
encrypted: "true" --加密
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
b.Azure Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azure-disk-premium
provisioner: disk.csi.azure.com
parameters:
skuName: Premium_LRS --磁盘类型
kind: Managed
cachingMode: ReadOnly
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
c.Google Cloud Persistent Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gce-pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd --磁盘类型
replication-type: regional-pd --区域复制
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
04.存储实践
a.MySQL持久化
a.创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs-client
resources:
requests:
storage: 10Gi
b.创建MySQL Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: MyP@ssw0rd
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql --MySQL数据目录
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc
-------------------------------------------------------------------------------------------------
kubectl apply -f mysql-deployment.yaml
c.创建Service
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
-------------------------------------------------------------------------------------------------
kubectl apply -f mysql-service.yaml
d.测试持久化
# 写入数据
kubectl exec -it mysql-xxxx -- mysql -uroot -pMyP@ssw0rd -e "CREATE DATABASE testdb;"
kubectl exec -it mysql-xxxx -- mysql -uroot -pMyP@ssw0rd -e "USE testdb; CREATE TABLE users (id INT, name VARCHAR(50));"
kubectl exec -it mysql-xxxx -- mysql -uroot -pMyP@ssw0rd -e "USE testdb; INSERT INTO users VALUES (1, 'Alice');"
-------------------------------------------------------------------------------------------------
# 删除Pod
kubectl delete pod mysql-xxxx
-------------------------------------------------------------------------------------------------
# 验证数据还在
kubectl exec -it mysql-yyyy -- mysql -uroot -pMyP@ssw0rd -e "USE testdb; SELECT * FROM users;"
b.Redis持久化
a.创建ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis.conf: |
appendonly yes --启用AOF持久化
appendfsync everysec --每秒同步
save 900 1 --RDB快照规则
save 300 10
save 60 10000
b.创建StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
spec:
serviceName: redis
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7.0
command: ["redis-server"]
args: ["/etc/redis/redis.conf"]
ports:
- containerPort: 6379
volumeMounts:
- name: redis-config
mountPath: /etc/redis
- name: redis-data
mountPath: /data --Redis数据目录
volumes:
- name: redis-config
configMap:
name: redis-config
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: nfs-client
resources:
requests:
storage: 5Gi
c.测试持久化
# 写入数据
kubectl exec -it redis-0 -- redis-cli SET key1 value1
kubectl exec -it redis-0 -- redis-cli GET key1
-------------------------------------------------------------------------------------------------
# 删除Pod
kubectl delete pod redis-0
-------------------------------------------------------------------------------------------------
# 验证数据还在
kubectl exec -it redis-0 -- redis-cli GET key1
c.文件共享
a.多Pod共享存储
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-pvc
spec:
accessModes:
- ReadWriteMany --多节点读写
storageClassName: nfs-client
resources:
requests:
storage: 10Gi
-------------------------------------------------------------------------------------------------
创建多个Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: shared-storage
spec:
replicas: 3
selector:
matchLabels:
app: shared-app
template:
metadata:
labels:
app: shared-app
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
volumes:
- name: shared-data
persistentVolumeClaim:
claimName: shared-pvc
b.文件上传示例
apiVersion: v1
kind: Pod
metadata:
name: file-uploader
spec:
containers:
- name: uploader
image: busybox
command: ['sh', '-c', 'while true; do echo $(date) >> /shared/upload.log; sleep 10; done']
volumeMounts:
- name: shared-data
mountPath: /shared
volumes:
- name: shared-data
persistentVolumeClaim:
claimName: shared-pvc
-------------------------------------------------------------------------------------------------
查看文件:
kubectl exec shared-storage-xxxx -- cat /usr/share/nginx/html/upload.log
c.静态网站托管
# 上传网站文件到共享存储
kubectl cp ./website/ shared-storage-xxxx:/usr/share/nginx/html/
-------------------------------------------------------------------------------------------------
# 所有nginx Pod都能访问相同的网站文件
05.CSI驱动
a.CSI介绍
a.什么是CSI
Container Storage Interface 容器存储接口
Kubernetes存储插件的标准接口
替代早期的in-tree存储插件
支持第三方存储供应商
b.CSI架构
CSI Controller 负责卷的创建、删除、挂载等
CSI Node 负责在节点上挂载卷到Pod
CSI Driver 具体存储的实现
c.CSI优势
解耦存储代码和Kubernetes核心代码
支持更多存储类型
存储插件可以独立升级
第三方可以开发自己的CSI插件
b.常用CSI驱动
a.NFS CSI Driver
部署NFS CSI:
helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs \
--namespace kube-system \
--set controller.replicas=1
-------------------------------------------------------------------------------------------------
创建StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
server: 192.168.1.100
share: /data/nfs
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
- nfsvers=4.1
b.Local Path CSI
安装Local Path Provisioner:
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
-------------------------------------------------------------------------------------------------
创建StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
c.Longhorn
安装Longhorn:
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.5.0/deploy/longhorn.yaml
-------------------------------------------------------------------------------------------------
访问UI:
kubectl port-forward -n longhorn-system svc/longhorn-frontend 8080:80
-------------------------------------------------------------------------------------------------
创建StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: longhorn
provisioner: driver.longhorn.io
allowVolumeExpansion: true
parameters:
numberOfReplicas: "3" --副本数量
staleReplicaTimeout: "2880" --过期副本超时
fromBackup: ""
d.OpenEBS
安装OpenEBS:
helm repo add openebs https://openebs.github.io/charts
helm install openebs openebs/openebs --namespace openebs --create-namespace
-------------------------------------------------------------------------------------------------
创建StorageClass(Local PV):
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: openebs-hostpath
provisioner: openebs.io/local
volumeBindingMode: WaitForFirstConsumer
c.配置示例
a.NFS CSI使用示例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-csi-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-csi
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
name: nfs-csi-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
persistentVolumeClaim:
claimName: nfs-csi-pvc
b.快照功能
创建VolumeSnapshotClass:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-snapshot-class
driver: nfs.csi.k8s.io --CSI驱动名称
deletionPolicy: Delete
-------------------------------------------------------------------------------------------------
创建快照:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: my-snapshot
spec:
volumeSnapshotClassName: csi-snapshot-class
source:
persistentVolumeClaimName: nfs-csi-pvc --源PVC
-------------------------------------------------------------------------------------------------
从快照恢复:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restored-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-csi
dataSource:
name: my-snapshot --指定快照
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
resources:
requests:
storage: 10Gi
c.存储扩容
查看是否支持扩容:
kubectl get storageclass nfs-csi -o yaml | grep allowVolumeExpansion
-------------------------------------------------------------------------------------------------
扩容PVC:
kubectl patch pvc nfs-csi-pvc -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
-------------------------------------------------------------------------------------------------
查看扩容状态:
kubectl describe pvc nfs-csi-pvc
d.存储监控
查看PV使用情况:
kubectl get pv
kubectl describe pv <pv-name>
-------------------------------------------------------------------------------------------------
查看PVC使用情况:
kubectl get pvc -A
kubectl describe pvc <pvc-name>
-------------------------------------------------------------------------------------------------
使用df查看Pod内存储:
kubectl exec <pod-name> -- df -h
01.Dashboard
a.安装Dashboard
a.获取安装文件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get pods -n kubernetes-dashboard --查看Dashboard Pod
kubectl get svc -n kubernetes-dashboard --查看Dashboard Service
b.创建管理员账号
创建ServiceAccount:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
c.获取访问Token
kubectl -n kubernetes-dashboard create token admin-user --临时Token(24小时)
-------------------------------------------------------------------------------------------------
创建永久Token:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: admin-user-secret
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: admin-user
type: kubernetes.io/service-account-token
EOF
-------------------------------------------------------------------------------------------------
获取永久Token:
kubectl get secret admin-user-secret -n kubernetes-dashboard -o jsonpath='{.data.token}' | base64 -d
b.访问Dashboard
a.kubectl proxy方式
kubectl proxy --启动代理(默认8001端口)
-------------------------------------------------------------------------------------------------
访问地址:
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
b.NodePort方式
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
-------------------------------------------------------------------------------------------------
修改type为NodePort:
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30443 --指定端口(30000-32767)
-------------------------------------------------------------------------------------------------
访问:https://<NodeIP>:30443
c.Ingress方式
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: dashboard.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
-------------------------------------------------------------------------------------------------
kubectl apply -f dashboard-ingress.yaml
-------------------------------------------------------------------------------------------------
访问:https://dashboard.example.com
d.port-forward方式
kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8443:443
-------------------------------------------------------------------------------------------------
访问:https://localhost:8443
c.Dashboard功能
a.资源查看
查看所有命名空间的资源
实时监控Pod状态和资源使用
查看Deployment、Service、Ingress等详情
查看ConfigMap和Secret(隐藏敏感信息)
b.日志和终端
查看Pod实时日志
支持多容器Pod的日志切换
Web终端访问容器
支持文件上传下载
c.资源操作
创建、编辑、删除资源
扩缩容Deployment
重启Pod
查看和编辑YAML配置
02.Helm包管理
a.Helm安装
a.脚本安装
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
-------------------------------------------------------------------------------------------------
验证安装:
helm version --查看Helm版本
b.二进制安装
# 下载Helm
wget https://get.helm.sh/helm-v3.13.0-linux-amd64.tar.gz
tar -zxvf helm-v3.13.0-linux-amd64.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm
-------------------------------------------------------------------------------------------------
# macOS
brew install helm
c.初始化配置
helm repo add stable https://charts.helm.sh/stable --添加stable仓库
helm repo add bitnami https://charts.bitnami.com/bitnami --添加bitnami仓库
helm repo update --更新仓库索引
-------------------------------------------------------------------------------------------------
查看仓库列表:
helm repo list
b.Chart使用
a.搜索Chart
helm search hub nginx --在Artifact Hub搜索
helm search repo nginx --在本地仓库搜索
-------------------------------------------------------------------------------------------------
查看Chart详情:
helm show chart bitnami/nginx --查看Chart信息
helm show values bitnami/nginx --查看可配置参数
helm show readme bitnami/nginx --查看README
b.安装Chart
helm install my-nginx bitnami/nginx --安装Chart
helm install my-nginx bitnami/nginx -n production --安装到指定命名空间
helm install my-nginx bitnami/nginx --create-namespace -n prod --自动创建命名空间
-------------------------------------------------------------------------------------------------
自定义配置:
helm install my-nginx bitnami/nginx --set service.type=NodePort --命令行设置
helm install my-nginx bitnami/nginx -f values.yaml --使用values文件
-------------------------------------------------------------------------------------------------
干运行(不实际安装):
helm install my-nginx bitnami/nginx --dry-run --debug --查看渲染后的YAML
c.管理Release
helm list --查看已安装的Release
helm list -A --查看所有命名空间
helm status my-nginx --查看Release状态
helm get values my-nginx --查看使用的配置
helm get manifest my-nginx --查看生成的清单
d.升级Release
helm upgrade my-nginx bitnami/nginx --升级到最新版本
helm upgrade my-nginx bitnami/nginx --set replicas=3 --修改配置并升级
helm upgrade my-nginx bitnami/nginx -f new-values.yaml --使���新配置升级
helm upgrade my-nginx bitnami/nginx --reuse-values --保持当前值升级
e.回滚Release
helm history my-nginx --查看版本历史
helm rollback my-nginx --回滚到上一版本
helm rollback my-nginx 2 --回滚到指定版本
f.卸载Release
helm uninstall my-nginx --卸载Release
helm uninstall my-nginx --keep-history --保留历史记录
c.自定义Chart
a.创建Chart
helm create mychart --创建Chart模板
-------------------------------------------------------------------------------------------------
Chart目录结构:
mychart/
├── Chart.yaml --Chart元数据
├── values.yaml --默认配置值
├── charts/ --依赖的Chart
├── templates/ --模板文件
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl --模板辅助函数
│ └── NOTES.txt --安装后提示信息
└── .helmignore --忽略文件
b.Chart.yaml配置
apiVersion: v2
name: mychart
description: A Helm chart for my application
type: application
version: 0.1.0 --Chart版本
appVersion: "1.0" --应用版本
keywords:
- nginx
- web
maintainers:
- name: Your Name
email: [email protected]
c.values.yaml配置
replicaCount: 3
image:
repository: nginx
tag: "1.21"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
ingress:
enabled: false
className: nginx
hosts:
- host: chart-example.local
paths:
- path: /
pathType: Prefix
d.模板语法
Deployment模板示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }} --使用辅助函数
labels:
{{- include "mychart.labels" . | nindent 4 }} --包含标签
spec:
replicas: {{ .Values.replicaCount }} --引用values值
selector:
matchLabels:
{{- include "mychart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "mychart.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 80
resources:
{{- toYaml .Values.resources | nindent 12 }} --转换为YAML
e.常用函数
{{ .Values.key }} --获取values值
{{ default "默认值" .Values.key }} --设置默认值
{{ required "必需的值" .Values.key }} --必填项检查
{{ if .Values.enabled }}...{{ end }} --条件判断
{{ range .Values.list }}...{{ end }} --循环
{{ .Values.text | quote }} --添加引号
{{ .Values.text | upper }} --转大写
{{ include "模板名" . }} --包含模板
{{- 内容 }} --去除左侧空白
{{ 内容 -}} --去除右侧空白
f.Chart使用
helm lint mychart --检查Chart语法
helm template mychart --渲染模板(不安装)
helm package mychart --打包Chart
helm install myapp ./mychart --安装本地Chart
helm install myapp mychart-0.1.0.tgz --安装打包的Chart
03.监控工具
a.Prometheus
a.安装Prometheus
使用Helm安装:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get pods -n monitoring --查看Prometheus组件
kubectl get svc -n monitoring --查看Service
b.访问Prometheus
kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090
-------------------------------------------------------------------------------------------------
访问:http://localhost:9090
c.常用查询
查看节点CPU使用率:
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
-------------------------------------------------------------------------------------------------
查看Pod内存使用:
sum(container_memory_working_set_bytes{pod!=""}) by (pod)
-------------------------------------------------------------------------------------------------
查看Pod CPU使用率:
sum(rate(container_cpu_usage_seconds_total{pod!=""}[5m])) by (pod) * 100
-------------------------------------------------------------------------------------------------
查看磁盘使用率:
(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_free_bytes{mountpoint="/"}) / node_filesystem_size_bytes{mountpoint="/"} * 100
d.配置告警规则
创建PrometheusRule:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: custom-alerts
namespace: monitoring
spec:
groups:
- name: custom-rules
interval: 30s
rules:
- alert: HighPodMemory
expr: sum(container_memory_working_set_bytes{pod!=""}) by (pod) / 1024 / 1024 / 1024 > 1
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} memory usage high"
description: "Pod {{ $labels.pod }} memory usage is {{ $value }}GB"
- alert: NodeDown
expr: up{job="node-exporter"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Node {{ $labels.instance }} is down"
-------------------------------------------------------------------------------------------------
kubectl apply -f prometheus-rules.yaml
e.ServiceMonitor配置
监控自定义应用:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: myapp-monitor
namespace: monitoring
spec:
selector:
matchLabels:
app: myapp
endpoints:
- port: metrics
interval: 30s
path: /metrics
b.Grafana
a.访问Grafana
kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80
-------------------------------------------------------------------------------------------------
访问:http://localhost:3000
-------------------------------------------------------------------------------------------------
默认凭证:
用户名:admin
密码:kubectl get secret -n monitoring prometheus-grafana -o jsonpath="{.data.admin-password}" | base64 -d
b.导入Dashboard
推荐的Dashboard ID:
315 --Kubernetes cluster monitoring
8588 --Kubernetes Deployment Statefulset Daemonset metrics
6417 --Kubernetes Cluster (Prometheus)
13770 --Kubernetes / Views / Pods
-------------------------------------------------------------------------------------------------
导入步骤:
点击"+" -> Import
输入Dashboard ID
选择Prometheus数据源
点击Import
c.创建自定义Dashboard
添加Panel步骤:
1. 点击"Create" -> "Dashboard"
2. 点击"Add new panel"
3. 输入PromQL查询
4. 选择可视化类型(Graph、Stat、Gauge等)
5. 配置显示选项
6. 保存Dashboard
-------------------------------------------------------------------------------------------------
常用Panel示例:
CPU使用率:
sum(rate(container_cpu_usage_seconds_total{pod!=""}[5m])) by (pod) * 100
-------------------------------------------------------------------------------------------------
内存使用量:
sum(container_memory_working_set_bytes{pod!=""}) by (pod) / 1024 / 1024 / 1024
-------------------------------------------------------------------------------------------------
网络流量:
sum(rate(container_network_receive_bytes_total[5m])) by (pod)
d.配置告警通知
配置Email通知:
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-config
namespace: monitoring
data:
grafana.ini: |
[smtp]
enabled = true
host = smtp.gmail.com:587
user = [email protected]
password = your-password
from_address = [email protected]
from_name = Grafana
-------------------------------------------------------------------------------------------------
配置Webhook通知:
在Grafana UI中:
Alerting -> Contact points -> New contact point
选择Webhook类型
输入Webhook URL
e.数据源配置
添加Prometheus数据源:
Configuration -> Data Sources -> Add data source
选择Prometheus
URL:http://prometheus-kube-prometheus-prometheus.monitoring.svc:9090
点击"Save & Test"
c.Metrics Server
a.安装Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get deployment metrics-server -n kube-system
kubectl get apiservice v1beta1.metrics.k8s.io -o yaml
b.修复证书问题
kubectl edit deployment metrics-server -n kube-system
-------------------------------------------------------------------------------------------------
添加启动参数:
spec:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls --跳过证书验证(测试环境)
c.使用Metrics Server
kubectl top nodes --查看节点资源使用
kubectl top pods -A --查看Pod资源使用
kubectl top pods --containers --查看容器资源使用
d.配置HPA
基于CPU的自动扩缩容:
kubectl autoscale deployment nginx --cpu-percent=50 --min=1 --max=10
-------------------------------------------------------------------------------------------------
YAML方式:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
04.日志工具
a.EFK Stack
a.部署Elasticsearch
使用Helm安装:
helm repo add elastic https://helm.elastic.co
helm repo update
helm install elasticsearch elastic/elasticsearch -n logging --create-namespace \
--set replicas=1 \
--set resources.requests.memory=2Gi \
--set resources.limits.memory=2Gi
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get pods -n logging | grep elasticsearch
b.部署Fluent Bit
helm install fluent-bit fluent/fluent-bit -n logging \
--set config.outputs.es.host=elasticsearch-master \
--set config.outputs.es.port=9200
-------------------------------------------------------------------------------------------------
配置文件示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: logging
data:
fluent-bit.conf: |
[SERVICE]
Flush 5
Daemon off
Log_Level info
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser docker
Tag kube.*
Refresh_Interval 5
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
[OUTPUT]
Name es
Match *
Host elasticsearch-master
Port 9200
Logstash_Format On
Logstash_Prefix kubernetes
Retry_Limit False
c.部署Kibana
helm install kibana elastic/kibana -n logging \
--set elasticsearchHosts=http://elasticsearch-master:9200
-------------------------------------------------------------------------------------------------
访问Kibana:
kubectl port-forward -n logging svc/kibana-kibana 5601:5601
-------------------------------------------------------------------------------------------------
访问:http://localhost:5601
d.Kibana使用
创建Index Pattern:
Stack Management -> Index Patterns -> Create index pattern
输入:kubernetes-*
选择时间字段:@timestamp
-------------------------------------------------------------------------------------------------
查询日志:
Discover -> 选择Index Pattern
-------------------------------------------------------------------------------------------------
常用查询语法:
kubernetes.pod_name:"nginx-*" --按Pod名称过滤
kubernetes.namespace_name:"default" --按命名空间过滤
log:"error" OR log:"ERROR" --搜索错误日志
kubernetes.labels.app:"myapp" AND log:"timeout" --组合查询
b.Loki
a.安装Loki Stack
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install loki grafana/loki-stack -n logging --create-namespace \
--set grafana.enabled=true \
--set prometheus.enabled=true \
--set promtail.enabled=true
-------------------------------------------------------------------------------------------------
验证安装:
kubectl get pods -n logging
b.Promtail配置
查看配置:
kubectl get configmap loki-promtail -n logging -o yaml
-------------------------------------------------------------------------------------------------
配置示例:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
target_label: app
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
c.Grafana集成Loki
添加Loki数据源:
Configuration -> Data Sources -> Add data source
选择Loki
URL:http://loki:3100
点击"Save & Test"
-------------------------------------------------------------------------------------------------
创建日志查询面板:
Explore -> 选择Loki数据源
输入LogQL查询
d.LogQL查询语法
基本查询:
{namespace="default"} --查询default命名空间日志
{app="nginx"} --查询nginx应用日志
{pod="nginx-7c5ddbdf54-abc12"} --查询指定Pod日志
-------------------------------------------------------------------------------------------------
过滤查询:
{namespace="default"} |= "error" --包含error的日志
{namespace="default"} != "debug" --不包含debug的日志
{namespace="default"} |~ "error|ERROR" --正则匹配
-------------------------------------------------------------------------------------------------
聚合查询:
sum(rate({namespace="default"}[5m])) --5分钟内日志速率
count_over_time({namespace="default"}[1h]) --1小时内日志数量
-------------------------------------------------------------------------------------------------
多标签查询:
{namespace="default", app="nginx"} |= "error" --多条件查询
05.其他工具
a.k9s
a.安装k9s
macOS:
brew install k9s
-------------------------------------------------------------------------------------------------
Linux:
wget https://github.com/derailed/k9s/releases/download/v0.27.0/k9s_Linux_amd64.tar.gz
tar -xzf k9s_Linux_amd64.tar.gz
sudo mv k9s /usr/local/bin/
-------------------------------------------------------------------------------------------------
Windows:
choco install k9s
b.基本使用
启动k9s:
k9s --连接默认集群
k9s --context my-context --指定上下文
k9s -n default --指定命名空间
-------------------------------------------------------------------------------------------------
常用快捷键:
:pods --查看Pod
:svc --查看Service
:deploy --查看Deployment
:nodes --查看Node
0 --查看所有命名空间
/ --搜索过滤
l --查看日志
d --描述资源
e --编辑资源
delete --删除资源
s --进入Shell
Ctrl+d --删除资源
? --帮助
c.高级功能
实时监控资源:
:pulse --查看集群脉冲
:xray deploy --查看Deployment关联资源
-------------------------------------------------------------------------------------------------
查看事件:
:events --查看集群事件
-------------------------------------------------------------------------------------------------
端口转发:
在Pod视图下按 Shift+f --配置端口转发
d.自定义配置
配置文件位置:~/.k9s/config.yml
-------------------------------------------------------------------------------------------------
配置示例:
k9s:
refreshRate: 2
maxConnRetry: 5
readOnly: false
noExitOnCtrlC: false
ui:
enableMouse: true
headless: false
logoless: false
crumbsless: false
skipLatestRevCheck: false
logger:
tail: 100
buffer: 5000
sinceSeconds: 60
b.Lens
a.安装Lens
macOS:
brew install --cask lens
-------------------------------------------------------------------------------------------------
Windows/Linux:
下载地址:https://k8slens.dev/
-------------------------------------------------------------------------------------------------
验证安装:
lens --version
b.添加集群
方法1:自动发现
Lens会自动读取~/.kube/config中的集群
-------------------------------------------------------------------------------------------------
方法2:手动添加
File -> Add Cluster
选择kubeconfig文件或粘贴内容
点击Add Cluster
c.主要功能
集群概览:
查看集群状态、节点数量、Pod数量
实时监控CPU、内存、磁盘使用
-------------------------------------------------------------------------------------------------
资源管理:
查看所有资源类型
实时更新资源状态
支持YAML编辑
-------------------------------------------------------------------------------------------------
日志和终端:
实时查看Pod日志
多容器Pod日志切换
Web终端访问容器
支持多Tab
-------------------------------------------------------------------------------------------------
Helm Charts:
浏览Helm仓库
安装Chart
管理Release
-------------------------------------------------------------------------------------------------
Prometheus集成:
查看资源使用图表
自定义监控面板
d.扩展插件
安装插件:
File -> Extensions
搜索插件名称
点击Install
-------------------------------------------------------------------------------------------------
推荐插件:
@alebcay/openlens-node-pod-menu --节点Pod快捷菜单
@nevalla/kube-rabbitmq --RabbitMQ管理
c.kubectx/kubens
a.安装kubectx和kubens
macOS:
brew install kubectx
-------------------------------------------------------------------------------------------------
Linux:
sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens
b.kubectx使用
查看所有上下文:
kubectx --列出所有上下文
-------------------------------------------------------------------------------------------------
切换上下文:
kubectx my-context --切换到指定上下文
kubectx - --切换到上一个上下文
-------------------------------------------------------------------------------------------------
重命名上下文:
kubectx new-name=old-name --重命名上下文
-------------------------------------------------------------------------------------------------
删除上下文:
kubectx -d context-name --删除指定上下文
c.kubens使用
查看所有命名空间:
kubens --列出所有命名空间
-------------------------------------------------------------------------------------------------
切换命名空间:
kubens default --切换到default命名空间
kubens - --切换到上一个命名空间
d.配置补全
Bash补全:
echo 'source /opt/kubectx/completion/kubectx.bash' >>~/.bashrc
echo 'source /opt/kubectx/completion/kubens.bash' >>~/.bashrc
-------------------------------------------------------------------------------------------------
Zsh补全:
mkdir -p ~/.oh-my-zsh/completions
ln -s /opt/kubectx/completion/kubectx.zsh ~/.oh-my-zsh/completions/_kubectx
ln -s /opt/kubectx/completion/kubens.zsh ~/.oh-my-zsh/completions/_kubens
e.使用技巧
快速切换:
kubectx production && kubens default --同时切换上下文和命名空间
-------------------------------------------------------------------------------------------------
查看当前:
kubectx -c --查看当前上下文
kubens -c --查看当前命名空间
-------------------------------------------------------------------------------------------------
交互式选择(需要fzf):
kubectx -i --交互式选择上下文
kubens -i --交互式选择命名空间
3.9 [3]troubles
01.Pod故障排查
a.Pod状态异常
a.常见Pod状态
Pending 等待调度或拉取镜像
Running 正常运行中
Succeeded 成功完成(Job/CronJob)
Failed 执行失败
Unknown 状态未知(节点失联)
CrashLoopBackOff 容器反复崩溃重启
ImagePullBackOff 镜像拉取失败
CreateContainerError 容器创建失败
ErrImagePull 镜像拉取错误
b.Pending状态排查
kubectl describe pod <pod-name> --查看详细信息
-------------------------------------------------------------------------------------------------
常见原因:
原因1: 资源不足
Events: 0/3 nodes are available: 3 Insufficient cpu.
解决: 调整Pod资源请求或扩容节点
-------------------------------------------------------------------------------------------------
原因2: 节点选择器不匹配
Events: 0/3 nodes are available: 3 node(s) didn't match node selector.
解决: 检查nodeSelector配置或给节点打标签
-------------------------------------------------------------------------------------------------
原因3: PVC未绑定
Events: pod has unbound immediate PersistentVolumeClaims
解决: 检查PVC状态,创建对应的PV
c.CrashLoopBackOff排查
kubectl logs <pod-name> --查看容器日志
kubectl logs <pod-name> --previous --查看崩溃前日志
kubectl describe pod <pod-name> --查看事件
-------------------------------------------------------------------------------------------------
常见原因:
原因1: 应用启动失败
解决: 检查应用日志,修复配置错误
-------------------------------------------------------------------------------------------------
原因2: 健康检查失败
解决: 调整livenessProbe配置或修复应用
-------------------------------------------------------------------------------------------------
原因3: 资源限制过低
解决: 增加resources.limits配置
d.ImagePullBackOff排查
kubectl describe pod <pod-name> --查看拉取错误
-------------------------------------------------------------------------------------------------
常见原因:
原因1: 镜像不存在
Events: Failed to pull image "nginx:wrongtag": rpc error: code = NotFound
解决: 检查镜像名称和标签是否正确
-------------------------------------------------------------------------------------------------
原因2: 私有镜像无认证
Events: Failed to pull image: pull access denied
解决: 创建imagePullSecrets
kubectl create secret docker-registry my-secret \
--docker-server=harbor.example.com \
--docker-username=admin \
--docker-password=password
-------------------------------------------------------------------------------------------------
原因3: 网络问题
解决: 检查节点到镜像仓库的网络连通性
b.容器启动失败
a.查看容器状态
kubectl get pods <pod-name> -o jsonpath='{.status.containerStatuses[*]}' --查看容器状态
kubectl describe pod <pod-name> --查看详细事件
b.启动命令错误
常见错误:
Error: failed to create containerd task: failed to create shim: OCI runtime create failed
-------------------------------------------------------------------------------------------------
排查步骤:
1. 检查容器启动命令是否正确
2. 检查容器工作目录是否存在
3. 检查环境变量配置
-------------------------------------------------------------------------------------------------
kubectl logs <pod-name> -c <container-name> --查看容器日志
c.权限问题
常见错误:
Error: container has runAsNonRoot and image has non-numeric user (www-data)
-------------------------------------------------------------------------------------------------
解决方案:
方法1: 修改SecurityContext
securityContext:
runAsUser: 33 --指定用户ID
runAsGroup: 33
-------------------------------------------------------------------------------------------------
方法2: 修改镜像Dockerfile
USER 1000:1000
d.存储挂载失败
常见错误:
Error: failed to mount volume: mount failed: exit status 32
-------------------------------------------------------------------------------------------------
排查步骤:
1. 检查PVC是否已绑定
kubectl get pvc
-------------------------------------------------------------------------------------------------
2. 检查挂载路径权限
kubectl exec <pod-name> -- ls -la /mount/path
-------------------------------------------------------------------------------------------------
3. 检查存储类是否支持访问模式
c.镜像拉取失败
a.认证问题
创建Docker镜像仓库Secret:
kubectl create secret docker-registry harbor-secret \
--docker-server=harbor.example.com \
--docker-username=admin \
--docker-password=Harbor12345 \
[email protected]
-------------------------------------------------------------------------------------------------
在Pod中使用:
apiVersion: v1
kind: Pod
metadata:
name: private-pod
spec:
containers:
- name: app
image: harbor.example.com/myapp:latest
imagePullSecrets:
- name: harbor-secret
b.镜像地址错误
检查镜像配置:
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].image}'
-------------------------------------------------------------------------------------------------
常见错误:
错误1: 镜像名称拼写错误
错误2: 标签不存在
错误3: 镜像仓库地址错误
c.网络连通性
测试节点到镜像仓库连通性:
kubectl debug node/<node-name> -it --image=busybox
ping harbor.example.com
nslookup harbor.example.com
-------------------------------------------------------------------------------------------------
检查代理配置:
systemctl show docker --property=Environment --查看Docker代理配置
d.镜像拉取策略
imagePullPolicy配置:
Always 总是拉取最新镜像
IfNotPresent 本地不存在才拉取
Never 从不拉取,只使用本地镜像
-------------------------------------------------------------------------------------------------
配置示例:
containers:
- name: app
image: nginx:1.21
imagePullPolicy: IfNotPresent --优先使用本地镜像
02.网络故障排查
a.Service无法访问
a.检查Service配置
kubectl get svc <service-name> --查看Service
kubectl describe svc <service-name> --查看详细信息
kubectl get endpoints <service-name> --查看Endpoints
-------------------------------------------------------------------------------------------------
常见问题:
问题1: Endpoints为空
原因: selector标签不匹配
解决: 检查Service的selector是否与Pod的labels匹配
kubectl get pods --show-labels
-------------------------------------------------------------------------------------------------
问题2: Service端口配置错误
解决: 检查Service的port和targetPort配置
kubectl get svc <service-name> -o yaml
b.测试Service连通性
在集群内测试:
kubectl run test-pod --image=busybox -it --rm -- sh
wget -O- http://<service-name>:<port>
nslookup <service-name>
-------------------------------------------------------------------------------------------------
测试DNS解析:
kubectl run test-dns --image=busybox -it --rm -- nslookup <service-name>
kubectl run test-dns --image=busybox -it --rm -- nslookup <service-name>.<namespace>.svc.cluster.local
c.检查网络策略
kubectl get networkpolicies -n <namespace> --查看NetworkPolicy
kubectl describe networkpolicy <policy-name> --查看详细信息
-------------------------------------------------------------------------------------------------
常见问题:
NetworkPolicy阻止流量
解决: 检查ingress和egress规则
b.Pod间通信失败
a.测试Pod连通性
获取Pod IP:
kubectl get pods -o wide --查看Pod IP
-------------------------------------------------------------------------------------------------
测试连通性:
kubectl exec <source-pod> -- ping <target-pod-ip>
kubectl exec <source-pod> -- wget -O- http://<target-pod-ip>:<port>
b.检查CNI插件
查看CNI状态:
kubectl get pods -n kube-system -l k8s-app=calico-node --Calico
kubectl get pods -n kube-system -l k8s-app=flannel --Flannel
kubectl logs <cni-pod> -n kube-system --查看CNI日志
-------------------------------------------------------------------------------------------------
常见问题:
问题1: CNI Pod未就绪
解决: 检查CNI配置和日志
-------------------------------------------------------------------------------------------------
问题2: 网络插件配置错误
解决: 检查/etc/cni/net.d/配置文件
c.检查iptables规则
查看iptables规则:
iptables -t nat -L -n -v | grep <service-name>
iptables -t filter -L -n -v
-------------------------------------------------------------------------------------------------
常见问题:
kube-proxy未正常工作
解决: 检查kube-proxy日志
kubectl logs -n kube-system -l k8s-app=kube-proxy
c.DNS解析问题
a.测试DNS解析
kubectl run test-dns --image=busybox -it --rm -- nslookup kubernetes.default
kubectl run test-dns --image=busybox -it --rm -- nslookup <service-name>
kubectl run test-dns --image=busybox -it --rm -- cat /etc/resolv.conf
b.检查CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns --查看CoreDNS状态
kubectl logs -n kube-system -l k8s-app=kube-dns --查看CoreDNS日志
kubectl get svc -n kube-system kube-dns --查看DNS Service
-------------------------------------------------------------------------------------------------
常见问题:
问题1: CoreDNS Pod未就绪
解决: 检查CoreDNS资源限制和日志
-------------------------------------------------------------------------------------------------
问题2: DNS解析超时
解决: 检查CoreDNS配置
kubectl get configmap coredns -n kube-system -o yaml
c.检查Pod DNS配置
kubectl get pod <pod-name> -o jsonpath='{.spec.dnsPolicy}' --查看DNS策略
kubectl exec <pod-name> -- cat /etc/resolv.conf --查看DNS配置
-------------------------------------------------------------------------------------------------
DNS策略:
ClusterFirst 使用集群DNS(默认)
Default 使用节点DNS
ClusterFirstWithHostNet hostNetwork Pod使用集群DNS
None 自定义DNS配置
d.Ingress访问失败
a.检查Ingress配置
kubectl get ingress --查看Ingress
kubectl describe ingress <ingress-name> --查看详细信息
kubectl get svc -n ingress-nginx --查看Ingress Controller
-------------------------------------------------------------------------------------------------
常见问题:
问题1: Ingress Controller未运行
解决: 检查Ingress Controller状态
kubectl get pods -n ingress-nginx
-------------------------------------------------------------------------------------------------
问题2: Ingress规则配置错误
解决: 检查host和path配置
b.检查Ingress Controller日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
-------------------------------------------------------------------------------------------------
常见错误:
错误1: Backend Service不存在
错误2: SSL证书配置错误
错误3: 注解配置错误
c.测试后端服务
kubectl get svc <backend-service> --检查后端Service
kubectl get endpoints <backend-service> --检查Endpoints
kubectl port-forward svc/<backend-service> 8080:80 --测试Service
03.存储故障排查
a.PVC绑定失败
a.检查PVC状态
kubectl get pvc --查看PVC状态
kubectl describe pvc <pvc-name> --查看详细信息
kubectl get pv --查看PV状态
-------------------------------------------------------------------------------------------------
常见状态:
Pending 等待绑定PV
Bound 已绑定PV
Lost PV丢失
b.PVC Pending排查
kubectl describe pvc <pvc-name> --查看Events
-------------------------------------------------------------------------------------------------
常见原因:
原因1: 没有匹配的PV
Events: no persistent volumes available
解决: 创建符合要求的PV或使用StorageClass动态创建
-------------------------------------------------------------------------------------------------
原因2: StorageClass不存在
Events: storageclass.storage.k8s.io "xxx" not found
解决: 创建StorageClass或使用已存在的
kubectl get storageclass
-------------------------------------------------------------------------------------------------
原因3: 访问模式不匹配
Events: access mode mismatch
解决: 调整PVC的accessModes配置
c.检查StorageClass
kubectl get storageclass --查看StorageClass
kubectl describe storageclass <sc-name> --查看详细信息
-------------------------------------------------------------------------------------------------
常见问题:
问题1: StorageClass未设置为默认
解决: 设置默认StorageClass
kubectl patch storageclass <sc-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
b.卷挂载失败
a.检查挂载错误
kubectl describe pod <pod-name> --查看Events
-------------------------------------------------------------------------------------------------
常见错误:
错误1: MountVolume.SetUp failed
原因: 存储后端不可用或配置错误
-------------------------------------------------------------------------------------------------
错误2: Unable to attach or mount volumes
原因: 节点无法访问存储
b.检查存储插件
kubectl get pods -n kube-system -l app=csi-driver --查看CSI驱动
kubectl logs <csi-pod> -n kube-system --查看驱动日志
c.检查节点挂载
ssh到节点检查:
mount | grep <volume-name> --查看挂载点
df -h --查看磁盘使用
dmesg | tail --查看内核日志
c.存储空间不足
a.检查PVC使用量
kubectl get pvc --查看PVC容量
kubectl exec <pod-name> -- df -h /mount/path --查看实际使用
b.扩容PVC
编辑PVC:
kubectl edit pvc <pvc-name>
-------------------------------------------------------------------------------------------------
修改spec.resources.requests.storage值:
spec:
resources:
requests:
storage: 20Gi --扩容到20Gi
-------------------------------------------------------------------------------------------------
注意事项:
1. StorageClass必须支持扩容(allowVolumeExpansion: true)
2. 某些存储需要重启Pod才能生效
3. 只能扩容不能缩容
04.节点故障排查
a.节点NotReady
a.检查节点状态
kubectl get nodes --查看节点状态
kubectl describe node <node-name> --查看详细信息
-------------------------------------------------------------------------------------------------
常见状态:
Ready 节点健康
NotReady 节点异常
SchedulingDisabled 节点已禁止调度
Unknown 无法获取节点状态
b.NotReady常见原因
kubectl describe node <node-name> --查看Conditions
-------------------------------------------------------------------------------------------------
原因1: kubelet未运行
Condition: Ready=False, Reason: KubeletNotReady
解决: 登录节点检查kubelet
systemctl status kubelet
systemctl restart kubelet
journalctl -u kubelet -f
-------------------------------------------------------------------------------------------------
原因2: 网络插件故障
解决: 检查CNI插件状态
kubectl get pods -n kube-system
-------------------------------------------------------------------------------------------------
原因3: 磁盘压力
Condition: DiskPressure=True
解决: 清理磁盘空间
df -h
docker system prune -a
-------------------------------------------------------------------------------------------------
原因4: 内存压力
Condition: MemoryPressure=True
解决: 释放内存或增加节点资源
c.检查节点日志
journalctl -u kubelet -f --查看kubelet日志
dmesg | tail --查看内核日志
/var/log/messages --查看系统日志
b.节点资源耗尽
a.检查节点资源
kubectl top node --查看节点资源使用
kubectl describe node <node-name> --查看资源分配
-------------------------------------------------------------------------------------------------
查看Allocated resources:
Resource Requests Limits
-------- -------- ------
cpu 2500m (62%) 4000m (100%)
memory 6Gi (75%) 8Gi (100%)
b.检查Pod资源
kubectl top pods -n <namespace> --查看Pod资源使用
kubectl get pods -n <namespace> --sort-by=.status.podIP --查看Pod分布
c.解决方案
方案1: 驱逐Pod
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --force
-------------------------------------------------------------------------------------------------
方案2: 扩容节点
增加节点数量或升级节点规格
-------------------------------------------------------------------------------------------------
方案3: 调整资源配额
减少Pod的requests和limits配置
c.磁盘压力
a.检查磁盘使用
登录节点:
df -h --查看磁盘使用
du -sh /var/lib/docker --Docker数据目录
du -sh /var/lib/kubelet --Kubelet数据目录
du -sh /var/log --日志目录
b.清理磁盘空间
清理Docker:
docker system df --查看Docker空间使用
docker system prune -a --清理未使用的镜像和容器
docker volume prune --清理未使用的卷
-------------------------------------------------------------------------------------------------
清理日志:
journalctl --vacuum-time=7d --保留7天日志
find /var/log -name "*.log" -mtime +7 -delete --删除7天前日志
-------------------------------------------------------------------------------------------------
清理Kubelet缓存:
kubectl get pods --all-namespaces -o wide | grep <node-name> --查看节点上的Pod
kubectl delete pod <completed-pod> -n <namespace> --删除已完成的Pod
c.配置日志轮转
配置logrotate:
/var/log/containers/*.log {
daily
rotate 7
compress
missingok
notifempty
create 0644 root root
}
d.网络插件问题
a.检查CNI插件
kubectl get pods -n kube-system -l k8s-app=calico-node --Calico
kubectl get pods -n kube-system -l app=flannel --Flannel
kubectl get pods -n kube-system -l k8s-app=cilium --Cilium
-------------------------------------------------------------------------------------------------
检查日志:
kubectl logs <cni-pod> -n kube-system
b.检查CNI配置
登录节点:
ls /etc/cni/net.d/ --查看CNI配置文件
cat /etc/cni/net.d/10-calico.conflist --查看配置内容
c.重启网络插件
kubectl delete pod <cni-pod> -n kube-system --重启CNI Pod
systemctl restart kubelet --重启kubelet
05.集群故障排查
a.组件故障
a.检查控制平面组件
kubectl get pods -n kube-system --查看组件状态
-------------------------------------------------------------------------------------------------
关键组件:
kube-apiserver API服务器
kube-controller-manager 控制器管理器
kube-scheduler 调度器
etcd 数据存储
b.检查API Server
kubectl get --raw /healthz --健康检查
kubectl get --raw /readyz --就绪检查
kubectl get cs --组件状态(已废弃)
-------------------------------------------------------------------------------------------------
检查日志:
kubectl logs -n kube-system kube-apiserver-<node>
journalctl -u kube-apiserver
c.检查Controller Manager
kubectl logs -n kube-system kube-controller-manager-<node>
-------------------------------------------------------------------------------------------------
常见问题:
问题1: Leader选举失败
问题2: 控制器循环错误
d.检查Scheduler
kubectl logs -n kube-system kube-scheduler-<node>
-------------------------------------------------------------------------------------------------
常见问题:
问题1: Pod无法调度
问题2: 调度策略错误
b.证书过期
a.检查证书有效期
kubeadm certs check-expiration --检查证书过期时间
-------------------------------------------------------------------------------------------------
输出示例:
CERTIFICATE EXPIRES RESIDUAL TIME
admin.conf Jan 01, 2025 00:00 UTC 364d
apiserver Jan 01, 2025 00:00 UTC 364d
apiserver-kubelet-client Jan 01, 2025 00:00 UTC 364d
b.手动检查证书
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text --查看证书详情
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates --查看有效期
c.更新证书
备份证书:
cp -r /etc/kubernetes/pki /etc/kubernetes/pki.backup
-------------------------------------------------------------------------------------------------
更新所有证书:
kubeadm certs renew all --更新所有证书
-------------------------------------------------------------------------------------------------
更新指定证书:
kubeadm certs renew apiserver --更新API Server证书
kubeadm certs renew apiserver-kubelet-client --更新kubelet客户端证书
-------------------------------------------------------------------------------------------------
重启控制平面组件:
kubectl -n kube-system delete pod -l component=kube-apiserver
kubectl -n kube-system delete pod -l component=kube-controller-manager
kubectl -n kube-system delete pod -l component=kube-scheduler
d.更新kubeconfig
cp /etc/kubernetes/admin.conf ~/.kube/config --更新配置文件
kubeadm init phase kubeconfig all --重新生成所有kubeconfig
c.etcd问题
a.检查etcd状态
kubectl get pods -n kube-system -l component=etcd --查看etcd Pod
kubectl logs -n kube-system etcd-<node> --查看etcd日志
-------------------------------------------------------------------------------------------------
使用etcdctl检查:
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint health
-------------------------------------------------------------------------------------------------
查看成员:
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
member list
b.etcd备份
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /backup/etcd-snapshot.db
-------------------------------------------------------------------------------------------------
验证备份:
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot.db
c.etcd恢复
停止API Server:
mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
-------------------------------------------------------------------------------------------------
恢复数据:
ETCDCTL_API=3 etcdctl \
snapshot restore /backup/etcd-snapshot.db \
--data-dir=/var/lib/etcd-restore
-------------------------------------------------------------------------------------------------
修改etcd配置指向新数据目录,重启etcd和API Server
d.etcd空间清理
检查空间使用:
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint status --write-out=table
-------------------------------------------------------------------------------------------------
压缩历史版本:
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
compact $(ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --write-out="json" | jq -r '.[0].Status.header.revision')
-------------------------------------------------------------------------------------------------
碎片整理:
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
defrag
d.API Server问题
a.API Server无法访问
检查API Server进程:
ps aux | grep kube-apiserver
-------------------------------------------------------------------------------------------------
检查监听端口:
netstat -tlnp | grep 6443
ss -tlnp | grep 6443
-------------------------------------------------------------------------------------------------
检查防火墙:
iptables -L -n | grep 6443
firewall-cmd --list-ports
b.认证授权问题
kubectl get --raw /api/v1 --测试API访问
curl -k https://localhost:6443/api/v1 --测试API访问
-------------------------------------------------------------------------------------------------
检查证书:
openssl s_client -connect localhost:6443 -showcerts
-------------------------------------------------------------------------------------------------
检查RBAC:
kubectl auth can-i --list --查看当前用户权限
kubectl auth can-i get pods --检查特定权限
c.API Server性能问题
检查API Server指标:
kubectl get --raw /metrics | grep apiserver_request_duration
-------------------------------------------------------------------------------------------------
检查慢请求:
kubectl logs -n kube-system kube-apiserver-<node> | grep "Trace\["
-------------------------------------------------------------------------------------------------
优化方案:
1. 增加API Server副本数
2. 启用API优先级和公平性(APF)
3. 调整etcd性能
e.调度器问题
a.Pod无法调度
kubectl describe pod <pod-name> --查看调度失败原因
-------------------------------------------------------------------------------------------------
常见原因:
原因1: Insufficient cpu/memory
解决: 调整资源请求或增加节点
-------------------------------------------------------------------------------------------------
原因2: No nodes are available
解决: 检查节点状态和污点
kubectl get nodes
kubectl describe node <node-name> | grep Taints
-------------------------------------------------------------------------------------------------
原因3: Node affinity/selector不匹配
解决: 调整Pod的nodeSelector或affinity配置
b.调度器日志
kubectl logs -n kube-system kube-scheduler-<node>
-------------------------------------------------------------------------------------------------
查看调度决策:
kubectl logs -n kube-system kube-scheduler-<node> --v=5
c.手动调度
创建Pod时指定节点:
apiVersion: v1
kind: Pod
metadata:
name: manual-schedule-pod
spec:
nodeName: node01 --手动指定节点
containers:
- name: nginx
image: nginx:1.21
4 container
4.1 jdk
01.安装JDK
a.Dockerfile
# 使用官方的 OpenJDK 镜像作为基础镜像
FROM openjdk:8-jdk-alpine
# 设置工作目录
WORKDIR /app
# 复制应用程序文件到容器中(如果有的话)
# COPY . /app
# 暴露必要的端口(如果需要)
# EXPOSE 8080
# 设置默认命令(如果需要)
# CMD ["java", "-jar", "your-app.jar"]
b.构建镜像
docker build -t my-jdk8-image .
c.运行容器
docker run -d --name my-jdk8-container my-jdk8-image
02.安装JDK
a.拉取镜像
docker pull openjdk:8-jdk-alpine
b.运行容器
docker run -d --name my-jdk8-container openjdk:8-jdk-alpine
c.进入容器
docker exec -it my-jdk8-container /bin/sh
d.验证
java -version
03.挂载全局
a.挂载JDK到主机系统
docker cp my-jdk8-container:/usr/lib/jvm/java-8-openjdk /path/to/host/directory
b.环境变量:~/.bashrc 或 /etc/profile
export JAVA_HOME=/path/to/host/directory/java-8-openjdk
export PATH=$JAVA_HOME/bin:$PATH
c.刷新配置
source ~/.bashrc
d.验证
java -version
4.2 minio
01.常用信息1
a.第1步:查看系统信息
a.查看系统架构
uname -m
b.查看Docker版本
docker version
c.查看系统版本
cat /etc/os-release
b.第2步:选择合适的MinIO镜像
a.镜像说明
镜像名称:quay.io/minio/minio:latest
说明:官方最新稳定版(推荐)
推荐场景:生产环境
b.镜像说明
镜像名称:minio/minio:latest
说明:Docker Hub 镜像
推荐场景:备用选择
c.镜像说明
镜像名称:quay.io/minio/minio:RELEASE.2024-XX-XX
说明:指定版本
推荐场景:需要特定版本时
c.第3步:安装前准备
a.创建数据目录
---
mkdir -p /data/minio/data
---
b.创建配置目录
---
mkdir -p /data/minio/config
---
02.常用信息2
a.第1步:运行MinIO容器
a.执行命令
# 创建数据目录
mkdir -p /opt/minio/data
-------------------------------------------------------------------------------------------------
# 运行 MinIO 容器
docker run -d \
--name minio \
--restart=unless-stopped \
-p 9000:9000 \
-p 9001:9001 \
-e MINIO_ROOT_USER=admin \
-e MINIO_ROOT_PASSWORD=Admin@123456 \
-v /opt/minio/data:/data \
quay.io/minio/minio server /data --console-address ":9001"
-------------------------------------------------------------------------------------------------
目录 优点 缺点
/opt/minio/data 符合 Linux 规范,可选软件安装目录 无
/data/minio/data 简洁明了 需要单独分区
/home/minio/data 用户目录 不符合生产规范
b.参数说明
参数:-p 9000:9000
说明:API 端口
c.参数说明
参数:-p 9001:9001
说明:Web 控制台端口
d.参数说明
参数:MINIO_ROOT_USER
说明:管理员账号(默认 minioadmin)
e.参数说明
参数:MINIO_ROOT_PASSWORD
说明:密码(至少8位)
f.参数说明
参数:-v /data/minio/data:/data
说明:数据持久化
g.参数说明
参数:--console-address ":9001"
说明:指定控制台端口
b.第2步:验证安装
a.查看容器状态
---
docker ps | grep minio
---
b.查看日志
---
docker logs minio
---
c.检查端口
---
netstat -tunlp | grep -E '9000|9001'
---
c.访问方式
a.Web控制台
http://你的IP:9001
b.API端点
http://你的IP:9000
4.3 redis1
01.镜像
docker pull redis:latest
02.部署
docker run -itd --name redis -p 6379:6379 redis --requirepass myslayers
03.运行
docker start d5667c109040 --启动容器
docker stop d5667c109040 --停止容器
docker restart d5667c109040 --重启容器
docker rm d5667c109040 --卸载容器
docker logs d5667c109040 --查看日志
docker exec -it redis /bin/bash --进入容器
redis-cli -p 6379 -a myslayers --测试(用户root密码myslayers)
4.4 redis2
01.镜像
docker pull redis:latest
02.运行命令下载默认的redis.conf 其中-P可指定下载目录
wget -p /docker/redis/conf https://raw.githubusercontent.com/antirez/redis/5.0/redis.conf -O redis.conf
03.运行命令创建文件夹,用来映射配置文件
mkdir -p /docker/redis/conf
mkdir -p /docker/redis/data
把2下载的redis.conf移动到4中的conf文件夹中
04.修改redis.conf文件
requirepass xxxxx # 设置密码
bind 127.0.0.1 # 注释掉,可以允许外网访问
protected-mode no # yes改成no启用保护模式
05.运行命令,运行镜像,其中 -v 后面映射的目录为上面创建的文件夹地址
docker run -d --privileged=true -p 6389:6379 --restart always -v /docker/redis/conf/redis.conf:/etc/redis/redis.conf -v /docker/redis/data:/data --name redis6389 redis redis-server /etc/redis/redis.conf --appendonly yes
06.运行成功
docker start d5667c109040 --启动容器
docker stop d5667c109040 --停止容器
docker restart d5667c109040 --重启容器
docker rm d5667c109040 --卸载容器
docker logs d5667c109040 --查看日志
docker exec -it redis /bin/bash --进入容器
redis-cli -p 6379 -a myslayers --测试(用户root密码myslayers)
4.5 mysql
01.镜像
docker pull mysql:5.7.27
docker pull mysql:latest
02.部署
docker run -itd --name mysql5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.27
# arm64,支持最低为8.0.31
docker run -itd --name mysql8 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.31
# arm64,支持最低为8.0.31,由于在docker属于linux系统,需要开启忽略大小写
docker run -itd --name mysql8 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.31 --lower-case-table-names=1
03.运行
docker start 80576e5ea74a --启动容器
docker stop 80576e5ea74a --停止容器
docker restart 80576e5ea74a --重启容器
docker rm 80576e5ea74a --移除容器
docker logs 80576e5ea74a --查看日志
docker exec -it mysql8 /bin/bash --进入容器
docker exec -it mysql5 /bin/bash --进入容器
mysql -u root -p --测试(用户root密码4033665)
04.外部访问
GRANT ALL PRIVILEGES on *.* to root@'%' WITH GRANT OPTION;
ALTER user 'root'@'%' IDENTIFIED BY '123456' PASSWORD EXPIRE NEVER;
ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;
4.6 postgres
01.镜像
docker pull postgres:latest
02.部署
docker run -itd -p 5432:5432 -v /data/postgres_docker/pgdata:/var/lib/postgresql/data --name pgsql postgres:latest
03.运行
docker exec -it pgsql /bin/bash
psql -h localhost -U postgres -p 5432 --(用户postgres 密码初始随机)
alter user postgres with password '123456';
4.7 oracle11g
01.镜像
docker pull rohitbasu77/oracle11g
02.部署
docker run -d \
--name myslayers-oracle11g \
-p 40022:22 \
-p 41521:1521 \
-p 48080:8080 \
rohitbasu77/oracle11g:latest
---------------------------------------------------------------------------------------------------------
docker run -d --name oracle11g -p 40022:22 -p 41521:1521 -p 48080:8080 rohitbasu77/oracle11g:latest
03.运行
docker start 80576e5ea74a --启动容器
docker stop 80576e5ea74a --停止容器
docker restart 80576e5ea74a --重启容器
docker rm 80576e5ea74a --移除容器
docker logs 80576e5ea74a --查看日志
docker exec -it oracle11g /bin/bash --进入容器
---------------------------------------------------------------------------------------------------------
sqlplus system/oracle --测试(system/oracle)
04.连接
a.Navicat连接
hostname: localhost or docker machine ip
port: 41521
sid: xe
username: system
password: oracle(默认),tiger(新密码)
Password for SYS & SYSTEM is oracle
Password for fareuser, searchuser, bookinguser, checkinuser is rohit123
b.SSH连接
Login by SSH:
ssh root@docker_machine_ip -p 40022
password: admin --Oracle容器内的Ubuntu 14.04 LTS
-----------------------------------------------------------------------------------------------------
Login by SSH:
ssh root@docker_machine_ip -p 22
password: 403366X --docker_machine远程的debian
4.8 mongodb
01.镜像
docker pull mongo:latest
02.部署
docker run -itd --name mongodb -p 27017:27017 mongo --auth
03.运行(设置密码)
docker exec -it mongodb mongo admin
db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'}]});
db.auth('admin', '123456') --测试(用户admin 密码123456)
4.9 activemq
01.镜像
docker pull webcenter/activemq
02.部署
docker run -d --name activemq -p 61616:61616 -p 8161:8161 webcenter/activemq
03.运行
docker exec -it activemq /bin/bash --进入容器
vi /opt/activemq/conf/jetty-realm.properties
myslayers: 4033665, admin --修改依次为账号、密码、角色
04.测试
http://127.0.0.1:8161 --测试(用户admin 密码admin)
4.10 rabbitmq
01.镜像
docker pull rabbitmq:management --图形化界面:management
02.部署
docker run -itd --name rabbitmq --hostname my-rabbit -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management
03.运行
docker start cfbabdfacbbe --启动容器
docker stop cfbabdfacbbe --停止容器
docker restart cfbabdfacbbe --重启容器
docker rm cfbabdfacbbe --移除容器
docker logs cfbabdfacbbe --查看日志
docker exec -it rabbitmq /bin/bash --进入容器
http://127.0.0.1:15672 --测试(用户guest 密码guest)
4.11 elasticsearch
01.解决:docker启动ElasticSearch,报错bootstrap checks failed
sudo sysctl -w vm.max_map_count=262144 --临时修改
---------------------------------------------------------------------------------------------------------
vi /etc/sysctl.conf --永久修改
vm.max_map_count=262144 --追加内容
sudo sysctl -p --刷新
02.安装
docker pull elasticsearch:6.4.3
03.部署
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 elasticsearch:6.4.3
04.安装中文分词插件
docker exec -it elasticsearch bash
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.3/elasticsearch-analysis-ik-6.4.3.zip
05.配置
docker exec -it elasticsearch bash
vi ./config/elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0
# minimum_master_nodes need to be explicitly set when bound on a public IP
# set to 1 to allow single node clusters
# Details: https://github.com/elastic/elasticsearch/pull/17288
discovery.zen.minimum_master_nodes: 1
06.运行
docker start cfbabdfacbbe --启动容器
docker stop cfbabdfacbbe --停止容器
docker restart cfbabdfacbbe --重启容器
docker rm cfbabdfacbbe --移除容器
docker logs -f elasticsearch --查看日志
docker exec -it elasticsearch /bin/bash --进入容器
http://127.0.0.1:9200 --测试
4.12 wordpress
01.镜像
docker pull mysql:latest && docker pull wordpress:latest
02.部署
docker run -d --privileged=true --name Mysql_Test -v /data/mysql:/var/lib/mysql -e MYSQL_DATABASE=wordpress -e MYSQL_ROOT_PASSWORD=4033665 mysql && docker run -d --name Wordpress_Test -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_PASSWORD=4033665 -p 8888:80 --link Mysql_Test:mysql wordpress
03.运行
登录:http://halavah.top:8888/wp-admin/index.php
登录:http://halavah.xyz:8888/wp-admin/index.php
标题:勿因喜而轻诺!
用户名:myslayers
密码:4033665
邮箱:[email protected]
主题:Blackoot Lite
04.解决
WordPress无法连接MySQL,无法识别MySQL8默认用户认证方式,plugin需要从caching_sha2_password变为mysql_native_password
---------------------------------------------------------------------------------------------------------
docker exec -it Mysql_Test mysql -p
mysql> mysql -u root -p
mysql> use mysql;
mysql> select host, user, plugin from user;
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '4033665';
mysql> select host, user, plugin from user;
mysql> exit
5 方式1:docker-compose.yml启动项目
5.1 gitlab
01.使用docker-compose部署
a.安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
b.版本
[root@bigdata01 ~]# sudo chmod +x /usr/local/bin/docker-compose --授予当前用户执行权限
[root@bigdata01 ~]# docker-compose version --版本
docker-compose version 1.25.0, build 0a186604
docker-py version: 4.1.0
CPython version: 3.7.4
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
c.操作
docker search gitlab --查看gitlab镜像
docker pull gitlab/gitlab-ce:latest --拉取gitlab镜像
d.创建文件夹
[root@bigdata01 ~]# cd /usr/local
[root@bigdata01 local]# mkdir docker
[root@bigdata01 local]# cd docker/
[root@bigdata01 docker]# mkdir gitlab_docker
[root@bigdata01 docker]# cd gitlab_docker/
[root@bigdata01 gitlab_docker]# pwd
/usr/local/docker/gitlab_docker
e.创建docker-compose.yml文件
cd /usr/local/docker/gitlab_docker
vi docker-compose.yml
-----------------------------------------------------------------------------------------------------
version: '3.1'
services:
gitlab:
image: 'gitlab/gitlab-ce:latest'
container_name: gitlab
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.2.129:8929'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
ports:
- '8929:8929'
- '2224:2224'
volumes:
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
f.启动docker-compose
cd /usr/local/docker/gitlab_docker
docker-compose up -d --启动
docker-compose logs -f gitlab --日志
g.访问
http://127.0.0.1:8929 --访问
root
glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
h.获取默认密码
[root@bigdata01 gitlab_docker]# docker exec -it gitlab bash --进入容器
root@f48f17cf9d8a:/# cat /etc/gitlab/initial_root_password --查看密码
# WARNING: This value is valid only in the following conditions
# 1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
# 2. Password hasn't been changed manually, either via UI or via command line.
#
# If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.
Password: glSnda+IlOCwj/vk4bgIo2+kT65iuO8Frt6MP0btUDA=
# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.
root@f48f17cf9d8a:/#
i.修改密码
http://127.0.0.1:8929/ --访问
root
12345678
j.设置容器开机自启动
a.开启
docker update --restart=always gitlab
b.关闭
docker update --restart=no gitlab
5.2 jenkins
00.使用docker-compose部署
a.安装
docker pull jenkins/jenkins:2.401.2-lts
b.创建文件夹
[root@bigdata01 ~]# cd /usr/local
[root@bigdata01 local]# mkdir docker
[root@bigdata01 local]# cd docker/
[root@bigdata01 docker]# mkdir jenkins_docker
[root@bigdata01 docker]# cd jenkins_docker/
[root@bigdata01 gitlab_docker]# pwd
/usr/local/docker/jenkins_docker
c.创建docker-compose.yml文件
cd /usr/local/docker/jenkins_docker
vi docker-compose.yml
-----------------------------------------------------------------------------------------------------
version: "3.1"
services:
jenkins:
image: jenkins/jenkins:2.401.2-lts
container_name: jenkins
ports:
- 8080:8080
- 50000:50000
volumes:
- ./data/:/var/jenkins_home/
d.启动docker-compose
cd /usr/local/docker/jenkins_docker
docker-compose up -d --启动
docker-compose logs -f jenkins --日志
e.解决权限问题
cd /usr/local/docker/jenkins_docker
chmod -R 777 data
f.查看日志
docker restart jenkins
docker-compose logs -f jenkins --日志
g.访问
http://127.0.0.1:8080 --访问
3b4119ffb9994eb9af73b3a38a89b311
h.获取默认密码
[root@bigdata01 gitlab_docker]# docker-compose logs -f jenkins --查看日志
jenkins | Jenkins initial setup is required. An admin user has been created and a password generated.
jenkins | Please use the following password to proceed to installation:
jenkins |
jenkins | 3b4119ffb9994eb9af73b3a38a89b311
jenkins |
jenkins | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
i.镜像地址
[root@bigdata02 data]# vi /usr/local/docker/jenkins_docker/data/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>http://mirror.esuni.jp/jenkins/updates/update-center.json</url>
</site>
</sites>
j.下载插件
Git Parameter
Publish Over SSH
k.修改密码
http://127.0.0.1:8080 --访问
root
12345678
l.设置容器开机自启动
a.开启
docker update --restart=always jenkins
b.关闭
docker update --restart=no jenkins
01.DevOps
DevOps的方式可以让公司能够更快地应对更新和市场发展变化,开发可以快速交付,部署也更加稳定。
核心就在于简化Dev和Ops团队之间的流程,使整体软件开发过程更快速
---------------------------------------------------------------------------------------------------------
整体的软件开发流程包括:
PLAN:开发团队根据客户的目标制定开发计划
CODE:根据PLAN开始编码过程,需要将不同版本的代码存储在一个库中。
BUILD:编码完成后,需要将代码构建并且运行。
TEST:成功构建项目后,需要测试代码是否存在BUG或错误。
DEPLOY:代码经过手动测试和自动化测试后,认定代码已经准备好部署并且交给运维团队。
OPERATE:运维团队将代码部署到生产环境中。
MONITOR:项目部署上线后,需要持续的监控产品。
INTEGRATE:然后将监控阶段收到的反馈发送回PLAN阶段,整体反复的流程就是DevOps的核心,即持续集成、持续部署。
02.CI/CD
Jenkins最主要的工作就是将GitLab上可以构建的工程代码拉取并且进行构建,再根据流程可以选择发布到测试环境或是生产环境。
---------------------------------------------------------------------------------------------------------
一般是GitLab上的代码经过大量的测试后,确定发行版本,再发布到生产环境。
CI/CD可以理解为:
CI过程即是通过Jenkins将代码拉取、构建、制作镜像交给测试人员测试。
持续集成:让软件代码可以持续的集成到主干上,并自动构建和测试。
CD过程即是通过Jenkins将打好标签的发行版本代码拉取、构建、制作镜像交给运维人员部署。
持续交付:让经过持续集成的代码可以进行手动部署。
持续部署:让可以持续交付的代码随时随地的自动化部署
03.Jenkins全局工具配置、目标服务器
a.全局工具配置
a.安装jdk、maven
tar -zxvf jdk-8u202-linux-x64.tar.gz -C /usr/local/docker/jenkins_docker/data
tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /usr/local/docker/jenkins_docker/data
b.将jdk、maven配置到jenkins容器中
jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> jdk1.8.0_202 /var/jenkins_home/jdk1.8.0_202
jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> git-2.38.1 /usr/bin/git
jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> apache-maven-3.6.3 /var/jenkins_home/apache-maven-3.6.3
b.目标服务器
jenkins -> Dashboard -> 系统管理 -> 系统配置 -> SSH Servers -> SSH Server Name 192.168.2.129
-> Hostname 192.168.2.129
-> Username root
-> Use Password 123456
-> Remote Directory /data/mytest_docker/
04.基础CI操作
a.第1步
工程mytest -> 工作空间 -> mytest / .git
.idea
src
target:mytest-0.0.1-SNAPSHOT.jar
pom.xm
b.第2步
Dockerfile -> FROM daocloud.io/library/java:8u40-jdk
COPY mytest-0.0.1-SNAPSHOT.jar /usr/local/
WORKDIR /usr/local
CMD java -jar mytest-0.0.1-SNAPSHOT.jar
docker-compose.yml -> version: '3.1'
services:
mytest:
build:
context: ./
dockerfile: Dockerfile
image: mytest: v1.0.0
container_name: mytest
ports:
- 8088:8088
MyTest.java -> @RestController
public class MyTest {
@GetMapping("/test")
public String Test() {
return "Jenkin 3.0";
}
}
c.第3步
工程mytest -> 配置 -> 源码管理 -> http://192.168.2.129:8929/troyekk/mytest.git -> 保存
d.第4步
工程mytest -> 配置 -> Build Steps -> 调用顶层 Maven 目标 -> Maven版本:apache-maven-3.6.3
目标:clean package -DskipTests
e.第5步
工程mytest -> 配置 -> 构建后操作 -> Send build artifacts over SSH -> Name:192.168.2.129
Transfer Set Source files:target/*.jar docker/*
Exec command:cd /data/mytest_docker/docker/
mv ../target/*.jar ./
docker-compose down
docker-compose up -d --build
docker image prune -f
f.第6步
工程mytest -> 立即构建(手动)
g.第7步
http://192.168.2.129:8088/test
05.基础CD操作
a.基于tag
git tag v1.0.0 && git push origin v1.0.0
git tag v2.0.0 && git push origin v2.0.0
b.第1步
工程mytest -> 配置 -> 参数化构建过程 -> 参数类型:标签、默认值:origin/master
c.第2步
工程mytest -> 配置 -> Build Steps -> 执行 shell -> git checkout $tag
d.第3步
工程mytest -> 立即构建(手动)
e.第4步
http://192.168.2.129:8088/test
5.3 sonarqube
00.使用docker-compose部署
a.安装
docker pull postgres:latest
docker pull sonarqube:8.9.3-community
b.创建文件夹
/data/sonarqube_docker/
c.创建docker-compose.yml文件
vi docker-compose.yml
-----------------------------------------------------------------------------------------------------
version: "3"
services:
sonarqube:
image: sonarqube:7.4-community
ports:
- "9089:9000"
networks:
- sonarnet
environment:
- SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
volumes:
- sonarqube_conf:/opt/sonarqube/conf
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins
db:
image: postgres:11.1
networks:
- sonarnet
environment:
- POSTGRES_USER=sonar
- POSTGRES_PASSWORD=sonar
volumes:
- postgresql_data:/var/lib/postgresql/data
networks:
sonarnet:
driver: bridge
volumes:
sonarqube_conf:
sonarqube_data:
sonarqube_extensions:
sonarqube_bundled-plugins:
postgresql_data:
c.创建docker-compose.yml文件
version: "3.1"
services:
db:
image: postgres
container_name: db
ports:
- 5432:5432
networks:
- sonarnet
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
sonarqube:
image: sonarqube:8.9.3-community
container_name: sonarqube
depends_on:
- db
ports:
- 9089:9000
networks:
- sonarnet
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
networks:
sonarnet:
driver: bridge
d.启动docker-compose
cd /data/sonarqube_docker/
docker-compose up -d --启动
docker logs -f sonargube --日志
e.配置
vi /etc/sysctl.conf --永久修改
vm.max_map_count=262144 --追加内容
sudo sysctl -p --刷新
f.访问
http://127.0.0.1:9089/ --访问(初始用户admin、初始密码admin)
admin
12345678
g.设置容器开机自启动
a.开启
docker update --restart=always sonarqube db
b.关闭
docker update --restart=no sonarqube db
h.容器
docker stop sonarqube db
docker start sonarqube db
01.介绍
SonarQube 是一个开源的代码分析平台,用来持续分析和评测项目源代码的质量。
通过SonarQube我们可以检测出项目中重复代码,潜在bug,代码规范,安全性漏洞等问题,并通过SonarQube web UI展示出来。
1、代码质量和安全扫描和分析平台。
2、多维度分析代码:代码量、安全隐患、编写规范隐患、重复度、复杂度、代码增量、测试覆盖率等。
3、支持25+编程语言的代码扫描和分析,包含java\python\C#\javascript\go\C++等。
4、涵盖了编程语言的静态扫描规则: 代码编写规范+安全规范。
5、能够与代码编辑器、CI/CD平台完美集成。
6、能够与SCM集成,可以直接在平台上看到代码问题是由哪位开发人员提交。
7、帮助程序猿写出更干净、更安全的代码。
02.sonar静态代码扫描由2部分组成:sonarQube平台,sonar-scanner扫描器
Web界面管理平台
1)展示所有的项目代码的质量数据。
2)配置质量规则、管理项目、配置通知、配置SCM等。
sonarScanner: 代码扫描工具
1)专门用来扫描和分析项目代码。支持20+语言。
2)代码扫描和分析完成之后,会将扫描结果存储到数据库当中,在sonarQube平台可以看到扫描数据。
03.方式一:Maven实现代码检测
a.修改Maven的settings.xml文件配置Sonar Qube信息
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.login>admin</sonar.login>
<sonar.password>12345678</sonar.password>
<sonar.host.url>http://192.168.2.129:9089</sonar.host.url>
</properties>
</profile>
b.执行命令检测代码
cd D:\software_xare\workspace_idea\mytest
mvn sonar:sonar
c.查看Sonar Qube界面检测结果
略
04.方式二:Sonar-scanner实现代码检测
a.安装
[root@bigdata02 data]# cd /data/jenkins_docker/data/
[root@bigdata02 data]# unzip sonar-scanner-cli-4.8.0.2856-linux.zip
[root@bigdata02 conf]# cd /data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/bin/
[root@bigdata02 bin]# pwd
/data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/bin
b.配置
vi /data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/conf/sonar-scanner.properties
#----- Default SonarQube server
sonar.host.url=http://192.168.2.129:9089
#----- Default source code encoding
sonar.sourceEncoding=UTF-8
c.执行命令检测代码
[root@bigdata02 mytest]# cd /data/jenkins_docker/data/workspace/mytest/
[root@bigdata02 mytest]# /data/jenkins_docker/data/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=linux-test -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=linux-test -Dsonar.java.binaries=./target/
05.方式三:Jenkins整合SonarQube
a.全局工具配置
jenkins -> Dashboard -> 系统管理 -> 全局工具配置 -> sonar-scanner-4.8.0.2856-linux /var/jenkins_home/sonar-scanner-4.8.0.2856-linux
b. SonarQube servers
jenkins -> Dashboard -> 系统管理 -> 系统配置 -> SonarQube servers -> Name SonarQube
Server URL http://192.168.2.129:9089/
Secret text 003ebe4eacdae15ca461a47af1eb4118d93caaa3
c.第1步
工程mytest -> 配置 -> Build Steps -> Execute SonarQube Scanner -> JDK jdk1.8.0_202
-> Analysis properties sonar.projectname=${JOB_NAME}
sonar.projectKey=${JOB_NAME}
sonar.source=./
sonar.java.binaries=target
d.第2步
工程mytest -> 立即构建(手动)
e.第3步
http://192.168.2.129:9089/
5.4 rabbitmq+canal
01.环境配置
a.docker-compose.yml
version: '3.8'
services:
redis:
container_name: redis
image: redis:6.2.7
restart: always
networks:
- app_net
ports:
- "6379:6379"
volumes:
- /usr/local/docker/redis/data:/data
- /usr/local/docker/redis/config/redis.conf:/usr/local/redis/config/redis.conf
- /usr/local/docker/redis/logs:/logs
command: [ "redis-server","/usr/local/redis/config/redis.conf" ]
mysql:
container_name: mysql
image: mysql:8.0.30
restart: always
networks:
- app_net
ports:
- "3306:3306"
volumes:
- /usr/local/docker/mysql/data:/var/lib/mysql
- /usr/local/docker/mysql/config:/etc/mysql/conf.d
environment:
MYSQL_ROOT_PASSWORD: root
TZ: Asia/Shanghai
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--log-bin=/var/lib/mysql/mysql-bin
--server-id=1
--binlog-format=ROW
--expire_logs_days=7
--max_binlog_size=500M
canal:
image: canal/canal-server:v1.1.5
container_name: canal
restart: always
ports:
- 11110:11110
- 11111:11111
- 11112:11112
volumes:
- /usr/local/docker/canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties
- /usr/local/docker/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties
- /usr/local/docker/canal/logs:/home/admin/canal-server/logs
networks:
- app_net
depends_on:
- mysql
- rabbitmq
rabbitmq:
image: rabbitmq:3-management
container_name: rabbitmq
restart: always
ports:
- "5672:5672"
- "15672:15672"
volumes:
- /usr/local/docker/rabbitmq/data/:/var/lib/rabbitmq/
- /usr/local/docker/rabbitmq/log/:/var/log/rabbitmq/
environment:
- RABBITMQ_DEFAULT_USER=guest
- RABBITMQ_DEFAULT_PASS=guest
networks:
- app_net
networks:
app_net:
driver: bridge
b.常用命令
# 后台启动容器编排文件
docker-compose up -d [service]
# 停止up命令所启动的容器,并移除网络
docker-compose down
# 进入指定容器
docker-compose exec [service]
# 列出项目中所有的容器
docker-compose ps [service]
# 重启项目中容器
docker-compose restart [service]
# 删除项目中所有容器
docker-compose rm -f [service]
# 启动项目中容器(或指定容器)
docker-compose start [service]
# 暂停项目中容器(或指定容器)
docker-compose stop [service]
c.镜像服务启动状态
[root@lavm-13jmyj9ugf docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0d4260bc557b canal/canal-server:v1.1.5 "/alidata/bin/main.s…" 38 minutes ago Up 38 minutes 9100/tcp, 0.0.0.0:11110-11112->11110-11112/tcp, :::11110-11112->11110-11112/tcp canal
c66b3f1f13a9 mysql:8.0.30 "docker-entrypoint.s…" 38 minutes ago Up 38 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
645e27bd4001 rabbitmq:3-management "docker-entrypoint.s…" 5 hours ago Up 49 minutes 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, :::5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp, :::15672->15672/tcp rabbitmq
f55d42cbbd8e redis:6.2.7 "docker-entrypoint.s…" 3 days ago Up 49 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
02.binlog配置
a.docker-compose command 配置 binlog
--log-bin=/var/lib/mysql/mysql-bin
--server-id=1
--binlog-format=ROW
--expire_logs_days=7
--max_binlog_size=500M
b.创建canal用户,以及查看是否开启binlog
mysql> CREATE USER canal IDENTIFIED BY 'canal';
Query OK, 0 rows affected (0.05 sec)
mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
Query OK, 0 rows affected (0.05 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.05 sec)
mysql> select * from mysql.user where User = 'canal';
+------+-------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+--------------------------+-----------------+
| Host | User | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Show_db_priv | Super_priv | Create_tmp_table_priv | Lock_tables_priv | Execute_priv | Repl_slave_priv | Repl_client_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Create_user_priv | Event_priv | Trigger_priv | Create_tablespace_priv | ssl_type | ssl_cipher | x509_issuer | x509_subject | max_questions | max_updates | max_connections | max_user_connections | plugin | authentication_string | password_expired | password_last_changed | password_lifetime | account_locked | Create_role_priv | Drop_role_priv | Password_reuse_history | Password_reuse_time | Password_require_current | User_attributes |
+------+-------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+--------------------------+-----------------+
| % | canal | Y | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | N | Y | Y | N | N | N | N | N | N | N | N | | | | | 0 | 0 | 0 | 0 | mysql_native_password | *E3619321C1A937C46A0D8BD1DAC39F93B27D4458 | N | 2025-03-10 11:53:49 | NULL | N | N | N | NULL | NULL | NULL | NULL |
+------+-------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+--------------+------------+-----------------------+------------------+--------------+-----------------+------------------+------------------+----------------+---------------------+--------------------+------------------+------------+--------------+------------------------+----------+------------+-------------+--------------+---------------+-------------+-----------------+----------------------+-----------------------+-------------------------------------------+------------------+-----------------------+-------------------+----------------+------------------+----------------+------------------------+---------------------+--------------------------+-----------------+
1 row in set (0.08 sec)
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.30 sec)
03.canal相关配置文件
a.canal.properties主要核心配置
canal.serverMode=rabbitMQ:选择 RabbitMQ 作为通知服务模型
rabbitmq.host=rabbitmq:基于 Docker 同一网络下,可以使用容器名称代替 host
rabbitmq.queue、rabbitmq.routingKey、rabbitmq.exchange : RabbitMQ 的三件套,用于后续创建具体通道监听
-----------------------------------------------------------------------------------------------------
#################################################
######### common argument #############
#################################################
# tcp, kafka, rocketMQ, rabbitMQ, pulsarMQ 支持的服务模型,tcp直连或mq,此处我选择RabbitMQ
canal.serverMode=rabbitMQ
##################################################
######### RabbitMQ #############
##################################################
rabbitmq.host=rabbitmq
rabbitmq.virtual.host=/
rabbitmq.exchange=canal-exchange
rabbitmq.username=guest
rabbitmq.password=guest
rabbitmq.queue=canal-queue
rabbitmq.routingKey=canal-routing-key
rabbitmq.deliveryMode=
b.instance.properties 主要核心配置
canal.instance.master.address 数据库地址
canal.instance.dbUsername 数据库用户名
canal.instance.dbPassword 数据库密码
canal.mq.topic RabbitMQ路由
-----------------------------------------------------------------------------------------------------
# 数据地址,此处mysql,是因为canal和mysql是同一network下,可以使用容器名称代替具体ip
canal.instance.master.address=mysql:3306
# username/password
canal.instance.dbUsername=root
canal.instance.dbPassword=root
# mq config
canal.mq.topic=canal-routing-key
c.canal.properties 完整文件
#################################################
######### common argument #############
#################################################
canal.ip=
canal.register.ip=
canal.port=11111
canal.metrics.pull.port=11112
canal.admin.port=11110
canal.admin.user=admin
canal.admin.passwd=
canal.zkServers=
canal.zookeeper.flush.period=1000
canal.withoutNetty=false
canal.serverMode=rabbitMQ
canal.file.data.dir=${canal.conf.dir}
canal.file.flush.period=1000
canal.instance.memory.buffer.size=16384
canal.instance.memory.buffer.memunit=1024
canal.instance.memory.batch.mode=MEMSIZE
canal.instance.memory.rawEntry=true
canal.instance.detecting.enable=false
canal.instance.detecting.sql=select 1
canal.instance.detecting.interval.time=3
canal.instance.detecting.retry.threshold=3
canal.instance.detecting.heartbeatHaEnable=false
canal.instance.transaction.size=1024
canal.instance.fallbackIntervalInSeconds=60
canal.instance.network.receiveBufferSize=16384
canal.instance.network.sendBufferSize=16384
canal.instance.network.soTimeout=30
canal.instance.filter.druid.ddl=true
canal.instance.filter.query.dcl=false
canal.instance.filter.query.dml=false
canal.instance.filter.query.ddl=false
canal.instance.filter.table.error=false
canal.instance.filter.rows=false
canal.instance.filter.transaction.entry=false
canal.instance.filter.dml.insert=false
canal.instance.filter.dml.update=false
canal.instance.filter.dml.delete=false
canal.instance.binlog.format=ROW,STATEMENT,MIXED
canal.instance.binlog.image=FULL,MINIMAL,NOBLOB
canal.instance.get.ddl.isolation=false
canal.instance.parser.parallel=true
canal.instance.parser.parallelThreadSize = 16
canal.instance.parser.parallelBufferSize=256
canal.instance.tsdb.enable=true
canal.instance.tsdb.dir=${canal.file.data.dir:../conf}/${canal.instance.destination:}
canal.instance.tsdb.url=jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.dbUsername=canal
canal.instance.tsdb.dbPassword=canal
canal.instance.tsdb.snapshot.interval=24
canal.instance.tsdb.snapshot.expire=360
#################################################
######### destinations #############
#################################################
canal.destinations=example
canal.conf.dir=../conf
canal.auto.scan=true
canal.auto.scan.interval=5
canal.auto.reset.latest.pos.mode=false
canal.instance.tsdb.spring.xml=classpath:spring/tsdb/h2-tsdb.xml
canal.instance.global.mode=spring
canal.instance.global.lazy=false
canal.instance.global.manager.address=${canal.admin.manager}
canal.instance.global.spring.xml=classpath:spring/file-instance.xml
##################################################
######### MQ Properties #############
##################################################
canal.aliyun.accessKey=
canal.aliyun.secretKey=
canal.aliyun.uid=
canal.mq.flatMessage=true
canal.mq.canalBatchSize=50
canal.mq.canalGetTimeout=100
canal.mq.accessChannel=local
canal.mq.database.hash=true
canal.mq.send.thread.size=30
canal.mq.build.thread.size=8
##################################################
######### Kafka #############
##################################################
kafka.bootstrap.servers=127.0.0.1:9092
kafka.acks=all
kafka.compression.type=none
kafka.batch.size=16384
kafka.linger.ms=1
kafka.max.request.size=1048576
kafka.buffer.memory=33554432
kafka.max.in.flight.requests.per.connection=1
kafka.retries=0
kafka.kerberos.enable=false
kafka.kerberos.krb5.file=../conf/kerberos/krb5.conf
kafka.kerberos.jaas.file=../conf/kerberos/jaas.conf
##################################################
######### RocketMQ #############
##################################################
rocketmq.producer.group=test
rocketmq.enable.message.trace=false
rocketmq.customized.trace.topic=
rocketmq.namespace=
rocketmq.namesrv.addr=127.0.0.1:9876
rocketmq.retry.times.when.send.failed=0
rocketmq.vip.channel.enabled=false
rocketmq.tag=
##################################################
######### RabbitMQ #############
##################################################
rabbitmq.host=rabbitmq
rabbitmq.virtual.host=/
rabbitmq.exchange=canal-exchange
rabbitmq.username=guest
rabbitmq.password=guest
rabbitmq.queue=canal-queue
rabbitmq.routingKey=canal-routing-key
rabbitmq.deliveryMode=
##################################################
######### Pulsar #############
##################################################
pulsarmq.serverUrl=
pulsarmq.roleToken=
pulsarmq.topicTenantPrefix=
d.instance.properties 完整文件
#################################################
## mysql serverId , v1.0.26+ will autoGen
# canal.instance.mysql.slaveId=0
# enable gtid use true/false
canal.instance.gtidon=false
# rds oss binlog
canal.instance.rds.accesskey=
canal.instance.rds.secretkey=
canal.instance.rds.instanceId=
# position info
canal.instance.master.address=mysql:3306
canal.instance.master.journal.name=
canal.instance.master.position=
canal.instance.master.timestamp=
canal.instance.master.gtid=
# multi stream for polardbx
canal.instance.multi.stream.on=false
# ssl
#canal.instance.master.sslMode=DISABLED
#canal.instance.master.tlsVersions=
#canal.instance.master.trustCertificateKeyStoreType=
#canal.instance.master.trustCertificateKeyStoreUrl=
#canal.instance.master.trustCertificateKeyStorePassword=
#canal.instance.master.clientCertificateKeyStoreType=
#canal.instance.master.clientCertificateKeyStoreUrl=
#canal.instance.master.clientCertificateKeyStorePassword=
# table meta tsdb info
canal.instance.tsdb.enable=true
#canal.instance.tsdb.url=jdbc:mysql://127.0.0.1:3306/canal_tsdb
#canal.instance.tsdb.dbUsername=canal
#canal.instance.tsdb.dbPassword=canal
#canal.instance.standby.address =
#canal.instance.standby.journal.name =
#canal.instance.standby.position =
#canal.instance.standby.timestamp =
#canal.instance.standby.gtid=
# username/password
canal.instance.dbUsername=root
canal.instance.dbPassword=admin123!@#
canal.instance.connectionCharset = UTF-8
# enable druid Decrypt database password
canal.instance.enableDruid=false
#canal.instance.pwdPublicKey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALK4BUxdDltRRE5/zXpVEVPUgunvscYFtEip3pmLlhrWpacX7y7GCMo2/JM6LeHmiiNdH1FWgGCpUfircSwlWKUCAwEAAQ==
# table regex
canal.instance.filter.regex=.*\\..*
# table black regex
canal.instance.filter.black.regex=mysql\\.slave_.*
# table field filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)
#canal.instance.filter.field=test1.t_product:id/subject/keywords,test2.t_company:id/name/contact/ch
# table field black filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)
#canal.instance.filter.black.field=test1.t_product:subject/product_image,test2.t_company:id/name/contact/ch
# mq config
canal.mq.topic=canal-routing-key
# dynamic topic route by schema or table regex
#canal.mq.dynamicTopic=mytest1.user,topic2:mytest2\\..*,.*\\..*
canal.mq.partition=0
# hash partition config
#canal.mq.enableDynamicQueuePartition=false
#canal.mq.partitionsNum=3
#canal.mq.dynamicTopicPartitionNum=test.*:4,mycanal:6
#canal.mq.partitionHash=test.table:id^name,.*\\..*
#################################################
e.检查配置是否与宿主机一致
进入容器内部:docker exec -it canal bash
检查配置文件内容是否与宿主机一致:
cat /home/admin/canal-server/conf/canal.properties
cat /home/admin/canal-server/conf/example/instance.properties
f.开启相关端口防火墙配置
canal:11110、11111、11112
mysql:3306
redis:6379
RabbitMQ: 15672、5672
04.代码实现
a.相关pom依赖引入
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.15</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- Spring Boot MQ 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- canal -->
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>1.1.0</version>
</dependency>
b.完整pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.neo</groupId>
<artifactId>code-repository</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.15</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<name>code-repository</name>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hutool.version>5.8.20</hutool.version>
<mysql.version>8.0.30</mysql.version>
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<redis.version>3.1.0</redis.version>
<druid.version>1.2.16</druid.version>
<fastjson.version>1.2.83</fastjson.version>
<sa-token.version>1.37.0</sa-token.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>${sa-token.version}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
c.application.yml 配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
publisher-confirm-type: correlated
publisher-returns: true
d.完整application.yml配置
server:
port: 8088
servlet:
context-path: /api
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_v1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
validation-query: SELECT 1
test-while-idle: true
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: admin123
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
filter:
stat:
enabled: true
log-slow-sql: true
slow-sql-millis: 1000
wall:
enabled: true
config:
drop-table-allow: false
redis:
host: localhost
port: 6379
password: 123456
database: 0
timeout: 5000
lettuce:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
mail:
host: smtp.aliyun.com
username:
password:
port: 25
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
publisher-confirm-type: correlated
publisher-returns: true
mybatis-plus:
mapper-locations: classpath*:mapper/*_Mapper.xml
global-config:
db-config:
logic-delete-field: delFlag
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
e.RabbitConstants 基础常量配置
public interface RabbitConstants {
interface Canal {
String QUEUE = "canal-queue";
String EXCHANGE = "canal-exchange";
String ROUTING = "canal-routing-key";
}
interface EventType {
String INSERT = "INSERT";
String UPDATE = "UPDATE";
String DELETE = "DELETE";
}
}
f.CanalMqConfigure MQ队列交换机配置
@Configuration
public class CanalMqConfigure {
@Bean
public Queue queue() {
return new Queue(RabbitConstants.Canal.QUEUE, true);
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange(RabbitConstants.Canal.EXCHANGE, true, false);
}
@Bean
public Binding bindingCanal() {
return BindingBuilder.bind(queue())
.to(directExchange())
.with(RabbitConstants.Canal.ROUTING);
}
}
g.CanalConsumer 消费者
package com.neo.core.canal;
import com.neo.core.constant.RabbitConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
@RabbitListener(queues = RabbitConstants.Canal.QUEUE)
public class CanalConsumer {
@RabbitHandler
public void execute(Map<String, Object> msg) {
log.info("canal消息监听事件触发,消息内容:{}", msg);
boolean isDdl = (boolean) msg.get("isDdl");
if (isDdl) {
return;
}
String database = (String) msg.get("database");
String table = (String) msg.get("table");
String type = (String) msg.get("type");
List<?> data = (List<?>) msg.get("data");
log.info("database:{}.table:{}", database, table);
if (RabbitConstants.EventType.INSERT.equalsIgnoreCase(type)) {
System.out.println("INSERT");
} else if (RabbitConstants.EventType.UPDATE.equalsIgnoreCase(type)) {
System.out.println("UPDATE");
} else if (RabbitConstants.EventType.DELETE.equalsIgnoreCase(type)) {
System.out.println("DELETE");
} else {
// 其他事件
}
}
}
6 方式2:通过deploy.sh自定义脚本启动项目
00.命令
deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
01.自由风格
[root@bigdata02 ~]# cd /data/harbor_docker/
[root@bigdata02 harbor_docker]# vi deploy.sh
-------------------------------------------------------------------------------------------------
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5
imageName=$harbor_url/$harbor_project_name/$project_name:$tag
containerId=`docker ps -a | grep ${project_name} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
docker stop $containerId
docker rm $containerId
echo "Delete Container Success"
fi
imageId=`docker images | grep ${project_name} | awk '{print $3}'`
if [ "$imageId" != "" ] ; then
docker rmi -f $imageId
echo "Delete Image Success"
fi
docker login -u DevOps -p P@ssw0rd $harbor_url
docker pull $imageName
docker run -d -p $port:$port --name $project_name $imageName
echo "Start Container Success"
echo $project_name
02.流水线风格
// 所有的脚本命令都放在pipeline中
pipeline {
// 指定任务在哪个集群节点中执行
agent any
// 声明全局变量
environment {
harborUser = 'admin'
harborPasswd = 'Harbor12345'
harborAddress = '192.168.2.129:8085'
harborRepo = 'repo'
}
// 存放所有任务的合集
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.129:8929/troyekk/mytest.git']])
}
}
stage('通过maven构建项目') {
steps {
sh '/var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
}
}
stage('通过SonarQube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/'
}
}
stage('通过Docker制作自定义镜像') {
steps {
sh '''
cp ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/
'''
}
}
stage('通过自定义镜像推送到Harbor') {
steps {
sh '''
docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
'''
}
}
stage('通过Publish Over SSH通知目标服务器') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
6.1 harbor:自由风格
00.安装
a.安装包
tar -zxvf harbor-offline-installer-v2.3.4.tgz -C /usr/local/
b.配置
cd /usr/local/harbor
cp harbor.yml.tmpl harbor.yml
-----------------------------------------------------------------------------------------------------
vi harbor.yml
hostname: 192.168.2.129
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 8085
#https:
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
harbor_admin_password: Harbor12345
c.启动Harbor
./install.sh
d.访问
http://127.0.0.1:8085/
admin
Harbor12345
e.设置容器开机自启动
a.开启
docker update --restart=always nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log
b.关闭
docker update --restart=no nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log
f.容器
docker stop nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log
docker start nginx harbor-jobservice harbor-core harbor-portal redis harbor-db registryctl registry harbor-log
01.介绍
前面在部署项目时,我们主要采用Jenkins推送jar包到指定服务器,再通过脚本命令让目标服务器对当前jar进行部署,
这种方式在项目较多时,每个目标服务器都需要将jar包制作成自定义镜像再通过docker进行启动,重复操作比较多,会降低项目部署时间。
---------------------------------------------------------------------------------------------------------
我们可以通过Harbor作为私有的Docker镜像仓库。让Jenkins统一将项目打包并制作成Docker镜像发布到Harbor仓库中,
只需要通知目标服务,让目标服务统一去Harbor仓库上拉取镜像并在本地部署即可。
Docker官方提供了Registry镜像仓库,但是Registry的功能相对简陋。
Harbor是VMware公司提供的一款镜像仓库,提供了权限控制、分布式发布、强大的安全扫描与审查机制等功能
02.Harbor的基本操作
a.修改配置文件
vi /etc/docker/daemon.json
{
"data-root":"/data/docker",
"registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
"insecure-registries" : ["192.168.2.129:8085"]
}
-----------------------------------------------------------------------------------------------------
systemctl daemon-reload --重新加载daemon.json文件
systemctl restart docker.service --重启docker服务
docker info --验证
b.修改镜像
[root@bigdata02 harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytest v5.0.0 0818e45d38be 22 hours ago 833MB
mytest v2.0.0 c3136680a20f 22 hours ago 833MB
mytest v1.0.0 3b0efa72116f 25 hours ago 833MB
-----------------------------------------------------------------------------------------------------
[root@bigdata02 harbor]# docker tag 0818e45d38be 192.168.2.129:8085/repo/mytest:v5.0.0
[root@bigdata02 harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.2.129:8085/repo/mytest v5.0.0 0818e45d38be 22 hours ago 833MB
mytest v5.0.0 0818e45d38be 22 hours ago 833MB
mytest v2.0.0 c3136680a20f 22 hours ago 833MB
c.PUSH镜像到Harbor
[root@bigdata02 harbor]# docker login -u admin -p Harbor12345 192.168.2.129:8085
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
-----------------------------------------------------------------------------------------------------
[root@bigdata02 harbor]# docker push 192.168.2.129:8085/repo/mytest:v5.0.0
The push refers to repository [192.168.2.129:8085/repo/mytest]
de80d7910b36: Pushed
50ecdabc71b7: Pushed
3e9cda2eceec: Pushed
5f70bf18a086: Pushed
bb7b60f93aea: Pushed
0ef3d186e2bd: Pushed
1e0931f30489: Pushed
fd97e4a10f39: Pushed
v5.0.0: digest: sha256:1de4a7c964f041d0a817555b9759aa145a60cc2b272d83de5ff460160656408c size: 2828
d.从Harbor来PULL镜像
[root@bigdata02 harbor]# docker pull 192.168.2.129:8085/repo/mytest:v5.0.0
v5.0.0: Pulling from repo/mytest
4f4fb700ef54: Already exists
44180127f7f4: Already exists
cf743f247f7a: Already exists
582dc57764f8: Already exists
d2318f6b7a5a: Already exists
971a7b8b8320: Already exists
0d862dd52090: Already exists
1935c08d3603: Already exists
Digest: sha256:1de4a7c964f041d0a817555b9759aa145a60cc2b272d83de5ff460160656408c
Status: Downloaded newer image for 192.168.2.129:8085/repo/mytest:v5.0.0
192.168.2.129:8085/repo/mytest:v5.0.0
-----------------------------------------------------------------------------------------------------
[root@bigdata02 harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.2.129:8085/repo/mytest v5.0.0 0818e45d38be 22 hours ago 833MB
03.Jenkins容器内部使用Docker
a.创建一个脚本(例如set-docker-socket-permissions.sh)并添加以下内容:
#!/bin/bash
# Wait for Docker daemon to start (if needed)
# sleep 5
# Set the correct owner and permissions for docker.sock
chown root:root /var/run/docker.sock
chmod o+rw /var/run/docker.sock
b.将脚本复制到系统的一个适当位置(例如/usr/local/bin)并添加可执行权限:
sudo cp set-docker-socket-permissions.sh /usr/local/bin
sudo chmod +x /usr/local/bin/set-docker-socket-permissions.sh
c.创建一个systemd服务单元文件(例如set-docker-socket-permissions.service)来在Docker服务启动之后自动运行该脚本,并添加以下内容:
[Unit]
Description=Set Docker Socket Permissions After Docker Start
After=docker.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/set-docker-socket-permissions.sh
[Install]
WantedBy=multi-user.target
d.将set-docker-socket-permissions.service复制到/etc/systemd/system/目录,并刷新systemd服务列表:
sudo cp set-docker-socket-permissions.service /etc/systemd/system/
sudo systemctl daemon-reload
e.启用并启动该服务:
sudo systemctl enable set-docker-socket-permissions.service
sudo systemctl start set-docker-socket-permissions.service
-----------------------------------------------------------------------------------------------------
现在,每当Docker服务启动时,set-docker-socket-permissions.sh脚本将被执行,并设置docker.sock的权限和所有者
04.Jenkins容器内部使用Docker
a.第1步
[root@bigdata02 ~]# cd /var/run/
[root@bigdata02 run]# chown root:root /var/run/docker.sock --将docker.sock设置为root
[root@bigdata02 run]# ll
drwx------ 8 root root 180 Jul 23 05:15 docker
-rw-r--r-- 1 root root 4 Jul 23 05:14 docker.pid
srw-rw---- 1 root root 0 Jul 23 05:14 docker.sock
[root@bigdata02 run]# chmod o+rw /var/run/docker.sock --修改权限,其他用户也可以使用docker
b.第2步
[root@bigdata02 run]# cd /data/jenkins_docker/
[root@bigdata02 jenkins_docker]# vi docker-compose.yml
-----------------------------------------------------------------------------------------------------
version: "3.1"
services:
jenkins:
image: jenkins/jenkins:2.401.2-lts
container_name: jenkins
ports:
- 8080:8080
- 50000:50000
volumes:
- ./data/:/var/jenkins_home/
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /etc/docker/daemon.json:/etc/docker/daemon.json
c.第3步
docker-compose up -d --启动
d.测试
[root@bigdata02 jenkins_docker]# docker exec -it jenkins bash
jenkins@d1ba4ac42552:/$ docker version --Jenkins容器内部使用Docker
Client: Docker Engine - Community
Version: 24.0.4
API version: 1.43
Go version: go1.20.5
Git commit: 3713ee1
Built: Fri Jul 7 14:54:21 2023
OS/Arch: linux/amd64
Context: default
05.操作
a.Jenkins实现制作自定义镜像并推送harbor
工程mytest -> 配置 -> Build Steps -> 执行 shell -> cp target/*.jar docker/
docker build -t mytest:$tag docker/
docker login -u admin -p Harbor12345 192.168.2.129:8085
docker tag mytest:$tag 192.168.2.129:8085/repo/mytest:$tag
docker push 192.168.2.129:8085/repo/mytest:$tag
b.目标服务器准备脚本文件1
a.脚本
[root@bigdata02 ~]# cd /data/harbor_docker/
[root@bigdata02 harbor_docker]# vi deploy.sh
-------------------------------------------------------------------------------------------------
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5
imageName=$harbor_url/$harbor_project_name/$project_name:$tag
containerId=`docker ps -a | grep ${project_name} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
docker stop $containerId
docker rm $containerId
echo "Delete Container Success"
fi
imageId=`docker images | grep ${project_name} | awk '{print $3}'`
if [ "$imageId" != "" ] ; then
docker rmi -f $imageId
echo "Delete Image Success"
fi
docker login -u DevOps -p P@ssw0rd $harbor_url
docker pull $imageName
docker run -d -p $port:$port --name $project_name $imageName
echo "Start Container Success"
echo $project_name
b.运行
[root@bigdata03 data]# echo $PATH --查看环境变量
[root@bigdata03 data]# mv deploy.sh /usr/bin --移至/usr/bin
[root@bigdata02 harbor_docker]# chmod a+x deploy.sh --权限为可执行
[root@bigdata02 harbor_docker]# ./deploy.sh 192.168.2.129:8085 repo mytest v6.0.0 8088 --PULL操作
dd91c4df71eb
dd91c4df71eb
Delete Container Success
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get "http://192.168.2.129:8085/v2/": unauthorized: authent ication required
v6.0.0: Pulling from repo/mytest
4f4fb700ef54: Already exists
44180127f7f4: Already exists
cf743f247f7a: Already exists
582dc57764f8: Already exists
d2318f6b7a5a: Already exists
971a7b8b8320: Already exists
0d862dd52090: Already exists
dbc5755bcdb5: Pull complete
Digest: sha256:92730c3e3cbb3a866dfa39ec370d1daaa962ee237005ba1f6e150519b13b19bf
Status: Downloaded newer image for 192.168.2.129:8085/repo/mytest:v6.0.0
192.168.2.129:8085/repo/mytest:v6.0.0
50ae64081cd88e03e4e78e61029b0f053cb693f653204f1840d65f8b2b253d6d
Start Container Success
mytest
[root@bigdata02 harbor_docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.2.129:8085/repo/mytest v6.0.0 5df1770a2201 21 minutes ago 833MB --PULL成功
jenkins/jenkins 2.401.2-lts 825c3e86c65d 3 weeks ago 471MB
c.目标服务器准备脚本文件2
工程mytest -> 配置 -> 构建后操作 -> 参数化构建过程 -> 字符参数 -> 名称:prot
默认值:8088
描述:容器启动时占用的端口
工程mytest -> 配置 -> General -> Send build artifacts over SSH -> Name:192.168.2.129
Exec command:deploy.sh 192.168.2.129:8085 repo ${JOB_NAME} $tag $port
工程mytest -> 配置 -> General -> Send build artifacts over SSH -> Name:192.168.2.130
Exec command:deploy.sh 192.168.2.129:8085 repo ${JOB_NAME} $tag $port
6.2 jenkinsfile:流水线
00.脚本示例
// 所有的脚本命令都放在pipeline中
pipeline {
// 指定任务在哪个集群节点中执行
agent any
// 声明全局变量
environment {
key = 'value'
}
// 存放所有任务的合集
stages {
stage('拉取git仓库代码') {
steps {
echo '拉取git仓库代码 - SUCCESS'
}
}
stage('通过maven构建项目') {
steps {
echo '通过maven构建项目 - SUCCESS'
}
}
stage('通过SonarQube做代码质量检测') {
steps {
echo '通过SonarQube做代码质量检测 - SUCCESS'
}
}
stage('通过Docker制作自定义镜像') {
steps {
echo '通过Docker制作自定义镜像 - SUCCESS'
}
}
stage('通过自定义镜像推送到Harbor') {
steps {
echo '通过自定义镜像推送到Harbor - SUCCESS'
}
}
stage('通过Publish Over SSH通知目标服务器') {
steps {
echo '通过Publish Over SSH通知目标服务器 - SUCCESS'
}
}
}
}
01.流水线1
harborUser = 'admin'
harborPasswd = 'Harbor12345'
harborAddress = '192.168.2.129:8085'
harborRepo = 'repo'
// 拉取git仓库代码
http://192.168.2.129:8929/troyekk/mytest.git
// 通过maven构建项目
/var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests
// 通过SonarQube做代码质量检测
/var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/
// 通过Docker制作自定义镜像
cp ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/
// 通过自定义镜像推送到Harbor
docker login -u admin -p Harbor12345 192.168.2.129:8085
docker tag mytest:$tag 192.168.2.129:8085/repo/mytest:$tag
docker push 192.168.2.129:8085/repo/mytest:$tag
docker login -u 用户名 -p 密码 harbor地址
docker tag ${JOB_NAME}:${tag} harbor地址/harbor仓库/${JOB_NAME}:${tag}
docker push harbor地址/harbor仓库/${JOB_NAME}:${tag}
docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
// 通过Publish Over SSH通知目标服务器
deploy.sh 192.168.2.129:8085 repo mytest v6.0.0 8088
deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
02.流水线2
// 所有的脚本命令都放在pipeline中
pipeline {
// 指定任务在哪个集群节点中执行
agent any
// 声明全局变量
environment {
harborUser = 'admin'
harborPasswd = 'Harbor12345'
harborAddress = '192.168.2.129:8085'
harborRepo = 'repo'
}
// 存放所有任务的合集
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.129:8929/troyekk/mytest.git']])
}
}
stage('通过maven构建项目') {
steps {
sh '/var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
}
}
stage('通过SonarQube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/'
}
}
stage('通过Docker制作自定义镜像') {
steps {
sh '''
cp ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/
'''
}
}
stage('通过自定义镜像推送到Harbor') {
steps {
sh '''
docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
'''
}
}
stage('通过Publish Over SSH通知目标服务器') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
03.构建后钉钉通知消息
a.插件
DingTalk
b.钉钉创建项目组
Webhook:https://oapi.dingtalk.com/robot/send?access_token=5a0d9031d33e1a659409d89418b00776c53cb8230c56cdef09f31dc87d48545e
7 方式3:通过kubectl apply -f pipeline.yml启动项目
7.1 kuboard
00.介绍
Kubernetes 从版本 v1.20 之后,弃用 Docker 这个容器运行时。
弃用 Docker 这个底层运行时,转而支持符合为 Kubernetes 创建的容器运行接口 Container Runtime Interface (CRI) 的运行时。
Docker 构建的镜像,将在你的集群的所有运行时中继续工作,一如既往。
01.组件
Pod
Container(容器)
Label(label)(标签)
Replication Controller(复制控制器)
Service(enter image description here)(服务)
Node(节点)
Kubernetes Master(Kubernetes主节点)
02.容器
RunC
Docker
podman
Containerted
03.安装Kuboard
a.检查 centos / hostname
# 在 master 节点和 worker 节点都要执行
cat /etc/redhat-release
# 此处 hostname 的输出将会是该机器在 Kubernetes 集群中的节点名字
# 不能使用 localhost 作为节点的名字
hostname
# 请使用 lscpu 命令,核对 CPU 信息
# Architecture: x86_64 本安装文档不支持 arm 架构
# CPU(s): 2 CPU 内核数量不能低于 2
lscpu
-----------------------------------------------------------------------------------------------------
# 修改 hostname
hostnamectl set-hostname your-new-host-name
# 查看修改结果
hostnamectl status
# 设置 hostname 解析
echo "127.0.0.1 $(hostname)" >> /etc/hosts
b.检查网络
[root@demo-master-a-1 ~]$ ip route show
default via 172.21.0.1 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.21.0.0/20 dev eth0 proto kernel scope link src 172.21.0.12
[root@demo-master-a-1 ~]$ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:12:a4:1b brd ff:ff:ff:ff:ff:ff
inet 172.17.216.80/20 brd 172.17.223.255 scope global dynamic eth0
valid_lft 305741654sec preferred_lft 305741654sec
c.安装docker及kubelet
# 在 master 节点和 worker 节点都要执行
# 最后一个参数 1.19.5 用于指定 kubenetes 版本,支持所有 1.19.x 版本的安装
# 腾讯云 docker hub 镜像
# export REGISTRY_MIRROR="https://mirror.ccs.tencentyun.com"
# DaoCloud 镜像
# export REGISTRY_MIRROR="http://f1361db2.m.daocloud.io"
# 华为云镜像
# export REGISTRY_MIRROR="https://05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.com"
# 阿里云 docker hub 镜像
export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
curl -sSL https://kuboard.cn/install-script/v1.19.x/install_kubelet.sh | sh -s 1.19.5
d.初始化 master 节点
a.操作
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点实际 IP(请使用内网 IP)
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP=192.168.2.131
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=10.100.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
curl -sSL https://kuboard.cn/install-script/v1.19.x/init_master.sh | sh -s 1.19.5
b.检查 master 初始化结果
# 只在 master 节点执行
# 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
watch kubectl get pod -n kube-system -o wide
# 查看 master 节点初始化结果
kubectl get nodes -o wide
e.初始化 worker节点
a.在 master 节点上执行
在 master 节点上执行
# 只在 master 节点执行
kubeadm token create --print-join-command
-------------------------------------------------------------------------------------------------
可获取kubeadm join 命令及参数,如下所示
# kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
b.针对所有的 worker 节点执行
# 只在 worker 节点执行
# 替换 x.x.x.x 为 master 节点的内网 IP
export MASTER_IP=192.168.2.131
# 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
export APISERVER_NAME=apiserver.demo
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
# 替换为 master 节点上 kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
c.检查初始化结果,在 master 节点上执行
# 只在 master 节点执行
kubectl get nodes -o wide
04.安装 Kuboard v3
a.安装
kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
# 您也可以使用下面的指令,唯一的区别是,该指令使用华为云的镜像仓库替代 docker hub 分发 Kuboard 所需要的镜像
# kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3-swr.yaml
b.等待 Kuboard v3 就绪
[root@node1 ~]# kubectl get pods -n kuboard
NAME READY STATUS RESTARTS AGE
kuboard-agent-2-65bc84c86c-r7tc4 1/1 Running 2 28s
kuboard-agent-78d594567-cgfp4 1/1 Running 2 28s
kuboard-etcd-fh9rp 1/1 Running 0 67s
kuboard-etcd-nrtkr 1/1 Running 0 67s
kuboard-etcd-ader3 1/1 Running 0 67s
kuboard-v3-645bdffbf6-sbdxb 1/1 Running 0 67s
c.访问 Kuboard
http://192.168.2.131:30080/
admin
Kuboard123
d.卸载
kubectl delete -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
rm -rf /usr/share/kuboard
7.2 podman
01.Podman介绍
a.OCI标准
podman是github的Containers项目的一部分,主要的5个组件如下:
Podman:Pod和容器镜像管理器 --代替docker
Buildah:容器镜像生成器 --代替dockerfile的脚本化执行
Skopeo:容器镜像检查管理器 --处理镜像相关的工作,如检查、复制、签名
Runc:容器运行器和特性构建器,并传递给Podman和Buildah
Crun:可选运行时,为Rootless容器提供更大的灵活性、控制和安全性
b.对比1
Podman Docker
架构 无守护进程,可以在启动容器的用户下运行容器 使用守护进程来创建镜像和运行容器
安全 允许容器使用Rootless特权 守护进程拥有Root权限
运行容器 需要另一个工具来管理服务并支持后台容器的运行 使用守护进程管理和运行容器
构建镜像 需要容器镜像生成器Buildah的辅助 可以自己构建容器镜像
理念 采用模块化的方法,依靠专门的工具来完成特定的任务 一个独立的、强大的工具
使用 兼容大部分Dockert命令,有专门的docker兼容插件 使用自己的命令
c.对比2
由于podman比docker少了一层daemon,因此重启的机制也就不同
podman相比docker也缺失了一些功能,比如不支持windows,不支持docker-compoese编排工具
-----------------------------------------------------------------------------------------------------
dockers在实现CRI的时候,它需要一个守护进程,其次需要以root运行,因此这也带来了安全隐患。
podman不需要守护程序,也不需要root用户运行,从逻辑架构上,比docker更加合理。
-----------------------------------------------------------------------------------------------------
在docker的运行体系中,需要多个daemon才能调用到OCI的实现RunC。
在容器管理的链路中,Docker Engine的实现就是dockerd daemon,它在linux中需要以root运行,
dockerd调用containerd,containerd调用containerd-shim,然后才能调用runC。
顾名思义shim起的作用也就是“垫片”,避免父进程退出影响容器的运行。
-----------------------------------------------------------------------------------------------------
podman直接调用OCI runtime(runC),通过common作为容器进程的管理工具,
但不需要dockerd这种以root身份运行的守护进程。
在podman体系中,有个称之为common的守护进程,其运行路径通常是/usr/libexec/podman/conmon,
它是各个容器进程的父进程,每个容器各有一个,common的父则通常是1号进程。
podman中的common其实相当于docker体系中的containerd-shim。
02.Podman设置
a.安装与卸载
a.Centos7
yum -y install podman --Centos7以上
systemctl start podman
b.Debian10
apt update
apt upgrade
apt-get -y install podman --Debian 11以上
podman --version
podman info
c.验证
podman version
podman info
d.卸载
apt-get remove podman
apt-get purge podman
apt-get autoremove
b.设置国内镜像仓库加速器
a.备份原配置文件
cp /etc/containers/registries.conf /etc/containers/registries.conf.bak
b.使用文本编辑器打开配置文件
vi /etc/containers/registries.conf
c.删除原有内容,重新编写文件内容后保存,下面xxxxxxxx是个人阿里云ID
unqualified-search-registries = ["docker.io"]
[[registry]]
prefix = "docker.io"
location = "xxxxxxxx.mirror.aliyuncs.com"
c.修改SELinux配置文件,永久关闭SELinux
a.打开/etc/selinux/config
vi /etc/selinux/config
b.将 “SELINUX” 参数设置为:”permissive” 或者 “disabled”
# enforcing - 表示启用 SELinux 安全策略。
# permissive - 表示启用 SELinux 安全策略,但不强制验证。如果执行第一步可以正常运行,则建议设置此值。
# disabled - 关闭 SELinux 安全策略,相当于没有安装 SELinux。
SELINUX=disabled
c.重启
reboot
d.以安装nginx为例
a.安装
podman run --rm -p 80:80 --name nginx nginx:alpine
b.由于Podman没有守护进程,所以自身无法实现开机自启功能
a.生成服务
podman generate systemd nginx > nginx.service
b.将服务移至启动目录
chmod +x nginx.service
mv nginx.service /usr/lib/systemd/system/
c.启动服务
systemctl daemon-reload
systemctl enable nginx.service
systemctl start nginx.service
systemctl status nginx.service
03.Podman命令
a.容器
podman run #创建并启动容器
podman start #启动容器
podman ps #查看容器
podman stop #终止容器
podman restart #重启容器
podman attach #进入容器
podman exec #进入容器
podman export #导出容器
podman import #导入容器快照
podman rm #删除容器
podman logs #查看日志
b.镜像
podman search #检索镜像
docke pull #获取镜像
podman images #列出镜像
podman image Is #列出镜像
podman rmi #删除镜像
podman image rm #删除镜像
podman save #导出镜像
podman load #导入镜像
podmanfile #定制镜像(三个)
podman build #构建镜像
podman run #运行镜像
podmanfile #常用指令(四个)
COPY #复制文件
ADD #高级复制
CMD #容器启动命令
ENV #环境变量
EXPOSE #暴露端口
7.3 常用操作1
00.对Kubernetes中的5个操作(Namespace操作、Pod操作、Deployment操作、Service操作、Ingress操作),按照它们的大小进行排序如下:
Ingress操作:Ingress是Kubernetes中用于配置应用程序的入口点的资源对象。它允许将外部流量路由到集群中的Service,并提供负载均衡、SSL终止等功能。相对于其他操作,Ingress的使用场景相对较少,因此在大小上排在最后。
Namespace操作:Namespace是用于在Kubernetes中隔离资源的一种机制,它可以将不同的资源划分到不同的逻辑组中,提供更好的资源管理和隔离。因为它是对整个集群的资源组织进行调整,所以在大小上属于较大的范畴。
Service操作:Service是用于暴露Pods或其他Service的网络端点的资源对象。它通过虚拟IP和负载均衡将流量引导到后端的Pod或Service。Service操作相对于Pod和Deployment来说,规模较小,但在网络通信和流量管理方面起着重要的作用。
Deployment操作:Deployment是Kubernetes中用于管理Pod副本的资源对象,它允许定义期望的副本数量,并负责维护这些副本的状态。Deployment的操作涉及到整个Pod副本的管理,因此在大小上较为重要。
Pod操作:Pod是Kubernetes中最基本的调度和部署单元,代表一个或多个容器的运行实例。虽然Pod是Kubernetes中最小的资源对象,但在部署和管理应用程序时起着核心作用。
请注意,这只是一种相对排序,每个操作在不同的场景下都可能具有不同的重要性和影响。实际上,这些操作通常是相互关联的,需要综合考虑来实现一个完整的Kubernetes应用程序部署和管理。
00.一些常用的操作
StatefulSet操作:StatefulSet是用于管理有状态应用程序的资源对象。与Deployment不同,StatefulSet保证Pod的唯一标识和稳定的网络标识,适用于有状态的应用程序,如数据库。
ConfigMap和Secret操作:ConfigMap和Secret分别用于存储配置数据和敏感信息,并可以在Pod中作为环境变量或卷挂载来使用。它们允许将配置信息从应用程序代码中分离出来,方便进行配置管理和安全管理。
PersistentVolume和PersistentVolumeClaim操作:PersistentVolume和PersistentVolumeClaim用于将持久化存储卷与Pod进行绑定。PersistentVolume是集群中的存储资源,而PersistentVolumeClaim是Pod对存储资源的请求。
DaemonSet操作:DaemonSet是用于在每个节点上运行一个Pod副本的资源对象,确保在集群中的每个节点上都运行了该Pod。适用于运行系统级别的服务或监控代理。
Job和CronJob操作:Job和CronJob用于运行一次性任务或定时任务。Job保证任务成功完成,而CronJob定期执行任务。
ReplicaSet操作:ReplicaSet与Deployment类似,也用于管理Pod副本的资源对象,但在Kubernetes的最新版本中,Deployment已经取代了大部分ReplicaSet的使用。
HorizontalPodAutoscaler操作:HorizontalPodAutoscaler可以自动调整Pod的副本数量,根据CPU利用率或其他自定义指标,确保应用程序的负载均衡和性能优化。
01.Namespace操作
a.常见命令1
kubectl create namespace <namespace-name> --创建一个Namespace
kubectl get namespaces --列出所有的Namespace
kubectl delete namespace <namespace-name> --删除一个Namespace
b.创建一个Namespace
a.文件
[root@bigdata04 ~]# vi namespace-test.yml
-------------------------------------------------------------------------------------------------
apiVersion: v1
kind: Namespace
metadata:
name: test
b.使用
[root@bigdata04 ~]# kubectl apply -f namespace-test.yml --创建一个Namespace
namespace/test created
c.查看
[root@bigdata04 ~]# kubectl get namespaces --列出所有的Namespace
NAME STATUS AGE
default Active 4h6m
kube-node-lease Active 4h6m
kube-public Active 4h6m
kube-system Active 4h6m
kuboard Active 3h55m
test Active 57s
02.Pod操作
a.常见命令1
kubectl create -f <pod-definition.yaml> --创建一个Pod
kubectl get pods -A --列出所有Pods
kubectl get pods -n <namespace-name> --获取特定Namespace的所有Pods
kubectl describe pod <pod-name> --查看Pod的详细信息
kubectl delete pod <pod-name> --删除一个Pod
b.常见命令2
kubectl get pod <pod-name> -o yaml > pod-definition.yaml --导出Pod配置
kubectl exec -it <pod-name> -- <command> --在Pod内执行命令
kubectl exec -it <pod-name> -- /bin/sh --进入Pod的交互式终端
kubectl logs <pod-name> --查看Pod日志
c.常见命令3
kubectl label pod <pod-name> <label-key>=<label-value> --添加/删除标签
kubectl label pod <pod-name> <label-key>-
d.常见命令4
kubectl scale deployment <deployment-name> --replicas=<replica-count> --扩展Pod副本数量
e.常见命令5
# 复制文件到Pod
kubectl cp <local-file> <namespace>/<pod-name>:<path-to-file-inside-pod>
# 从Pod复制文件到本地
kubectl cp <namespace>/<pod-name>:<path-to-file-inside-pod> <local-file>
f.常见命令6
kubectl get pods -o wide --获取Pod的IP地址
kubectl describe pod <pod-name> --获取Pod的事件
kubectl delete pod <pod-name> --临时重启Pod
kubectl get pods -w --观察Pod状态变化
kubectl get pods -l <label-key>=<label-value> --按标签选择Pod
kubectl get pod <pod-name> -o json | jq .metadata.ownerReferences --查找Pod的控制器
g.常用命令7
a.运行nginx
[root@bigdata04 ~]# kubectl run nginx --image=nginx:latest
[root@bigdata04 ~]# kubectl run nginx --image=daocloud.io/library/nginx:1.9.1 -n test
pod/nginx created
b.获取特定Namespace的所有Pods
[root@bigdata04 ~]# kubectl get pod -n default
[root@bigdata04 ~]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
nginx 0/1 ContainerCreating 0 24s
c.删除启动失败的镜像
[root@bigdata04 ~]# kubectl delete pod nginx -n test
pod "nginx" deleted
d.查看Pod的详细信息
[root@bigdata04 ~]# kubectl describe pod nginx
[root@bigdata04 ~]# kubectl describe pod nginx -n test
Name: nginx
Namespace: test
Priority: 0
Node: bigdata05/192.168.2.132
Start Time: Tue, 25 Jul 2023 06:51:16 +0800
Labels: run=nginx
Annotations: cni.projectcalico.org/podIP: 10.100.27.2/32
cni.projectcalico.org/podIPs: 10.100.27.2/32
Status: Running
IP: 10.100.27.2
IPs:
IP: 10.100.27.2
e.访问Pod中的nginx
[root@bigdata04 ~]# curl 10.100.27.2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
f.进入Pod中nginx
[root@bigdata04 ~]# kubectl exec -it nginx -n test -- bash
root@nginx:/# cd /etc/nginx
root@nginx:/etc/nginx# ls
conf.d koi-utf mime.types scgi_params win-utf
fastcgi_params koi-win nginx.conf uwsgi_params
g.查看Pod中Nginx的日志
[root@bigdata04 ~]# kubectl logs -f nginx -n test
10.100.243.128 - - [24/Jul/2023:23:01:19 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
h.常用命令8
a.创建一个Pod
[root@bigdata04 ~]# vi pod-nignx.yml
-------------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: nginx2
namespace: test
spec:
containers:
- image: daocloud.io/library/nginx:1.9.1
name: nginx2
b.使用
[root@bigdata04 ~]# kubectl apply -f pod-nignx.yml --创建一个Pod
namespace/test created
c.获取特定Namespace的所有Pods
[root@bigdata04 ~]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 26m
nginx2 1/1 Running 0 71s
g.常用命令9
a.Pod运行多容器
[root@bigdata04 ~]# vi pod-nginx-tomact.yml
-------------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: nginx-tomcat
namespace: test
spec:
containers:
- image: daocloud.io/library/nginx:1.9.1
name: nginx
- image: daocloud.io/library/tomcat:8.0.45
name: tomcat
b.使用
[root@bigdata04 ~]# kubectl apply -f pod-nginx-tomact.yml --创建一个Pod
pod/nginx-tomcat created
c.获取特定Namespace的所有Pods
[root@bigdata04 ~]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
nginx-tomcat 0/2 ContainerCreating 0 56s
d.查看Pod的详细信息
[root@bigdata04 ~]# kubectl describe pod nginx-tomcat -n test
Name: nginx-tomcat
Namespace: test
Priority: 0
Node: bigdata05/192.168.2.132
Start Time: Tue, 25 Jul 2023 07:27:51 +0800
Labels: <none>
Annotations: cni.projectcalico.org/podIP: 10.100.27.4/32
cni.projectcalico.org/podIPs: 10.100.27.4/32
Status: Running
IP: 10.100.27.4
IPs:
IP: 10.100.27.4
e.访问Pod中的nginx、tomcat
[root@bigdata04 ~]# curl 10.100.27.4:80
[root@bigdata04 ~]# curl 10.100.27.4:8080
03.Deployment操作
a.常见命令1
kubectl create -f <deployment-definition.yaml> --创建一个Deployment
kubectl get deployments --列出所有Deployments
kubectl get deployments -n <namespace-name> --获取特定Namespace的所有Deployments
kubectl describe deployment <deployment-name> --查看Deployment的详细信息
kubectl scale deployment <deployment-name> --replicas=<replica-count> --扩展或缩减Deployment的副本数量
kubectl delete deployment <deployment-name> --删除一个Deployment
b.常见命令2
a.创建
[root@bigdata04 ~]# kubectl create deployment deploy-nginx -n test --image=daocloud.io/library/nginx:1.9.1
deployment.apps/deploy-nginx created
b.查看
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
deploy-nginx-9b8d5cd59-nd6kp 1/1 Running 0 50s
nginx-tomcat 2/2 Running 0 19m
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
deploy-nginx 1/1 1 1 98s
c.删除
[root@bigdata04 ~]# kubectl delete pod nginx-tomcat -n test --删除pod
-----------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl delete deployment deploy-nginx -n test --删除deployments
deployment.apps "deploy-nginx" deleted
c.工作负载
a.文件
[root@bigdata04 ~]# vi deployment-nginx.yml
-------------------------------------------------------------------------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
b.使用
[root@bigdata04 ~]# kubectl apply -f deployment-nginx.yml --创建一个deployment
deployment.apps/nginx-deployment created
c.查看
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-jszqq 0/1 ContainerCreating 0 76s
nginx-deployment-66b6c48dd5-kkhkm 0/1 ContainerCreating 0 76s
nginx-deployment-66b6c48dd5-vksrx 1/1 Running 0 76s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 3 0 55s
04.Service操作1
a.常见命令1
kubectl create -f <service-definition.yaml> --创建一个Service
kubectl get services --列出所有Services
kubectl get services -n <namespace-name> --获取特定Namespace的所有Services
kubectl describe service <service-name> --查看Service的详细信息
kubectl delete service <service-name> --删除一个Service
b.实现2个Deployment暴露1个Service
a.port代表Service,target-port代表nginx
[root@bigdata04 ~]# kubectl expose deployment nginx-deployment -n test --port=8888 --target-port=80
b.查看
[root@bigdata04 ~]# kubectl get namespaces --查看namespace
NAME STATUS AGE
default Active 16h
kube-node-lease Active 16h
kube-public Active 16h
kube-system Active 16h
kuboard Active 16h
test Active 12h
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get service -n test --查看service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16h
nginx-deployment ClusterIP 10.96.47.113 <none> 80/TCP 90s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 3 0 55s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-jszqq 0/1 ContainerCreating 0 76s
nginx-deployment-66b6c48dd5-kkhkm 0/1 ContainerCreating 0 76s
nginx-deployment-66b6c48dd5-vksrx 1/1 Running 0 76s
c.负载均衡
[root@bigdata04 ~]# curl 10.96.47.113
c.实现2个Deployment暴露1个Service
a.port代表Service,target-port代表nginx,type=NodePort表示对外暴露端口
[root@bigdata04 ~]# kubectl expose deployment nginx-deployment -n test --port=8888 --target-port=80 --type=NodePort
b.查看
[root@bigdata04 ~]# kubectl get namespaces --查看namespace
NAME STATUS AGE
default Active 16h
kube-node-lease Active 16h
kube-public Active 16h
kube-system Active 16h
kuboard Active 16h
test Active 12h
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get service -n test --查看service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-deployment NodePort 10.96.67.193 <none> 8888:31188/TCP 24s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 3 0 55s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-jszqq 0/1 ContainerCreating 0 76s
nginx-deployment-66b6c48dd5-kkhkm 0/1 ContainerCreating 0 76s
nginx-deployment-66b6c48dd5-vksrx 1/1 Running 0 76s
c.访问
http://192.168.2.131:31118
-------------------------------------------------------------------------------------------------
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
Thank you for using nginx.
d.总结
a.示例
[root@bigdata04 ~]# kubectl get service -n test --查看service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16h
nginx-deployment NodePort 10.96.67.193 <none> 8888:31188/TCP 24s
b.分析
ClusterIP 代表 集群内部通信,对内暴露端口
NodePort 代表 集群外部通信,对外暴露端口
04.Service操作2
a.文件
[root@bigdata04 ~]# vi service-nginx.yml
-------------------------------------------------------------------------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx-deployment
spec:
selector:
app: nginx
ports:
- port: 8888
targetPort: 80
type: NodePort
b.使用
[root@bigdata04 ~]# kubectl apply -f service-nginx.yml --创建一个Service
deployment.apps/nginx-deployment created
c.查看
[root@bigdata04 ~]# kubectl get namespaces --查看namespace
NAME STATUS AGE
default Active 16h
kube-node-lease Active 16h
kube-public Active 16h
kube-system Active 16h
kuboard Active 16h
test Active 12h
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get service -n test --查看service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-deployment NodePort 10.96.38.189 <none> 8888:32151/TCP 3m18s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 3 0 55s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-t7wgl 1/1 Running 0 4m23s
nginx-deployment-66b6c48dd5-tggf8 1/1 Running 0 4m23s
nginx-deployment-66b6c48dd5-ztvlr 1/1 Running 0 4m23s
c.删除
kubectl delete pod nginx-deployment-66b6c48dd5-t7wgl -n test
kubectl delete deployment nginx-deployment -n test
kubectl delete services nginx-deployment -n test
05.Ingress操作
a.常见命令1
kubectl create -f <ingress-definition.yaml> --创建一个Ingress
kubectl get ingresses --列出所有Ingresses
kubectl get ingresses -n <namespace-name> --获取特定Namespace的所有Ingresses
kubectl describe ingress <ingress-name> --查看Ingress的详细信息
kubectl delete ingress <ingress-name> --删除一个Ingress
b.常用命令2
a.文件
[root@bigdata04 ~]# vi ingress-nginx.yml
-------------------------------------------------------------------------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx-deployment
spec:
selector:
app: nginx
ports:
- port: 8888
targetPort: 80
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: nginx-ingress
spec:
ingressClassName: ingress
rules:
- host: myslayers.nginx.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-deployment
port:
number: 8888
b.使用
[root@bigdata04 ~]# kubectl apply -f ingress-nginx.yml --创建一个ingress
deployment.apps/nginx-deployment created
c.查看
[root@bigdata04 ~]# kubectl get namespaces --查看namespace
NAME STATUS AGE
default Active 16h
kube-node-lease Active 16h
kube-public Active 16h
kube-system Active 16h
kuboard Active 16h
test Active 12h
-------------------------------------------------------------------------------------------------
[root@bigdata04 k8s]# kubectl get ingresses -n test --查看ingresses
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress ingress myslayers.nginx.com 192.168.2.132 80 107s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get service -n test --查看service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-deployment NodePort 10.96.38.189 <none> 8888:32151/TCP 25m
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 55s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-t7wgl 1/1 Running 0 4m23s
nginx-deployment-66b6c48dd5-tggf8 1/1 Running 0 4m23s
nginx-deployment-66b6c48dd5-ztvlr 1/1 Running 0 4m23s
7.4 常用操作2
01.namespace-test.yml
apiVersion: v1
kind: Namespace
metadata:
name: test
02.pod-nignx.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx2
namespace: test
spec:
containers:
- image: daocloud.io/library/nginx:1.9.1
name: nginx2
02.pod-nginx-tomact.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-tomcat
namespace: test
spec:
containers:
- image: daocloud.io/library/nginx:1.9.1
name: nginx
- image: daocloud.io/library/tomcat:8.0.45
name: tomcat
03.deployment-nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
04.service-nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx-deployment
spec:
selector:
app: nginx
ports:
- port: 8888
targetPort: 80
type: NodePort
05.ingress-nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: nginx-deployment
labels:
app: nginx-deployment
spec:
selector:
app: nginx
ports:
- port: 8888
targetPort: 80
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: nginx-ingress
spec:
ingressClassName: ingress
rules:
- host: myslayers.nginx.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-deployment
port:
number: 8888
7.5 k8s启动pipeline.yml
01.pipeline.yml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: mytest
labels:
app: mytest
spec:
replicas: 2
selector:
matchLabels:
app: mytest
template:
metadata:
labels:
app: mytest
spec:
containers:
- name: mytest
image: 192.168.2.129:8085/repo/mytest:v1.0.0
imagePullPolicy: Always
ports:
- containerPort: 8088
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: mytest
labels:
app: mytest
spec:
selector:
app: mytest
ports:
- port: 8088
targetPort: 8088
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: mytest
spec:
ingressClassName: ingress
rules:
- host: myslayers.mytest.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mytest
port:
number: 8088
02.使用
[root@bigdata04 k8s]# kubectl apply -f pipeline.yml
deployment.apps/mytest created
service/mytest created
ingress.networking.k8s.io/mytest created
03.配置harbor私服信息
a.Kuboard
名称空间(test) -> 配置中心 -> 密文 -> docker server http://192.168.2.129:8085/
-> docker username admin
-> docker password Harbor12345
b.配置
vi /etc/docker/daemon.json
{
"data-root":"/data/docker",
"registry-mirrors": ["https://almtd3fa.mirror.aliyuncs.com"],
"insecure-registries" : ["192.168.2.129:8085"]
}
-----------------------------------------------------------------------------------------------------
systemctl daemon-reload --重新加载daemon.json文件
systemctl restart docker.service --重启docker服务
docker info --验证
c.测试
docker login 192.168.2.129:8085/ -u admin -p Harbor12345
04.访问
a.查看
[root@bigdata04 ~]# kubectl get namespaces --查看namespace
NAME STATUS AGE
default Active 16h
kube-node-lease Active 16h
kube-public Active 16h
kube-system Active 16h
kuboard Active 16h
test Active 12h
-------------------------------------------------------------------------------------------------
[root@bigdata04 k8s]# kubectl get ingresses -n test --查看ingresses
NAME CLASS HOSTS ADDRESS PORTS AGE
mytest ingress myslayers.mytest.com 192.168.2.132 80 3m59s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get service -n test --查看service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mytest NodePort 10.96.187.37 <none> 8088:32150/TCP 6m47s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
mytest 0/2 2 0 7m3s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
mytest-5bc5884fbf-jhd4r 0/1 InvalidImageName 0 7m32s
mytest-5bc5884fbf-rvh2j 0/1 InvalidImageName 0 7m32s
b.访问
http://bigdata04:32150/test
http://bigdata05:32150/test
http://myslayers.mytest.com:32150/test
---------------------------------------------------------------------------------------------------------
[root@bigdata04 k8s]# curl 192.168.2.132:32150/test
Jenkin ----- v1.0.0
[root@bigdata04 k8s]# curl 192.168.2.131:32150/test
Jenkin ----- v1.0.0
[root@bigdata04 k8s]# curl myslayers.mytest.com:32150/test
Jenkin ----- v1.0.0
7.6 k8s整合到jenkins启动pipeline.yml
01.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
a.目标服务器
jenkins -> Dashboard -> 系统管理 -> 系统配置 -> SSH Servers -> SSH Server Name 192.168.2.131
-> Hostname 192.168.2.131
-> Username root
-> Use Password 123456
-> Remote Directory /data/mytest_docker/
b.流水线语法:将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
sshPublisher:Send build artifacts over SSH -> SSH Server Name:192.168.2.131
-> Transfer Set Source files:pipeline.yml
c.Jenkinsfile
将如下内容
// 方式一:deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
// stage('通过Publish Over SSH通知目标服务器') {
// steps {
// sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
// }
// }
替换为
// 方式二:
// 1.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
// 2.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
stage('将yml文仵传到k8s-master') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.131', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
02.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
a.将Jenkis(192.168.2.129)中的id_rsa.pub,发送给k8s-master(192.168.2.131)中的authorized_keys
a.SSH免密钥登陆
a.生成密钥
ssh-keygen -t rsa
b.发送私钥(本机)
ssh-copy-id localhost
c.发送公钥(其他计算机)
ssh-copy-id bigdata02
d.测试免密钥登陆
ssh bigdata02
b.Jenkis(192.168.2.129)
[root@bigdata02 ~]# docker exec -it jenkins bash
jenkins@d1ba4ac42552:/$ cd ~
jenkins@d1ba4ac42552:~$ cd .ssh
jenkins@d1ba4ac42552:~/.ssh$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDW0S54Ip2KSEjDc9Vh7PAXcBe4QOIn2m0XQ/pmaPrglNHSCtwIEWdMJrJPqxI5o7nEdL8LCTrCn8neat5u7c7lu2fmZamaEdW0su9tSKw1BDVGhjV5LfVb21W4psK1x21/DQgoZqSKxyKAYMImxzpqSNimUniOtpBst8+V9oAOJzMb7HI/M7Ei+v/1eLNPDQo3ovChvKR5kIbflQVjT96t1eO5tBsYlIDlFP9uh36++bdA5z3DL5URt88i87g1qHINuKXhxGwdsjMuIVCsqd6BWrAbEUczB2quaceiZ5xMo0gAcgQj+4kULzsFROUYqLzIq9DcwzKZv9G5jzg0j/Yl/8qtvG4EE5GXtC4Gy31KxMxtV1snFW5gyPONpPulVlwcBiVEvOjJAeFYd0HNkES4W0MPMgBAY/0kqzWF2PkmXN8IeXSIsA00PZW5kxE7JJM/j9rEcWakkuXg9x31MsERpo1xQ7zVUrl7j/GqGTSkXKCM98imGRPueC5/NIgxnz8= jenkins@d1ba4ac42552
c.k8s-master(192.168.2.131)
[root@bigdata04 .ssh]# touch authorized_keys
[root@bigdata04 .ssh]# vi authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDW0S54Ip2KSEjDc9Vh7PAXcBe4QOIn2m0XQ/pmaPrglNHSCtwIEWdMJrJPqxI5o7nEdL8LCTrCn8neat5u7c7lu2fmZamaEdW0su9tSKw1BDVGhjV5LfVb21W4psK1x21/DQgoZqSKxyKAYMImxzpqSNimUniOtpBst8+V9oAOJzMb7HI/M7Ei+v/1eLNPDQo3ovChvKR5kIbflQVjT96t1eO5tBsYlIDlFP9uh36++bdA5z3DL5URt88i87g1qHINuKXhxGwdsjMuIVCsqd6BWrAbEUczB2quaceiZ5xMo0gAcgQj+4kULzsFROUYqLzIq9DcwzKZv9G5jzg0j/Yl/8qtvG4EE5GXtC4Gy31KxMxtV1snFW5gyPONpPulVlwcBiVEvOjJAeFYd0HNkES4W0MPMgBAY/0kqzWF2PkmXN8IeXSIsA00PZW5kxE7JJM/j9rEcWakkuXg9x31MsERpo1xQ7zVUrl7j/GqGTSkXKCM98imGRPueC5/NIgxnz8= jenkins@d1ba4ac42552
[root@bigdata04 .ssh]#
b.流水线语法
sh:Shell Script -> Shell Script -> ssh [email protected] kubectl apply -f pipeline.yml
sh:Shell Script -> Shell Script -> ssh [email protected] kubectl rollout restart deployment mytest -n test
c.Jenkinsfile
将如下内容
// 方式一:deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
// stage('通过Publish Over SSH通知目标服务器') {
// steps {
// sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
// }
// }
替换为
// 方式二:
// 1.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
// 2.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
stage('将yml文仵传到k8s-master') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.131', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('远程执行k8s-master的kubectl命令') {
steps {
sh '''
ssh [email protected] kubectl apply -f /data/mytest_docker/pipeline.yml
ssh [email protected] kubectl rollout restart deployment mytest -n test
'''
}
}
03.完整的Jenkinsfile
// 所有的脚本命令都放在pipeline中
pipeline {
// 指定任务在哪个集群节点中执行
agent any
// 声明全局变量
environment {
harborUser = 'admin'
harborPasswd = 'Harbor12345'
harborAddress = '192.168.2.129:8085'
harborRepo = 'repo'
}
// 存放所有任务的合集
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.129:8929/troyekk/mytest.git']])
}
}
stage('通过maven构建项目') {
steps {
sh '/var/jenkins_home/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
}
}
stage('通过SonarQube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.login=75de8d2e51a1c86e2ec1c661c04164ee2cc2b9ba -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/'
}
}
stage('通过Docker制作自定义镜像') {
steps {
sh '''
cp ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/
'''
}
}
stage('通过自定义镜像推送到Harbor') {
steps {
sh '''
docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
'''
}
}
// 方式一:deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}
// stage('通过Publish Over SSH通知目标服务器') {
// steps {
// sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.129', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh ${harborAddress} ${harborRepo} ${JOB_NAME} ${tag} ${port}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
// }
// }
// 方式二:
// 1.将192.168.2.129中的pipeline.yml 传输到 192.168.2.131的/data/mytest_docker/ 目录中
// 2.使用无密码登录并操作,ssh [email protected] kubectl apply -f pipeline.yml
stage('将yml文仵传到k8s-master') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.2.131', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('远程执行k8s-master的kubectl命令') {
steps {
sh '''
ssh [email protected] kubectl apply -f /data/mytest_docker/pipeline.yml
ssh [email protected] kubectl rollout restart deployment mytest -n test
'''
}
}
}
04.完整的pipeline.yml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: mytest
labels:
app: mytest
spec:
replicas: 2
selector:
matchLabels:
app: mytest
template:
metadata:
labels:
app: mytest
spec:
containers:
- name: mytest
image: 192.168.2.129:8085/repo/mytest:v3.0.0
imagePullPolicy: Always
ports:
- containerPort: 8088
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: mytest
labels:
app: mytest
spec:
selector:
app: mytest
ports:
- port: 8088
targetPort: 8088
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: mytest
spec:
ingressClassName: ingress
rules:
- host: myslayers.mytest.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mytest
port:
number: 8088
05.访问
a.查看
[root@bigdata04 ~]# kubectl get namespaces --查看namespace
NAME STATUS AGE
default Active 16h
kube-node-lease Active 16h
kube-public Active 16h
kube-system Active 16h
kuboard Active 16h
test Active 12h
-------------------------------------------------------------------------------------------------
[root@bigdata04 k8s]# kubectl get ingresses -n test --查看ingresses
NAME CLASS HOSTS ADDRESS PORTS AGE
mytest ingress myslayers.mytest.com 192.168.2.132 80 3m59s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get service -n test --查看service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mytest NodePort 10.96.187.37 <none> 8088:32150/TCP 6m47s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get deployments -n test --查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
mytest 0/2 2 0 7m3s
-------------------------------------------------------------------------------------------------
[root@bigdata04 ~]# kubectl get pod -n test --查看pod
NAME READY STATUS RESTARTS AGE
mytest-5bc5884fbf-jhd4r 0/1 InvalidImageName 0 7m32s
mytest-5bc5884fbf-rvh2j 0/1 InvalidImageName 0 7m32s
b.访问
http://bigdata04:32150/test
http://bigdata05:32150/test
http://myslayers.mytest.com:32150/test
---------------------------------------------------------------------------------------------------------
[root@bigdata04 k8s]# curl 192.168.2.132:32150/test
Jenkin ----- v1.0.0
[root@bigdata04 k8s]# curl 192.168.2.131:32150/test
Jenkin ----- v1.0.0
[root@bigdata04 k8s]# curl myslayers.mytest.com:32150/test
Jenkin ----- v1.0.0