kubeadm快速部署K8S

news2024/11/24 20:59:26

目录

一、kubeadm安装K8S

1.1 环境准备

1.2 初始化配置

1.3 所有节点安装docker

1.3.1 安装依赖环境和docker

1.3.2 定义docker 配置文件

1.3.3 重启并开机自启docker

1.3.4 查看docker 是否配置成功

1.4 master、node01 、node02安装kubeadm,kubelet和kubectl 

1.5 部署K8S集群

1.5.1 查看初始化(一键安装)需要的镜像

1.5.2 master、node01、node02节点准备需要的镜像和启动脚本

1.5.3  生成Kubernetes集群初始化的默认配置文件

1.5.4 编辑ymal 文件

1.5.5 根据提示设定kubectl(准备家目录下.kube目录)

 1.5.6 master、node01、node02节点部署网络插件flannel

 1.5.7 检查集群状态

1.5.8 暴露端口提供服务

二、安装Harbor私有仓库 

2.1 Harbor节点配置

2.1.1 修改主机名

2.1.2 所有节点加上主机名映射

2.1.3 上传 harbor-offline-installer-v1.2.2.tgz 和 docker-compose 文件到 /opt 目录

2.1.4 移到指定目录添加执行权限

2.1.5 解压harbor

2.1.6 修改cfg文件内容

2.2 生成私钥

2.2.1 生成证书

2.2.2  备份私钥并清除私钥密码

2.2.3 签发一个有效期为1000天的X.509证书,并将生成的证书保存为server.crt

2.2.4 给所有的文件加执行权限

2.2.5 安装harbor

​2.2.6 检测harbor 仓库

 2.2.7 修改调度策略为NodePort

2.2.8 浏览器访问master01或node01或node02的ip+31090

2.2.9 将cluster-admin角色权限授予用户system:anonymous 

三、内核参数优化方案


一、kubeadm安装K8S

1.1 环境准备

节点名称IP地址相关组件
master192.168.133.19docker、kubeadm、kubelet、kubectl、flannel
node01192.168.133.20docker、kubeadm、kubelet、kubectl、flannel
node02192.168.133.21docker、kubeadm、kubelet、kubectl、flannel
harbor192.168.133.13docker、docker-compose、harbor-offline-v1.2.2

1.2 初始化配置

systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
swapoff -a						#交换分区必须要关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab		#永久关闭swap分区,&符号在sed命令中代表上次匹配的结果

//加载ip_vs 模块
for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done


//修改主机名
hostnamectl set-hostname master01
hostnamectl set-hostname node01
hostnamectl set-hostname node02


//所有节点修改hosts文件
vim /etc/hosts
192.168.133.19 master01
192.168.133.20 node01
192.168.133.21 node02


//调整内核参数
cat > /etc/sysctl.d/kubernetes.conf << EOF
#开启网桥模式,可将网桥的流量传递给iptables链
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
#关闭ipv6协议
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
EOF

//生效参数
sysctl --system 

1.3 所有节点安装docker

1.3.1 安装依赖环境和docker

yum install -y yum-utils device-mapper-persistent-data lvm2 
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
yum install -y docker-ce docker-ce-cli containerd.io

1.3.2 定义docker 配置文件

mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  }
}
EOF

#使用Systemd管理的Cgroup来进行资源控制与管理,因为相对Cgroupfs而言,Systemd限制CPU、内存等资源更加简单和成熟稳定。
#日志使用json-file格式类型存储,大小为100M,保存在/var/log/containers目录下,方便ELK等日志系统收集和管理日志。

1.3.3 重启并开机自启docker

systemctl daemon-reload
systemctl restart docker.service
systemctl enable docker.service 

1.3.4 查看docker 是否配置成功

docker info | grep "Cgroup Driver"


1.4 master、node01 、node02安装kubeadm,kubelet和kubectl 

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
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-1.20.11 kubeadm-1.20.11 kubectl-1.20.11
systemctl enable kubelet.service    # 开机自启kubelet

 #K8S通过kubeadm安装出来以后都是以Pod方式存在,即底层是以容器方式运行,所以kubelet必须设置开机自启

1.5 部署K8S集群

1.5.1 查看初始化(一键安装)需要的镜像

kubeadm config images list

1.5.2 master、node01、node02节点准备需要的镜像和启动脚本

for i in $(ls *.tar); do docker load -i $i; done

1.5.3  生成Kubernetes集群初始化的默认配置文件

kubeadm config print init-defaults > /opt/kubeadm-config.yaml

生成Kubernetes集群初始化的默认配置文件。这个命令的具体操作分解如下:

1、kubeadm config print init-defaults: 这部分命令调用了kubeadm工具中的config print init-defaults子命令。kubeadm是Kubernetes的一个命令行工具,用于快速、简单地初始化和管理Kubernetes集群。print init-defaults命令会输出一个默认的初始化配置模板,这个模板定义了使用kubeadm init命令启动一个新的Kubernetes控制平面所需的配置选项。配置包括API服务器的设置、网络插件的选择、证书和token的管理等。

2、**> 符号**: 在shell命令中,>`是一个重定向操作符,它指示将前面命令的输出内容写入(或覆盖)到后面指定的文件中,而不是打印到终端屏幕上。

3、/opt/kubeadm-config.yaml: 这是文件路径和名称,表示生成的默认配置将会被保存到/opt/目录下,文件名为kubeadm-config.yaml。/opt/目录通常用于存放可选的附加软件包,这里用来存储Kubernetes的初始化配置文件。

1.5.4 编辑ymal 文件

 vim kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.133.19
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master01
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.20.11
networking:
  dnsDomain: cluster.local
  podSubnet: "10.244.0.0/16"
  serviceSubnet: 10.96.0.0/16
scheduler: {}
 
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

1.5.5 执行ymal 文件

kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log

1、kubeadm init: 这是 kubeadm 命令中用于初始化一个新的 Kubernetes 控制平面的主要子命令。执行此命令会在当前机器上部署集群的控制面组件,如 API 服务器、控制器管理器、调度器等,并且会设置必要的网络和安全配置。

2、--config=kubeadm-config.yaml: 这个参数指定了一个自定义的配置文件路径。在此命令中,使用了之前通过 kubeadm config print init-defaults 生成并可能经过编辑的 kubeadm-config.yaml 文件。该文件包含了初始化过程中的各种配置选项,比如 Pod 网络、API 服务器广告地址、令牌以及证书配置等。

3、--upload-certs: 这是一个可选参数,指示 kubeadm init 在初始化过程中自动将生成的证书上传到 Kubernetes 密钥存储中(通常是通过集群内的 Secret 对象)。这简化了在多节点集群中分发这些证书的过程,使得加入额外的节点变得更容易。

4、| (管道符号): 管道符号用于将前一个命令的输出作为后一个命令的输入。

5、tee kubeadm-init.log: tee 命令用于读取标准输入(本例中是 kubeadm init 的输出)并同时将其写入到指定的文件(这里是 kubeadm-init.log)以及标准输出(即屏幕)。这意味着初始化过程的日志不仅会显示在终端上,还会被保存到 kubeadm-init.log 文件中,便于后续查看或故障排查。

综上,整个命令的作用是使用自定义配置文件 kubeadm-config.yaml 初始化 Kubernetes 集群,并自动上传证书到集群内,同时通过管道和 tee 命令记录整个初始化过程的日志到 kubeadm-init.log 文件中。这样既完成了集群的初始化配置,又方便记录和审查操作日志。

(1) 查看 kubeadm-init 日志

less kubeadm-init.log

(2)查看kubernetes配置文件目录

ls /etc/kubernetes/

(3)查看存放ca等证书和密码的目录

ls /etc/kubernetes/pki/

1.5.5 根据提示设定kubectl(准备家目录下.kube目录)

kubectl需经由API server认证及授权后方能执行相应的管理操作,kubeadm 部署的集群为其生成了一个具有管理员权限的认证配置文件 /etc/kubernetes/admin.conf,它可由 kubectl 通过默认的 “$HOME/.kube/config” 的路径进行加载。

在master01上操作

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
 
----------------------------------------------------
#这条命令序列是用来配置Kubernetes命令行工具(kubectl)的访问权限,以便用户能够在本地轻松地管理Kubernetes集群
vim /etc/kubernetes/manifests/kube-scheduler.yaml

 

vim /etc/kubernetes/manifests/kube-controller-manager.yaml

systemctl restart kubelet

 1.5.6 master、node01、node02节点部署网络插件flannel

(1)上传 flannel-cni-v1.2.0.tar   flannel-v0.22.2.tar 这两个镜像

(2)载入镜像

docker load -i flannel-v0.22.2.tar
docker load -i flannel-cni-v1.2.0.tar

(3)在master节点上传 kube-flannel.yml 文件

 

kubectl apply -f kube-flannel.yml 

(4)node节点让node 也加入集群,复制执行 kubeadm-config.yaml 得到的令牌(可以看 kubeadm-init.log )

 1.5.7 检查集群状态

kubectl get node

kubectl get pods -n kube-system

在Kubernetes环境中,使用kubectl get pods -n <namespace>命令可以查看指定命名空间(namespace)下的Pods状态。上述命令显示了kube-system命名空间中的Pods状态。下面是输出信息的解释:

        NAME: Pod的名称。每个条目代表一个运行中的Pod实例。

        READY: 表示Pod内所有容器的期望状态是否达到。例如,1/1意味着Pod中有一个容器,并且这个容器已经就绪(Running且健康检查通过)。如果有多个容器,会显示为N/M,其中N是已就绪的容器数,M是总容器数。

        STATUS: 描述Pod的当前状态。常见状态包括:

                Running: Pod内的容器正在运行并且至少有一个容器已经就绪。
                Pending: Pod正在被调度或者等待其依赖的服务(如镜像拉取)完成。
                Failed: Pod中的所有容器以非0退出码终止,且kubelet不会重启它们。
                Succeeded: 对于只运行到完成的Pod(比如Job),所有容器都成功执行结束。
                其他状态还包括CrashLoopBackOff(容器反复启动并失败)等。
        RESTARTS: 自Pod启动以来,容器被重启的次数。频繁的重启可能指示存在问题。

        AGE: Pod创建至今的时间长度。

kubectl get pod -n kube-flannel -owide

1.5.8 暴露端口提供服务

(1)测试 pod 资源创建

kubectl  create deployment nginx --image=nginx
kubectl get pods -owide

(2)查看所有的网络

1) 查看pod ip

kubectl get pods -owide

 2)查看service ip

kubectl get svc

 3)在内部可以访问 (网络互通的)

(3)暴露端口提供服务

kubectl expose deployment nginx --port=80 --type=NodePort

 1)浏览器访问 node ip:30660

 

(4)副本扩容

kubectl scale deployment nginx --replicas=3

(5)部署 Dashboard

1)上传软件包并载入镜像

docker load -i dashboard.tar

 2)修改yaml文件

vim recommended.yaml

3)启动ymal 文件

kubectl apply -f recommended.yaml

4)创建service account并绑定默认cluster-admin管理员集群角色 

kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

 

(5)使用输出的token登录Dashboard

 

二、安装Harbor私有仓库 

2.1 Harbor节点配置

2.1.1 修改主机名

hostnamectl set-hostname hub.shibin.com

2.1.2 所有节点加上主机名映射

echo '192.168.133.13 hub.shibin.com' >> /etc/hosts

2.1.3 上传 harbor-offline-installer-v1.2.2.tgz 和 docker-compose 文件到 /opt 目录

2.1.4 移到指定目录添加执行权限

cp docker-compose /usr/local/bin/
chmod +x /usr/local/bin/docker-compose

2.1.5 解压harbor

tar zxvf harbor-offline-installer-v1.2.2.tgz

2.1.6 修改cfg文件内容

vim harbor.cfg
5  hostname = hub.wyq.com
9  ui_url_protocol = https
24 ssl_cert = /data/cert/server.crt
25 ssl_cert_key = /data/cert/server.key
59 harbor_admin_password = Harbor12345

2.2 生成私钥

2.2.1 生成证书

mkdir -p /data/cert

cd /data/cert

openssl genrsa -des3 -out server.key 2048

openssl req -new -key server.key -out server.csr

 

2.2.2  备份私钥并清除私钥密码

cp server.key server.key.org

openssl rsa -in server.key.org -out server.key
#清除私钥密码主要是为了自动化部署和服务运行的便捷性

2.2.3 签发一个有效期为1000天的X.509证书,并将生成的证书保存为server.crt

openssl x509 -req -days 1000 -in server.csr -signkey server.key -out server.crt

2.2.4 给所有的文件加执行权限

chmod +x /data/cert/*

2.2.5 安装harbor

cd /opt/harbor/
./install.sh

 

解决方法: 

sudo yum remove -y docker-ce docker-ce-cli containerd.io
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y docker-ce-20.10.18 docker-ce-cli-20.10.18 containerd.io

解决方法

sudo yum remove -y docker-buildx-plugin
sudo yum install -y docker-ce-20.10.18 docker-ce-cli-20.10.18 containerd.io
sudo systemctl start docker
sudo systemctl enable docker
docker --version

./install.sh

2.2.6 本机映射

192.168.133.13 hub.shibin.com

在本地使用浏览器访问:https://hub.shibin.com
用户名:admin
密码:Harbor12345

 

 2.2.6 检测harbor 仓库

docker login -u admin -p Harbor12345 https://hub.shibin.com

解决方法

sudo nano /etc/docker/daemon.json

{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "insecure-registries": ["hub.shibin.com"]
}

sudo systemctl daemon-reload
sudo systemctl restart docker

docker login -u admin -p Harbor12345 https://hub.shibin.com

 

(1)上传镜像

 

 (2)在master节点上删除之前创建的nginx资源

kubectl delete deployment nginx

(3)创建3台nginx并暴露端口

kubectl create deployment nginx-deployment --image=hub.shibin.com/library/nginx:v1 --port=80 --replicas=3
 
kubectl expose deployment nginx-deployment --port=30000 --target-port=80

(4)查看LVS

yum install ipvsadm -y
ipvsadm -Ln

 (5)使用deployment的虚拟ip进行内部访问

 2.2.7 修改调度策略为NodePort

kubectl edit svc nginx-deployment
25   type: NodePort						#把调度策略改成NodePort

 

2.2.8 浏览器访问master01或node01或node02的ip+31090

 

2.2.9 将cluster-admin角色权限授予用户system:anonymous 

kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

三、内核参数优化方案

cat > /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0									#禁止使用 swap 空间,只有当系统内存不足(OOM)时才允许使用它
vm.overcommit_memory=1							#不检查物理内存是否够用
vm.panic_on_oom=0								#开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963							#指定最大文件句柄数
fs.nr_open=52706963								#仅4.4以上版本支持
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF

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

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

相关文章

CSS 实现个人资料卡

CSS 实现个人资料卡 效果展示 CSS 知识点 CSS 综合知识运用 页面整体布局 <div class"card"><div class"imgBox"><img src"./bg.jpg" /></div><div class"content"><div class"details&quo…

PCB设计简介

PCB电路板各层的含义 A. Signal And Plane Layers(S) 1. Signal Layers(信号层): 信号层主要用于布置电路板上的导线。Altium Designer提供了32个信号层&#xff0c;包括Top layer(顶层)&#xff0c;Bottom layer(底层)和32个内电层。 包括&#xff1a;Top layer(顶层),Bott…

PAT B1026. 程序运行时间

题目描述 要获得一个C语言程序的运行时间,常用的方法是调用头文件time.h,其中提供了clock(&#xff09;函数,可以捕捉从程序开始运行到clock()被调用时所耗费的时间。这个时间单位是clock tick,即“时钟打点”。同时还有一个常数CLK_TCK——给出了机器时钟每秒所走的时钟打点数…

Harbor镜像中心搭建

文章目录 Harbor镜像中心搭建前置条件下载Harbor创建CA证书配置Harbor开始启动地址映射访问配置本地登录配置外部虚拟机访问 Harbor镜像中心搭建 Harbor是一个镜像中心&#xff0c;我们所熟知的DockerHub就是一个镜像中心&#xff0c;我们可以把我们打包的镜像放在镜像中心中供…

Proteus 新建工程

Proteus 新建工程 新建简单工程 首先在File工具栏中点击New Project&#xff0c;弹出新建工程向导程序(New Proteus Wizard) 填写工程名称与存储路径&#xff0c;选择New Proteus并点击Next进行下一步设置 我们不需要生成PCB文件&#xff0c;一路默认&#xff0c;点击Next即…

基于springboot实现火锅店管理系统项目【项目源码+论文说明】

基于springboot实现火锅店管理系统演示 摘要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装火锅店管理系统软件来…

篮球杯小白+强者

2. 宣读数字【算法赛】 思维题&#xff0c;注意到完全平方数的约数是奇数个&#xff0c;其余都是偶数个。 #include <bits/stdc.h>using namespace std;#define LL long long#define pb push_back#define x first#define y second #define int long long #define endl \n…

[240615] X-CMD 发布 v0.3.11,增加对 elvish 的支持

目录 X-CMD 发布 v0.3.11&#xff0c;增加对 elvish 的支持&#xff0c;并优化对 nushell&#xff0c;fish&#xff0c;xonsh&#xff0c;tcsh 的支持✨ co 模块 - copilot✨ elv 模块✨ hub X-CMD 发布 v0.3.11&#xff0c;增加对 elvish 的支持&#xff0c;并优化对 nushell&…

2024抖音电影奇遇夜沪上落幕,短视频宣发助力电影佳作被看见

6月14日&#xff0c;由抖音、央视电影频道联合举办的2024抖音电影奇妙夜在上海落幕。该活动以“在电影里遇见”为主题&#xff0c;邀请40个电影剧组、120多位影人嘉宾、30位抖音创作者共话光影。张艺谋、陈思诚、刘伟强、黄渤、吴镇宇、马丽、邓超、任贤齐、张家辉、倪妮、刘昊…

2078.两栋颜色不同且距离最远的房子

街上有 n 栋房子整齐地排成一列&#xff0c;每栋房子都粉刷上了漂亮的颜色。给你一个下标从 0 开始且长度为 n 的整数数组 colors &#xff0c;其中 colors[i] 表示第 i 栋房子的颜色。 返回 两栋 颜色 不同 房子之间的 最大 距离。 第 i 栋房子和第 j 栋房子之间的距离是 a…

Keil5新建工程详细讲解

一. 新建文件夹并拷贝库文件 新建project文件夹后建立4个子文件夹&#xff1a;startup&#xff0c;device&#xff0c;drivers&#xff0c;main 二. 新建mdk工程 1. 打开MDK软件&#xff0c;再点击Project->New uVision Project…新建一个工程&#xff0c;在弹出的对话框内…

MySQL日常问题-行列互换

问题 行列互换 场景1 行转换列 1、表结构和数据 /*Navicat Premium Data TransferSource Server : 本地Source Server Type : MySQLSource Server Version : 80027Source Host : localhost:3306Source Schema : schoolTarget Server Type :…

Javaweb9 AOP+案例

AOP Aspect Oriented Programming面向切片编程【就是面向特定方法变成】 SpringAOP是Spring框架的高级技术&#xff0c;旨在管理bean对象的过程中&#xff0c;主要通过底层的**动态代理机制&#xff0c;**对特定的方法进行编程 1.导入AOP依赖 2.编写AOP程序 加上Component//类…

二分查找-java代码实现(easy)

目录 一、问题描述 二、代码实现 三、刷题链接 一、问题描述 二、代码实现 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** 如果目标值存在返回下标&#xff0c;否则返…

Digital电路仿真软件的安装

文章目录 1. Java环境的安装 2. Digital安装 3. 软件配置 1. Java环境的安装 电路仿真软件Digital是一款用于设计和仿真数字逻辑电路的工具。它可以帮助用户创建、测试和调试各种数字电路&#xff0c;提供可视化的电路编辑环境&#xff0c;使得设计过程更加直观和便捷。 D…

Apple - Cocoa Text Architecture Guide

翻译整理自&#xff1a;Cocoa Text Architecture Guide https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009459 文章目录 一、关于 Cocoa 文本系统1、概览大…

MyBatis 的多级缓存机制是怎么样运作的?

引言&#xff1a;上周三&#xff0c;小 X 去面试一家中厂&#xff0c;其中面试官问到 MyBatis 的多级缓存机制是怎么样运行的&#xff1f;这个问题可以好好准备一下&#xff0c;很多人可能只会用 MyBatisPlus&#xff0c;简单的多表联查 SQL 语句可能都写不出来&#xff0c;更别…

MySql 各种 join

MySql 定义了很多join的方式&#xff0c;接下来我们用一个例子来讲解。 用到的表 本文用到了两个表s1,s2&#xff1a; 内外连接 测试 1 1 1.select * from s1 inner join s2 on(s1.id s2.id);&#xff1a; -------- | id | id | -------- | 3 | 3 | | 4 | 4 | --------2…

sqlite3模块的使用

1. SQLite数据库 SQLite是一个轻量级的, 基于磁盘的, 关系型的数据库管理系统(RDBMS). 它不需要一个独立的服务器进程或操作系统级别的配置. SQLite是D.Richard Hipp在2000年创建的, 并且由于其小巧, 快速, 可靠和易于使用的特性, 它在全球范围内得到了广泛的应用.以下是 SQLi…

最长回文子串问题详解

最长回文子串的问题描述&#xff1a;给出一个字符串S&#xff0c;求S的最长回文子串的长度。 针对这个问题&#xff0c;先看暴力解法&#xff1a;枚举子串的两个端点i和j&#xff0c;判断在[i,j]区间内的子串是否回文。从复杂度上来看&#xff0c;枚举端点需要&#xff0c;判断…