K8S极简教程(4小时快速学会)
1. K8S 概览
1.1 K8S 是什么
K8S官网文档:https://kubernetes.io/zh/docs/home/
1.2 K8S核心特性
服务发现与负载均衡
:无需修改你的应用程序即可使用陌生的服务发现机制。存储编排
:自动挂载所选存储系统,包括本地存储。Secret和配置管理
:部署更新Secrets和应用程序的配置时不必重新构建容器镜像,且不必将软件堆栈配置中的秘密信息暴露出来。批量执行
:除了服务之外,Kubernetes还可以管理你的批处理和CI工作负载,在期望时替换掉失效的容器。水平扩缩
:使用一个简单的命令、一个UI或基于CPU使用情况自动对应用程序进行扩缩。自动化上线和回滚
:Kubernetes会分步骤地将针对应用或其配置的更改上线,同时监视应用程序运行状况以确保你不会同时终止所有实例。自动装箱
:根据资源需求和其他约束自动放置容器,同时避免影响可用性。自我修复
:重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器。
1.3 K8S 核心架构
我们已经知道了 K8S 的核心功能:自动化运维管理多个容器化程序。那么 K8S 怎么做到的呢?这里,我们从宏观架构上来学习 K8S 的设计思想。首先看下图:
K8S 是属于Master-Worker架构
,即有 Master 节点负责核心的调度、管理和运维,Worker 节点则
执行用户的程序。但是在 K8S 中,主节点一般被称为Master Node
,而从节点则被称为Worker Node
或者 Node。
注意
:Master Node 和 Worker Node 是分别安装了 K8S 的 Master 和 Woker 组件的实体服务器,
每个 Node 都对应了一台实体服务器(虽然 Master Node 可以和其中一个 Worker Node 安装在同
一台服务器,但是建议 Master Node 单独部署),所有 Master Node 和 Worker Node 组成了
K8S 集群,同一个集群可能存在多个 Master Node 和 Worker Node
。
首先来看Master Node都有哪些组件:
kube-apiserver
。K8S 的请求入口服务。API Server 负责接收 K8S 所有请求(来自 UI 界面或者CLI命令行工具),然后,API Server 根据用户的具体请求,去通知其他组件干活。Schedule
r。K8S 所有 Worker Node 的调度器。当用户要部署服务时,Scheduler 会选择最合适的 Worker Node(服务器)来部署。Controller Manager
。K8S 所有 Worker Node 的监控器。Controller Manager 有很多具体的
Controller,Node Controller、Service Controller、Volume Controller等。Controller 负责监控和调整在 Worker Node上部署的服务的状态,比如用户要求 A 服务部署 2个副本,那么当其中一个服务挂了的时候,Controller 会马上调整,让 Scheduler 再选择一个 Worker Node 重新部署服务。etcd。K8S 的存储服务
。etcd 存储了K8S 的关键配置和用户配置
,K8S 中仅 API Server
才具备读写权限,其他组件必须通过 API Server 的接口才能读写数据。
接着来看Worker Node的组件:
Kubelet。Worker Node 的监视器,以及与 Master Node 的通讯器
。Kubelet 是 Master Node
安插在 Worker Node 上的“眼线”,它会定期向 Master Node 汇报自己 Node上运行的服务的状态,并接受来自Master Node 的指示采取调整措施。负责控制所有容器的启动停止,保证节点工作正常。Kube-Proxy
。K8S 的网络代理。Kube-Proxy 负责 Node 在 K8S 的网络通讯、以及对外部网络流量的负载均衡。Container Runtime。Worker Node 的运行环境
。即安装了容器化所需的软件环境确保容器化程序能够跑起来,比如 Docker Engine运行环境
2、K8S安装教程
视频地址:图灵K8S
2.1. 安装要求
- 3台以上机器,操作系统 CentOS7.7以上64位系统
- 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
- 集群中所有机器之间网络互通
- 可以访问外网,需要拉取镜像
- 禁止swap分区
2.2. centos7兼容版本(7.7~7.9)
2.3. 三台主机
搭建k8s集群,三台主机,每台至少2G以上
主机 说明
主机 | 说明 |
---|---|
192.168.23.201 | k8s-master |
192.168.23.202 | k8s-node1 |
192.168.23.203 | k8s-node2 |
备注:本次装机选用k8s 1.19.16版本,dokcer1.18.09版本
主机安装参考链接,这里只参考第六集
黑马k8s第六集
2.4. 安装docker(三台主机都需要安装)
#卸载旧版本
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-enginesudo yum update -ysudo yum install -y yum-utils device-mapper-persistent-data lvm2#配置docker的yum地址
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo#安装指定docker版本
sudo yum -y install docker-ce-18.09.9 docker-ce-cli-18.09.9 containerd.io#启动dokcer并开机自启
sudo systemctl start docker
sudo systemctl enable docker#Docker配置修改
vim /etc/docker/daemon.json{"graph": "/data/docker","registry-mirrors": ["https://xv8xjvpp.mirror.aliyuncs.com","https://docker.m.daocloud.io/","https://dockerproxy.com/","https://mirror.baidubce.com/","https://docker.nju.edu.cn/","https://ccr.ccs.tencentyun.com/" ],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2"
}
#加载配置文件并重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
常见错误
如果yum update失败,需要进行更换镜像,下面以清华镜像为例, 三台机器都要操作
- 打开配置yum所在文件,CentOS-Base.repo
vi /etc/yum.repos.d/CentOS-Base.repo
- 将CentOS-Base.repo里的内容全部替换为以下内容
# CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/ http://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/ http://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/ http://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/ http://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/ http://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 # 使用failovermethod指定优先级,这里设置为随机(roundrobin),也可以改为priority并指定每个URL的优先级
failovermethod=roundrobin
- 清理YUM缓存并更新,更新完之后再安装Docker
yum clean all
yum makecache
yum update
2.5. 主机环境配置(三台都需要)
#1.关闭防火墙
sudo systemctl stop firewalld
sudo systemctl disable firewalld#2.关闭selinux
#selinux禁用
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config#2.关闭swap分区
swapoff -a
vim /etc/fstab # 注释到swap那一行 永久关闭#3.设置主机名
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2#4.添加host,IP需要改成你自己机器的IP
cat >> /etc/hosts << EOF
192.168.23.201 k8s-master
192.168.23.202 k8s-node1
192.168.23.203 k8s-node2
EOF#5.允许iptables 检查桥接流量
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.ipv4.tcp_tw_recycle = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system#6.设置时间同步
yum install -y ntpdate
ntpdate time.windows.com
2.6. 安装kubelet,kubeadm,kubectl(三台机器都需要执行)
#1.配置k8s的yum源
cat <<EOF | sudo tee /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#2.如果之前安装了k8s,先卸载旧版本
yum -y remove kubelet kubeadm kubectl#3.查看可以安装的版本#可以将 kubelet 替换为 kubeadm 或 kubectl,以查看相应组件的可用版本
yum list --showduplicates kubelet | sort -r #4,安装指定的kubelet,kubeadm,kubectl版本
sudo yum install -y kubelet-1.19.16 kubeadm-1.19.16 kubectl-1.19.16# 启动kubelet并卡机自启
sudo systemctl start kubelet
sudo systemctl enable kubelet#检查k8s是否启动
sudo systemctl status kubelet#排查错误
journalctl -xefu kubelet#master主机上执行
# 下载镜像。
# 此镜像 kubernetes 的仓库中,由于网络原因,无法连接,下面提供了一种替换方案。
images=(kube-apiserver:v1.19.16kube-controller-manager:v1.19.16kube-scheduler:v1.19.16kube-proxy:v1.19.16pause:3.2etcd:3.4.13-0coredns:1.7.0
)for imageName in ${images[@]};dodocker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageNamedocker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageNamedocker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
donekubeadm init \--apiserver-advertise-address=192.168.23.201 \--image-repository=registry.aliyuncs.com/google_containers \--kubernetes-version=v1.19.16 \--pod-network-cidr=192.168.0.0/16 \--service-cidr=10.96.0.0/12#master主机上执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf#手动拉取(三台机器都要)
docker pull docker.io/calico/cni:v3.20.6
docker pull docker.io/calico/kube-controllers:v3.20.6
docker pull docker.io/calico/node:v3.20.6#安装网络插件 Calico(仅master主机需要)
#下载calico.yaml
mkdir /root/k8s
cd /root/k8s
wget https://docs.projectcalico.org/v3.20/manifests/calico.yaml
kubectl apply -f calico.yaml#申请一个新令牌
kubeadm token create --print-join-command#加入node节
#复制新生成的令牌
kubeadm join 192.168.23.201:6443 --token xxxx --discovery-token-ca-cert-hash sha256:xxxxx
三个节点都是Ready
表示搭建成功
3. K8S基础命令
3.1 kubectl命令使用
使用kubectl 查看
Cluster Management Commands:certificate 修改 certificate 资源.cluster-info 显示集群信息top Display Resource (CPU/Memory/Storage) usage.cordon 标记 node 为 unschedulableuncordon 标记 node 为 schedulabledrain Drain node in preparation for maintenancetaint 更新一个或者多个 node 上的 taintsTroubleshooting and Debugging Commands:describe 显示一个指定 resource 或者 group 的 resources 详情logs 输出容器在 pod 中的日志attach Attach 到一个运行中的 containerexec 在一个 container 中执行一个命令port-forward Forward one or more local ports to a podproxy 运行一个 proxy 到 Kubernetes API servercp 复制 files 和 directories 到 containers 和从容器中复制 files 和 directories.auth Inspect authorizationAdvanced Commands:diff Diff live version against would-be applied versionapply 通过文件名或标准输入流(stdin)对资源进行配置patch 使用 strategic merge patch 更新一个资源的 field(s)replace 通过 filename 或者 stdin替换一个资源wait Experimental: Wait for a specific condition on one or many resources.convert 在不同的 API versions 转换配置文件kustomize Build a kustomization target from a directory or a remote url.Settings Commands:label 更新在这个资源上的 labelsannotate 更新一个资源的注解completion Output shell completion code for the specified shell (bash or zsh)Other Commands:alpha Commands for features in alphaapi-resources Print the supported API resources on the serverapi-versions Print the supported API versions on the server, in the form of "group/version"config 修改 kubeconfig 文件plugin Provides utilities for interacting with plugins.version 输出 client 和 server 的版本信息
3.2 Namespace
k8s中,命名空间(Namespace) 提供一种机制同一集群中的资源划分为相互隔离的组,同一命名空间内的资源名称要唯一,命名空间是用来隔离资源的,不隔离网路。
kubernetes启动时会创建四个初始命名空间:
-
default
kubernetes包含这个命名空间,以便你无需创建新的命名空间即可开始使用新集群 -
kube-node-lease
该命名空间包含用于各个节点关联的Lease(租约)对象。节点租约允许kubelet发送心跳,由此控制能够检测到节点故障。 -
kube-public
所有的客户端(包括未经身份验证的客户端)都可以读取该命名空间。该命名空间主要预留未集群使用,以便某些资源需要在整个集群中可见可读。该命名空间的公属性是一种约定而非要求。 -
kube-system
该命名空间使用kubernetes系统创建的对象。
#查看namespace
kubectl get namespace
#查看kube-system下的pod
kubectl get pods -n kube-system
#查看所有namespace下的pod
kubectl get pods -A
创建Namespace
- 命令行方式
kubectl create namespace XXXXX
- yaml方式
新建一个名为
my-namespace.yaml 的 YAML 文件,并写入下列内容:
#XXXXX.yaml
apiVersion: v1
kind: Namespace
metadata:name: my-namespace
然后运行:
kubectl create -f XXXXX.yaml
删除namespace
kubectl delete namespace XXXXX
kubectl delete -f XXXXX.yaml
3.3 Pod
创建Pod示例:运行一个NGINX容器
命令方式
#创建pod
kubectl run mynginx --image=nginx:1.14
#获取pod的信息,-owide 表示更详细的显示信息 -n 命名空间 查询对应namespace下的pod
kubectl get pod
kubectl get pod -owide
kubectl get pod -n <namespace-name>
#查看pod的详情
kubctl describe pod <pod-name>
#查看pod的运行日志
kubectl logs <pod-name>
#删除pod
kubectl delete pod <pod-name>
yaml方式
#nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:labels:run: mynginxname: mynginx
spec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80
部署成功访问nginx
3.4 Deployment
Deployment负责创建和更新应用程序的实例,使Pod拥有多副本,自愈,扩容等能力
。创建Deployment后,kubernetes master将应用程序实列调整到集群中的各个节点上。如果托管实列的节点关闭或被删除,Deployment控制器会将该实例替换为集群中另一个节点上的实例,这提供了一种自我修复机制来解决机器故障维护问腿。
创建一个Tomcat应用程序
使用 kubectl create deployment 命令可以创建一个应用部署deployment与pod
#my-tomcat表示pod的名称 --image表示镜像的地址 kubectl create deployment my-tomcat --image=tomcat:9.0.55#查看一下deployment的信息kubectl get deployment#删除deploymentkubectl delete deployment my-tomcat#查看Pod打印的日志kubectl logs my-tomcat-6d6b57c8c8-n5gm4#使用 exec 可以在Pod的容器中执行命令kubectl exec my-tomcat-6d6b57c8c8-n5gm4 -- env #使用 env 命令查看环境变量kubectl exec my-tomcat-6d6b57c8c8-n5gm4 -- ls / # 查看容器的根目录下面内容kubectl exec my-tomcat-6d6b57c8c8-n5gm4 -- sh #进入Pod容器内部并执行bash命令,如果想退出
容器可以使用exit命令
思考:下面两个命令有什么区别?
kubectl create my-tomcat --image=tomcat:9.0.55
kubectl create deployment my-tomcat --image=tomcat:9.0.55
自愈
现在我们来删除刚刚添加的pod,看看会发生什么
#查看pod信息,-w意思是一直等待观察pod信息的变动kubectl get pod -w
开另外一个命令窗口执行如下命令,同时观察之前命令窗口的变化情况
kubectl delete pod my-tomcat-6d6b57c8c8-n5gm4
我们可以看到之前那个tomcat的pod被销毁,但是又重新启动了一个新的tomcat pod,
这是k8s的服务自愈功能
,不需要运维人员干预
多副本
命令行的方式
# 创建3个副本kubectl create deployment my-tomcat --image=tomcat:9.0.55 --replicas=3
yaml方式
apiVersion: apps/v1
kind: Deployment
metadata:name: tomcat-deploymentlabels:app: tomcat-deployment
spec:replicas: 3 # 定义了 3 个副本selector:matchLabels:app: tomcat-deploymenttemplate:metadata:labels:app: tomcat-deploymentspec:containers:- name: tomcatimage: tomcat:9.0.55
扩缩容
# 扩容到5个podkubectl scale --replicas=5 deployment my-tomcat# 缩到3个podkubectl scale --replicas=3 deployment my-tomcat#修改 replicaskubectl edit deployment my-tomcat
滚动升级与回滚
对my-tomcat这个deployment进行滚动升级和回滚,将tomcat版本由tomcat:9.0.55升级到
tomcat:10.1.11,再回滚到tomcat:9.0.55
滚动升级:
kubectl set image deployment my-tomcat tomcat=tomcat:10.1.11 --record
可以执行 kubectl get pod -w 观察pod的变动情况,可以看到有的pod在销毁,有的pod在创建
查看pod信息
kubectl get pod
查看某个pod的详细信息,发现pod里的镜像版本已经升级了
kubectl describe pod my-tomcat-85c5c8f685-lnkfm
版本回滚:
查看历史版本
kubectl rollout history deploy my-tomcat
回滚到上一个版本
kubectl rollout undo deployment my-tomcat #--to-revision 参数可以指定回退的版本#回滚(回到指定版本)kubectl rollout undo deployment/my-dep --to-revision=2
查看pod详情,发现版本已经回退了
访问tomcat pod
集群内访问(在集群里任一worker节点都可以访问)
curl 192.168.36.74:8080
集群外部访问
当我们在集群之外访问是发现无法访问,那么集群之外的客户端如何才能访问呢?这就需要我们的
service服务了,下面我们就创建一个service,使外部客户端可以访问我们的pod
3.5 Service
创建service示例
命令行形式
kubectl expose deployment my-tomcat --port=8080 --type=NodePort
#查看service信息,port信息冒号后面的端口号就是对集群外暴露的访问接口
#NodePort范围在 30000-32767之间
kubectl get svc -owide
集群外部访问
使用集群节点的ip加上暴露的端口就可以访问
tomcat版本太高返回404的解决办法:进入tomcat容器,把 webapps 目录删除,再
把 webapps.dist 重命名为 webapps 即可。
yaml形式
apiVersion: v1
kind: Service
metadata:labels:app: my-tomcatname: my-tomcat # Service 的名称
spec:ports:- port: 8080 #service的虚拟ip对应的端口,在集群内网机器可以访问用service的虚拟ip加该端口号访问nodePort: 30001 #Service在宿主主机上映射的外网访问端口,端口范围必须在30000~32767protocol: TCPport: 80 # Service 暴露的端口targetPort: 8080 # 被暴露的 Pod 的容器端口,一般与pod内部容器暴露的端口一致selector:app: my-tomcattype: NodePort # Service 类型,可以是 ClusterIP、NodePort、LoadBalancer 等
3.6 存储
Volume
Volume指的是存储卷,包含可被Pod中容器访问的数据目录。容器中的文件在磁盘上是临时存放的,当容器崩溃时文件会丢失,同事无法在多个Pod中共享文件,通过使用存储卷可以解决这问题。
kubernetes 支持很多类型的卷。Pod可以同时使用任意数目的卷类型。临时卷类型的生命周期与Pod相同,但持久卷可以比Pod的存活期长。当Pod不再存在时,kubernetes 也会销毁临时卷;不过kubernetes 不会销毁永久卷。对于给定的Pod中任何类型的卷,在容器重启期间数据都不会丢失。
卷的核心就是一个目录,其中可能存有数据,Pod中的容器可以访问该目录中的数据。所采用的不同卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的东西。常见有confingMap、emptyDir、local、nfs、secret
等。
- ConfingMap:可以将配置文件以键值对的形式保存到ConfigMap中,并且可以在Pod中以文件或环境变量的形式使用。ConfigMap可以用来存储不敏感的配置信息,如应用程序的配置文件。
- EmptyDir:是一个空目录,可以在Pod用来存储临时数据,当Pod删除时,该目录也会删除。
- Local:将本地文件系统的目录或文件映射到Pod中的一个Volume中,可以用来在Pod中共享文件或数据。
- NFS:将网络上的一个或多个NFS共享目录挂载到Pod中的Volume中,可以用来在多个Pod之间共享数据。
- Secret:将敏感信息以密文的形式保存到Secret中,并且可以在Pod中以文件或环境变量的形式使用。Secret可以用来存储敏感信息,如用户的密码、证书等。
使用方式
使用卷时, 在 .spec.volumes 字段中设置为 Pod 提供的卷,并在 .spec.containers[*].volumeMounts
字段中声明卷在容器中的挂载位置。 容器中的进程看到的文件系统视图是由它们的容器镜像的初始内
容以及挂载在容器中的卷(如果定义了的话)所组成的。 其中根文件系统同容器镜像的内容相吻合。
任何在该文件系统下的写入操作,如果被允许的话,都会影响接下来容器中进程访问文件系统时所看
到的内容。
搭建nfs文件系统
nfs(network filesystem ): 网络文件存储系统
安装nfs-server
# 在每个机器。yum install -y nfs-utils
# 在master 执行以下命令echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports# 执行以下命令,启动 nfs 服务;创建共享目录mkdir -p /nfs/data # 在master执行10systemctl enable rpcbindsystemctl enable nfs-serversystemctl start rpcbindsystemctl start nfs-server# 使配置生效exportfs -r #检查配置是否生效exportfs
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-pv-demoname: nginx-pv-demo
spec:replicas: 2selector:matchLabels:app: nginx-pv-demotemplate:metadata:labels:app: nginx-pv-demospec:containers:- image: nginxname: nginxvolumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlnfs:server: 192.168.23.201path: /nfs/data/nginx-pv
测试通过,实现挂载
PV & PVC
基本使用
静态供应示例
创建PV池
#nfs主节点1
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03
创建PV
apiVersion: v1
kind: PersistentVolume
metadata:name: pv01-10m
spec:capacity:storage: 10MaccessModes:- ReadWriteManystorageClassName: nfsnfs:path: /nfs/data/01server: 192.168.23.201
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv02-1gi
spec:capacity:storage: 1GiaccessModes:- ReadWriteManystorageClassName: nfsnfs:path: /nfs/data/02server: 192.168.23.201
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv03-3gi
spec:capacity:storage: 3GiaccessModes:- ReadWriteManystorageClassName: nfsnfs:path: /nfs/data/03server: 192.168.23.201
创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nginx-pvc
spec:accessModes:- ReadWriteManyresources:requests:storage: 200MistorageClassName: nfs
自动分配1G的
创建Pod绑定PVC
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-deploy-pvcname: nginx-deploy-pvc
spec:replicas: 2selector:matchLabels:app: nginx-deploy-pvctemplate:metadata:labels:app: nginx-deploy-pvcspec:containers:- image: nginxname: nginxvolumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlpersistentVolumeClaim:claimName: nginx-pvc
动态供应
3.7 配置
ConfigMap
在 Kubernetes 中,ConfigMap 是一种用于存储非敏感信息的 Kubernetes 对象
。它用于存储配置
数据,如键值对、整个配置文件或 JSON 数据等。ConfigMap 通常用于容器镜像中的配置文件、命令
行参数和环境变量等。
ConfigMap 可以通过三种方式进行配置数据的注入:
环境变量注入
:将配置数据注入到 Pod 中的容器环境变量中。配置文件注入
:将配置数据注入到 Pod 中的容器文件系统中,容器可以读取这些文件。命令行参数注入
:将配置数据注入到容器的命令行参数中。
优点
- 避免了硬编码,将配置数据与应用代码分离。
- 便于维护和更新,可以单独修改 ConfigMap 而不需要重新构建镜像。
- 可以通过多种方式注入配置数据,更加灵活。
- 可以通过 Kubernetes 的自动化机制对 ConfigMap 进行版本控制和回滚。
- ConfigMap 可以被多个 Pod 共享,减少了配置数据的重复存储。
定义 ConfigMap
基本操作
# 查看 configmap$ kubectl get configmap/cm# 查看详细$ kubectl describe configmap/cm my-config# 删除 cm$ kubectl delete cm my-config
- 命令行创建:
可以使用kubectl create configmap命令来创建configmap,具体命令如下:
kubectl create configmap my-config --from-literal=key1=value1 --from
literal=key2=value2
通过配置文件创建:推荐
可以通过创建YAML文件的方式来定义configmap的内容。例如,创建一个名为
内容如下:
- 然后使用kubectl apply -f命令来创建configmap。
通过文件创建:
echo-n admin >./usernameecho -n 123456 > ./passwordkubectl create configmap myconfigmap --from-file=./username --from-file=./password
通过文件夹创建:
可以将多个配置文件放在同一个文件夹下,然后使用如:kubectl create configmap命令来创建configmap
kubectl create configmap my-config --from-file=config-files/
这将创建一个名为my-config的configmap,其中包含config-files/文件夹下所有的文件内容作为键值对。
通过环境变量创建:
可以将环境变量的值转换为configmap。例如,使用以下命令将当前环境变量的值转换为configmap:
kubectl create configmap my-config --from-env-file=<env>
使用示例
# docker安装redis
docker run -v /data/redis/redis.conf:/etc/redis/redis.conf \
-v /data/redis/data:/data \
-d --name myredis \
-p 6379:6379 \
redis:latest redis-server /etc/redis/redis.conf
创建ConfigMap
通过文件的方式创建
#创建redis.conf daemonize yes requirepass root # 创建配置,redis保存到k8s的etcdkubectl create cm redis-conf --from-file=redis.conf #查看资源清单kubectl get cm redis-conf -oyaml
通过yaml的方式创建
apiVersion: v1kind: ConfigMapmetadata: name: redis-conf data: redis.conf: | maxmemory-policy allkeys-lru requirepass root
创建Pod
apiVersion: v1
kind: Pod
metadata:name: redis
spec:containers:- name: redisimage: rediscommand:- redis-server- "/redis-master/redis.conf" #指的是redis容器内部的位置11# command: ["/bin/bash", "-ce", "tail -f /dev/null"]ports:- containerPort: 6379volumeMounts:- mountPath: /dataname: data- mountPath: /redis-mastername: configvolumes:- name: dataemptyDir: {}- name: configconfigMap:name: redis-confitems:- key: redis.confpath: redis.conf
测试
kubectl exec -it redis -- redis-cli 127.0.0.1:6379> config get maxmemory-policy
Secret
定义 Secret
- 使用命令行创建:
可以使用 kubectl create secret 命令来创建 secret,例如
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=admin123
- 使用 YAML 文件定义:
可以创建一个 YAML 文件来定义 Secret 对象,例如
apiVersion: v1
kind: Secret
metadata:name: my-secret
type: Opaque
data: username: YWRtaW4= # base64 编码后的用户名 admin password: MWYyZDFlMmU2N2Rm # base64 编码后的密码 1f2d1e2e67df
注意: 这个 YAML 文件定义了一个名为 my-secret 的 Secret 对象,其中包含了两个 base64 编码后的
key-value 对:username 和 password。
使用文件创建:
echo -n admin >./username
echo -n 123456 > ./password
kubectl create secret generic mysecret --from-file=./username --from-file=./password
- 通过环境变量创建:
可以将环境变量的值转换为secret。例如,使用以下命令将当前环境变量的值转换为secret:
kubectl create secret generic my-config --from-env-file=<env>
使用示例:从私有docker仓库拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/fox666/tulingmall-product:0.0.5
无法从私有镜像仓库拉取镜像,抛出如下错误:
解决方案:使用 docker 的用户信息来生成 secret:
##命令格式
kubectl create secret docker-registry myregistrykey \--docker-server=<你的镜像仓库服务器> \--docker-username=<你的用户名> \--docker-password=<你的密码> \--docker-email=<你的邮箱地址>kubectl create secret docker-registry myregistrykey --docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=fox666 --docker-password=xxx
在创建 Pod 的时候,通过imagePullSecrets来引用刚创建的myregistrykey
apiVersion: v1
kind: Pod
metadata:name: tulingmall-product
spec:containers:- name: tulingmall-productimage: registry.cn-hangzhou.aliyuncs.com/fox666/tulingmall-product:0.0.5imagePullSecrets: - name: myregistrykey
3.8 Ingress
Ingress 是一种kubernetes资源类型,它允许kubernetes 集群中暴露HTTP和HTTPS服务。通过Ingress,你可以将流量路由到不同的服务和端口点,而无需使用不同的负载均衡器。Ingress通常使用Ingress Contrller实现,它是一个运行在kubernetes 集群中的负载均衡器,它根据Ingress规则下面是一个将所有流量都发送到同一Service的简单Ingress示例:
Ingress和Service区别
Ingress和Service都是kubernetes中用于将流量路由到应用的机制,但他们是在路由层面上有所不同:
- Service是kubernetes中抽象的应用程序服务,它公开了一个单一的IP地址和端口,可以用于在kubernetes集群内部的Pod之间进行流量路由。
- Ingress是一个kubernetes资源对象,它提供了对集群外部路由的规则。Ingress通过一个公共IP地址和端口将流量路由到一个或多个Service。
安装Ingress
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
#修改镜像vi deploy.yaml#1、将image k8s.gcr.io/ingress-nginx/controller:v0.46.0@sha256:52f0058bed0a17ab0fb35628ba97e8d52b5d32299fbc03cc0f6c7b9ff036b61a的值改为如下值:registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0
2)安装ingress,执行如下命令
kubectl apply -f ingress-controller.yaml
- 查看是否安装成功
kubectl get pod,svc -n ingress-nginx -owide
使用Ingress
官网地址:
https://kubernetes.github.io/ingress-nginx/
配置ingress访问规则(就是类似配置nginx的代理转发配置),让ingress将域名tomcat.tuling.com
转发给后端的my-tomcat服务,新建一个文件ingress-tomcat.yaml,内容如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: name: web-ingress
spec:rules: - host: tomcat.tuling.com #转发域名http:paths: - pathType: Prefixpath: /backend:service:name: my-tomcatport:number: 8080 #service的端口
执行如下命令生效规则:
kubectl apply -f ingress-tomcat.yaml
查看生效的ingress规则:
kubectl get ing
在访问机器配置host,win10客户机在目录:C:\Windows\System32\drivers\etc,在host里增加如
下host(ingress部署的机器ip对应访问的域名)
192.168.65.82 tomcat.tuling.com
配置完后直接在客户机浏览器访问http://tomcat.tuling.com:30940能正常访问tomcat。
Service&Ingress总结
4. K8S核心原理
4.1 K8S的网络模型
K8S的网络中主要存在4种类型的通信:
- 同一Pod内的容器间通信
- 各个Pod彼此间的通信
- Pod和Service间的通信
集群外部流量和Service之间的通信
K8S为Pod和Service资源对象分别使用了各自的专有网络,Pod网络由K8S的网络插件配置实现,而
Service网络则由K8S集群进行指定。如下图:
K8S使用的网络插件需要为每个Pod配置至少一个特定的地址,即Pod IP。Pod IP地址实际存在于某个
网卡(可以是虚拟机设备)上。
而Service的地址却是一个虚拟IP地址,没有任何网络接口配置在此地址上,它由Kube-proxy借助
iptables规则或ipvs规则重定向到本地端口,再将其调度到后端的Pod对象。Service的IP地址是集群提
供服务的接口,也称为Cluster IP。
Pod网络和IP由K8S的网络插件负责配置和管理,具体使用的网络地址可以在管理配置网络插件时进行
指定,如10.244.0.0/16网络。而Cluster网络和IP是由K8S集群负责配置和管理,如10.96.0.0/12网
络。
从上图进行总结起来,一个K8S集群包含是三个网络。
节点网络
:各主机(Master、Node、ETCD等)自身所属的网络,地址配置在主机的网络接口,用于各主机之间的通信,又称为节点网络。Pod网络
:专用于Pod资源对象的网络,它是一个虚拟网络,用于为各Pod对象设定IP地址等网络参数,其地址配置在Pod中容器的网络接口上。Pod网络需要借助kubenet插件或CNI插件实现。Service网络
:专用于Service资源对象的网络,它也是一个虚拟网络,用于为K8S集群之中的Service配置IP地址,但是该地址不会配置在任何主机或容器的网络接口上,而是通过Node上的kube-proxy配置为iptables或ipvs规则,从而将发往该地址的所有流量调度到后端的各Pod对象之上。
4.2 K8S的工作流程
用K8S部署Nginx的过程中,K8S内部各组件是如何协同工作的:
我们在master节点执行一条命令要master部署一个nginx应用(kubectl create deployment nginx --image=nginx)
1. 这条命令首先发到master节点的网关api server,这是matser的唯一入口
2. api server将命令请求交给controller mannager进行控制
3. controller mannager 进行应用部署解析
4. controller mannager 会生成一次部署信息,并通过api server将信息存入etcd存储中
5. scheduler调度器通过api server从etcd存储中,拿到要部署的应用,开始调度看哪个节点有资源适合部署
6. scheduler把计算出来的调度信息通过api server再放到etcd中
7. 每一个node节点的监控组件kubelet,随时和master保持联系(给api-server发送请求不断获取最新数据),拿到master节点存储在etcd中的部署信息
8. 假设node2的kubelet拿到部署信息,显示他自己节点要部署某某应用
9. kubelet就自己run一个应用在当前机器上,并随时给master汇报当前应用的状态信息
10. node和master也是通过master的api-server组件联系的
11. 每一个机器上的kube-proxy能知道集群的所有网络,只要node访问别人或者别人访问node,
12. node上的kube
proxy网络代理自动计算进行流量转发
4.3 k8s架构原理六连问
K8S 是一个基于容器技术的分布式集群管理系统。既然是个分布式系统,那势必有多个 Node 节点(物理主机或虚拟机),它们共同组成一个分布式集群,并且这些节点中会有一个 Master 节点,由它来统一管理Node 节点。
如图所示:
问题一:主节点和工作节点是如何通信的呢?
首先,Master 节点启动时,会运行一个 kube-apiserver
进程,它提供了集群管理的 API 接口,是集群内各个功能模块之间数据交互和通信的中心枢纽,并且它也提供了完备的集群安全机制。
在 Node 节点上,使用 K8S 中的 kubelet
组件,在每个 Node 节点上都会运行一个 kubelet 进程,它负责向 Master 汇报自身节点的运行情况
,如 Node 节点的注册、终止、定时上报健康状况等,以及接收 Master发出的命令,创建相应 Pod。
在 K8S 中,Pod 是最基本的操作单元
,它与 docker 的容器有略微的不同,因为 Pod 可能包含一个或多个容器(可以是 docker 容器),这些内部的容器是共享网络资源
的,即可以通过 localhost 进行相互访问。关于 Pod 内是如何做到网络共享的,每个 Pod 启动,内部都会启动一个 pause 容器(google的一个镜像),它使用默认的网络模式,而其他容器的网络都设置给它,以此来完成网络的共享问题。
如图所示:
问题二:Master 是如何将 Pod 调度到指定的 Node 上的?
该工作由 kube-scheduler
来完成,整个调度过程通过执行一些列复杂的算法最终为每个 Pod 计算出一个最佳的目标 Node,该过程由 kube-scheduler 进程自动完成。常见的有轮询调度
(RR)。当然也有可能,我们需要将 Pod 调度到一个指定的 Node 上,我们可以通过节点的标签(Label)和 Pod 的 nodeSelector 属性的相互匹配,来达到指定的效果。
如图所示:
问题三:各节点、Pod 的信息都是统一维护在哪里的,由谁来维护?
从上面的 Pod 调度的角度看,我们得有一个存储中心
,用来存储各节点资源使用情况、健康状态、以及各Pod 的基本信息
等,这样 Pod 的调度来能正常进行。
在 K8S 中,采用 etcd 组件
作为一个高可用强一致性的存储仓库,该组件可以内置在 K8S 中,也可以外部搭建供 K8S 使用。
集群上的所有配置信息都存储在了 etcd
,为了考虑各个组件的相对独立,以及整体的维护性,对于这些存储数据的增、删、改、查,统一由 kube-apiserver 来进行调用,apiserver 也提供了 REST 的支持,不仅对各个内部组件提供服务外,还对集群外部用户暴露服务。
外部用户可以通过 REST 接口,或者 kubectl 命令行工具进行集群管理,其内在都是与 apiserver 进行通信。
如图所示:
问题四:外部用户如何访问集群内运行的 Pod ?
前面讲了外部用户如何管理 K8S,而我们更关心的是内部运行的 Pod 如何对外访问。使用过Docker 的同学应该知道,如果使用 bridge 模式,在容器创建时,都会分配一个虚拟 IP,该 IP 外部是没法访问到的,我们需要做一层端口映射
,将容器内端口与宿主机端口进行映射绑定
,这样外部通过访问宿主机的指定端口,就可以访问到内部容器端口了。
那么,K8S 的外部访问是否也是这样实现的?答案是否定的,K8S 中情况要复杂一些。因为上面讲
的 Docker 是单机模式下的,而且一个容器对外就暴露一个服务。在分布式集群下,一个服务往往由多个Application 提供,用来分担访问压力,而且这些 Application 可能会分布在多个节点上,这样又涉及到了跨主机的通信。
这里,K8S 引入了 Service 的概念,将多个相同的 Pod
包装成一个完整的 service
对外提供服务,至于获取到这些相同的 Pod,每个 Pod 启动时都会设置 labels 属性
,在 Service 中我们通过选择器 Selector,选择具有相同 Name 标签属性的 Pod
,作为整体服
务,并将服务信息通过 Apiserver 存入 etcd 中,该工作由Service Controller 来完成。同时,每个节点上会启动一个 kube-proxy 进程
,由它来负责服务地址到 Pod地址的代理
以及负载均衡
等工作。
如图所示:
问题五:Pod 如何动态扩容和缩放?
既然知道了服务是由 Pod 组成的,那么服务的扩容也就意味着 Pod 的扩容
。通俗点讲,就是在需要时将Pod 复制多份
,在不需要后,将 Pod 缩减至指定份数
。K8S 中通过 Replication Controller
来进行管理,为每个 Pod 设置一个期望的副本数,当实际副本数与期望不符时,就动态的进行数量调整
,以达到期望值。期望数值可以由我们手动更新,或自动扩容代理
来完成。
如图所示:
问题六:各个组件之间是如何相互协作的?
最后,讲一下 kube-controller-manager 这个进程的作用。我们知道了 ectd 是作为集群数据的存储中心
,apiserver 是管理数据中心
,作为其他进程与数据中心通信的桥梁。而 Service Controller、Replication Controller 这些统一交由 kube-controller-manager
来管理,kube-controller-manager 作为一个守护进程,每个 Controller 都是一个控制循环,通过 apiserver
监视集群的共享状态,并尝试将实际状态与期望不符的进行改变。关于 Controller,manager 中还包含了 Node 节点控制器(Node Controller)、资源配额管控制器(ResourceQuota Controller)、命名空间控制器(Namespace Controller)等。
如图所示:
相关文章:
K8S极简教程(4小时快速学会)
1. K8S 概览 1.1 K8S 是什么 K8S官网文档:https://kubernetes.io/zh/docs/home/ 1.2 K8S核心特性 服务发现与负载均衡:无需修改你的应用程序即可使用陌生的服务发现机制。存储编排:自动挂载所选存储系统,包括本地存储。Secret和…...
大数据学习之SCALA分布式语言三
7.集合类 111.可变set一 112.可变set二 113.不可变MAP集合一 114.不可变MAP集合二 115.不可变MAP集合三 116.可变map一 package com . itbaizhan . chapter07 //TODO 2. 使用 mutable.Map 前导入如下包 import scala . collection . mutable // 可变 Map 集合 object Ma…...
[免费]基于Python的Django博客系统【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的基于Python的Django博客系统,分享下哈。 项目视频演示 【免费】基于Python的Django博客系统 Python毕业设计_哔哩哔哩_bilibili 项目介绍 随着互联网技术的飞速发展,信息的传播与…...
ES设置证书和创建用户,kibana连接es
1、启动好es 2、进入es容器 docker exec -it es /bin/bash 3、生成ca证书 ./bin/elasticsearch-certutil ca 注:两个红方框位置直接回车 4、生成cert证书 ./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 注:前两个红框直接回车&am…...
“大模型横扫千军”背后的大数据挖掘--浅谈MapReduce
文章目录 O 背景知识1 数据挖掘2 邦费罗尼原则3 TF.IDF4 哈希函数5 分布式文件系统 一、MapReduce基本介绍1. Map 任务2. 按键分组3. Reduce 任务4. 节点失效处理5.小测验:在一个大型语料库上有100个map任务和若干reduce任务: 二、基于MapReduce的基本运…...
< OS 有关 > 阿里云 几个小时前 使用密钥替换 SSH 密码认证后, 发现主机正在被“攻击” 分析与应对
信息来源: 文件:/var/log/auth.log 因为在 sshd_config 配置文件中,已经定义 LogLevel INFO 部分内容: 2025-01-27T18:18:55.68272708:00 jpn sshd[15891]: Received disconnect from 45.194.37.171 port 58954:11: Bye Bye […...
【C++高并发服务器WebServer】-7:共享内存
本文目录 一、共享内存1.1 shmget函数1.2 shmat1.3 shmdt1.4 shmctl1.5 ftok1.6 共享内存和内存映射的关联1.7 小demo 二、共享内存操作命令 一、共享内存 共享内存允许两个或者多个进程共享物理内存的同一块区域(通常被称为段)。由于一个共享内存段会称…...
Python中容器类型的数据(下)
集合 集合 (set) 是一种可迭代的、无序的、不能包含重复元素的容器类型的数据。 Python中的集合是一种重要的数据结构,以下为你详细介绍: 定义与特点 无序性:集合中的元素没有固定顺序, {1, 2, 3} 和 {3, 2, 1} 在Python中是同一…...
JavaScript系列(45)--响应式编程实现详解
JavaScript响应式编程实现详解 🔄 今天,让我们深入探讨JavaScript的响应式编程实现。响应式编程是一种基于数据流和变化传播的编程范式,它使我们能够以声明式的方式处理异步数据流。 响应式编程基础概念 🌟 💡 小知识…...
uniapp版本升级
1.样式 登录进到首页,弹出更新提示框,且不可以关闭,侧边返回直接退出! 有关代码: <uv-popup ref"popupUpdate" round"8" :close-on-click-overlay"false"><view style"…...
K8s运维管理平台 - KubeSphere 3.x 和4.x 使用分析:功能较强,UI美观
目录标题 Lic使用感受优点:优化点: 实操首页项目 | 应用负载 | 配置 | 定制资源定义存储监控告警集群设置 **KubeSphere 3.x** 和 **4.x**1. **架构变化**:2. **多集群管理**:3. **增强的 DevOps 功能**:4. **监控与日…...
使用Python Dotenv库管理环境变量
使用Python Dotenv库管理环境变量 在开发Python应用程序时,管理配置信息(如API密钥、数据库连接字符串等)是一个常见的需求。为了确保安全性和灵活性,通常不建议将这些敏感信息硬编码在代码中。这时,dotenv库就派上了…...
HTTP 配置与应用(不同网段)
想做一个自己学习的有关的csdn账号,努力奋斗......会更新我计算机网络实验课程的所有内容,还有其他的学习知识^_^,为自己巩固一下所学知识,下次更新校园网设计。 我是一个萌新小白,有误地方请大家指正,谢谢…...
异或哈希总结
例题 例题1https://codeforces.com/problemset/problem/1175/Fhttps://codeforces.com/problemset/problem/1175/F 例题2https://codeforces.com/contest/2014/problem/Hhttps://codeforces.com/contest/2014/problem/H例题4https://codeforces.com/contest/1418/problem/Ght…...
我的2024年总结
趁着摸鱼赶紧写一下吧 去年目标review 还是将去年的目标完成了一些 【接纳不完美,多拍照片】 这个还是部分做到了,今年和一些朋友们见面时都注意拍照留记录了,不过还可以继续加强,因为外貌上发生了重大变化,下面细说…...
简易CPU设计入门:控制总线的剩余信号(二)
项目代码下载 请大家首先准备好本项目所用的源代码。如果已经下载了,那就不用重复下载了。如果还没有下载,那么,请大家点击下方链接,来了解下载本项目的CPU源代码的方法。 CSDN文章:下载本项目代码 上述链接为本项目…...
软件开发中的密码学(国密算法)
1.软件行业中的加解密 在软件行业中,加解密技术广泛应用于数据保护、通信安全、身份验证等多个领域。加密(Encryption)是将明文数据转换为密文的过程,而解密(Decryption)则是将密文恢复为明文的过程。以下…...
ArcGIS10.2 许可License点击始终启动无响应的解决办法及正常启动的前提
1、问题描述 在ArcGIS License Administrator中,手动点击“启动”无响应;且在计算机管理-服务中,无ArcGIS License 或者License的启动、停止、禁止等均为灰色,无法操作。 2、解决方法 ①通过cmd对service.txt进行手动服务的启动…...
rust feature h和 workspace相关知识 (十一)
feature 相关作用和描述 在 Rust 中,features(特性) 是一种控制可选功能和依赖的机制。它允许你在编译时根据不同的需求启用或禁用某些功能,优化构建,甚至改变代码的行为。Rust 的特性使得你可以轻松地为库提供不同的…...
动手学深度学习-卷积神经网络-3填充和步幅
目录 填充 步幅 小结 在上一节的例子(下图) 中,输入的高度和宽度都为3,卷积核的高度和宽度都为2,生成的输出表征的维数为22。 正如我们在 上一节中所概括的那样,假设输入形状为nhnw,卷积核形…...
最长递增——蓝桥杯
1.题目描述 在数列 a1,a2,⋯,an 中,如果ai<ai1<ai2<⋯<aj,则称 ai 至 aj 为一段递增序列,长度为 j−i1。 定一个数列,请问数列中最长的递增序列有多长。 输入描述 输入的第一行包含一个整数 n。…...
DeepSeek R1 对比 AlphaGo,Zero 的思考过程
作者:真中合欢 原文:https://zhuanlan.zhihu.com/p/19897045280 等了好久,终于等来R1的论文,我在当天晚上第一时间拜读。整篇论文的实验和理论给我一种简洁的优雅,和DeepSeek-V3那篇论文的感觉完全不同。读论文的过程中…...
【2025最新计算机毕业设计】基于SSM房屋租赁平台【提供源码+答辩PPT+文档+项目部署】(高质量源码,可定制,提供文档,免费部署到本地)
作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...
蓝桥杯练习日常|c/c++竞赛常用库函数(下)
书接上回......蓝桥杯算法日常|c\c常用竞赛函数总结备用-CSDN博客 目录 书接上回......https://blog.csdn.net/weixin_47011416/article/details/145290017 1、二分查找 2、lower_bound uper_bound 3、memset() 函数原型 参数说明 返回值 常见用…...
手撕Diffusion系列 - 第十一期 - lora微调 - 基于Stable Diffusion(代码)
手撕Diffusion系列 - 第十一期 - lora微调 - 基于Stable Diffusion(代码) 目录 手撕Diffusion系列 - 第十一期 - lora微调 - 基于Stable Diffusion(代码)Stable Diffusion 原理图Stable Diffusion的原理解释Stable Diffusion 和Di…...
技术总结:FPGA基于GTX+RIFFA架构实现多功能SDI视频转PCIE采集卡设计方案
目录 1、前言工程概述免责声明 3、详细设计方案设计框图SDI 输入设备Gv8601a 均衡器GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGBFDMA图像缓存RIFFA用户数据控制RIFFA架构详解Xilinx 7 Series Integrated Block for PCI ExpressRIFFA驱动及其安装QT上位机HDMI输出RGB转BT…...
【16届蓝桥杯寒假刷题营】第2期DAY5
2.最大公因数 - 蓝桥云课 问题描述 给你2个正整数N,M。 你需要构造一个有N个数的正整数序列a,满足以下条件: ∑i1NaiM。 求gcd(a),可能的最大值。 输入描述 输入一行两个正整数N,M,表示数组的长…...
26.项目集风险管理战略和项目集风险管理活动有何区别与联系?
项目集风险管理战略和项目集风险管理活动有何区别与联系? 项目集风险管理战略和项目集风险管理活动在项目集管理中的作用不同,但又是密切相关的。 区别: 1.定义 项目集风险管理战略:指的是制定一套全面的、系统的方针和方法,…...
PETSc源码分析: Time Integrators
本文结合PETSc源代码,总结PETSc中的ODE/DAE求解器。 注1:限于研究水平,分析难免不当,欢迎批评指正。 注2:文章内容会不定期更新。 参考文献 Balay S. PETSc/TAO Users Manual, Revision 3.22. Argonne National Labo…...
Spring Boot是什么及其优点
简介 Spring Boot是基于Spring框架开发的全新框架,其设计目的是简化Spring应用的初始化搭建和开发过程。 Spring Boot整合了许多框架和第三方库配置,几乎可以达到“开箱即用”。 优点 可快速构建独立的Spring应用。 直接嵌入Tomcat、Jetty和Underto…...
21.Word:小赵-毕业论文排版❗【39】
目录 题目 NO1.2 NO3.4 NO5.6 NO7.8.9 NO10.11.12 题目 NO1.2 自己的论文当中接收老师的修改:审阅→比较→源文档:考生文件夹:Word.docx→修订的文档:考生文件夹:教师修改→确定→接收→接收所有修订将合并之…...
LeetCode --- 433周赛
题目列表 3427. 变长子数组求和 3428. 最多 K 个元素的子序列的最值之和 3429. 粉刷房子 IV 3430. 最多 K 个元素的子数组的最值之和 一、变长子数组求和 题意要求我们能快速算出 n u m s [ s t a r t . . . i ] nums[start...i] nums[start...i] 这段区间和,其中…...
LLM幻觉(Hallucination)缓解技术综述与展望
LLMs 中的幻觉问题(LLM 幻觉:现象剖析、影响与应对策略)对其可靠性与实用性构成了严重威胁。幻觉现象表现为模型生成的内容与事实严重不符,在医疗、金融、法律等对准确性要求极高的关键领域,可能引发误导性后果&#x…...
Rocky9.5编译freeswitch【记录】
文件目录 tree -dL 1 . ├── flite-2.0.0 ├── freeswitch ├── ldns-1.8.4 ├── libcodec2-2.59 ├── libks ├── ooh323-0.1 ├── opus ├── signalwire-client-c ├── sofia-sip ├── spandsp ├── v8-6.1.298 └── zeromq-2.1.9操作记录 ip a nm…...
自定义数据集 使用tensorflow框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测
在 TensorFlow 中实现逻辑回归、保存模型并加载模型进行预测的过程可以分为以下几个步骤: 准备数据:创建或加载你的自定义数据集。构建逻辑回归模型。训练模型。保存模型。加载模型。使用加载的模型进行预测。 import tensorflow as tf import numpy as…...
WPF进阶 | WPF 数据绑定进阶:绑定模式、转换器与验证
WPF进阶 | WPF 数据绑定进阶:绑定模式、转换器与验证 一、前言二、WPF 数据绑定基础回顾2.1 数据绑定的基本概念2.2 数据绑定的基本语法 三、绑定模式3.1 单向绑定(One - Way Binding)3.2 双向绑定(Two - Way Binding)…...
八股——Java基础(四)
目录 一、泛型 1. Java中的泛型是什么 ? 2. 使用泛型的好处是什么? 3. Java泛型的原理是什么 ? 什么是类型擦除 ? 4.什么是泛型中的限定通配符和非限定通配符 ? 5. List和List 之间有什么区别 ? 6. 可以把List传递给一个接受List参数的方法吗? 7. Arra…...
2025蓝桥杯JAVA编程题练习Day1
1.刑侦科推理试题 题目描述 有以下10道单选题,编程求这10道题的答案。 这道题的答案是: A. A B. B C. C D. D 第5题的答案是: A. C B. D C. A D. B 以下选项中哪一题的答案与其他三项不同: A. 第3题 B. 第6题 C. 第2题 D.…...
数据结构与算法-要点整理
知识导图: 一、数据结构 包含:线性表(数组、队列、链表、栈)、散列表、树(二叉树、多路查找树)、图 1.线性表 数据之间就是“一对一“的逻辑关系。 线性表存储数据的实现方案有两种,分别是顺序存储结构和链式存储结构。 包含:数组、队列、链表、栈。 1.1 数组…...
SaaS底层盈利逻辑剖析:运维费与服务费的战略抉择
一、引言 1.1 研究背景与意义 在数字化浪潮的推动下,SaaS(软件即服务)行业近年来取得了迅猛发展,成为软件产业中不可或缺的一部分。SaaS 通过互联网提供软件服务,企业无需进行复杂的本地软件安装和硬件购置ÿ…...
Python爬虫之——Cookie存储器
目录 专栏导读1、背景介绍2、库的安装3、核心代码4、完整代码总结 专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 &…...
【数据结构】(2)时间、空间复杂度
一、衡量算法好坏的指标 时间复杂度衡量算法的运行速度,空间复杂度衡量算法所需的额外空间。这些指标,是某场景中选择使用哪种数据结构和算法的依据。如今,计算机的存储器已经变得容易获得,所以不再太关注空间复杂度。 二、渐进表…...
理解 IS-IS 中重要概念之间的关系
本文为 “IS-IS 中重要概念” 相关文章合辑。 未整理去重。 理解 IS-IS、CLNS、CMNS、NSAP、NET 等概念之间的关系 1. 核心概念 IS-IS (Intermediate System to Intermediate System) 一种链路状态路由协议,基于 SPF(最短路径优先)算法计…...
AI 模型评估与质量控制:生成内容的评估与问题防护
在生成式 AI 应用中,模型生成的内容质量直接影响用户体验。然而,生成式模型存在一定风险,如幻觉(Hallucination)问题——生成不准确或完全虚构的内容。因此,在构建生成式 AI 应用时,模型评估与质…...
Mybatis-plus缓存
mybatis-plus缓存 MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上提供了更多的便利性和强大的功能,包括但不限于分页、条件构造器、通用 Mapper、代码生成器等。MyBatis-Plus 也内置了基础的缓存功能,但需要注意的是ÿ…...
unity学习20:time相关基础 Time.time 和 Time.deltaTime
目录 1 unity里的几种基本时间 1.1 time 相关测试脚本 1.2 游戏开始到现在所用的时间 Time.time 1.3 时间缩放值 Time.timeScale 1.4 固定时间间隔 Time.fixedDeltaTime 1.5 两次响应时间之间的间隔:Time.deltaTime 1.6 对应测试代码 1.7 需要关注的2个基本…...
系统思考—转型
“我知道自己有问题,但问题到底出在哪里?” 很多中小企业主都会在这样的迷茫中徘徊。市场变化太快、团队执行力不强、内部沟通不畅……这些问题似乎无处不在。但其实,真正让企业陷入困境的,并不是问题本身,而是——看…...
Java面试题2025-设计模式
1.说一下开发中需要遵守的设计原则? 设计模式中主要有六大设计原则,简称为SOLID ,是由于各个原则的首字母简称合并的来(两个L算一个,solid 稳定的),六大设计原则分别如下: 1、单一职责原则 单一职责原则的定义描述非…...
本地Harbor仓库搭建流程
Harbor仓库搭建流程 本文主要介绍如何搭建harbor仓库,推送本地镜像供其他机器拉取构建服务 harbor文档:Harbor 文档 | 配置 Harbor YML 文件 - Harbor 中文 github下载离线安装包 Releases goharbor/harbor 这是harbor的GitHub下载地址,…...
爬虫基础之爬取某基金网站+数据分析
声明: 本案例仅供学习参考使用,任何不法的活动均与本作者无关 网站:天天基金网(1234567.com.cn) --首批独立基金销售机构-- 东方财富网旗下基金平台! 本案例所需要的模块: 1.requests 2.re(内置) 3.pandas 4.pyecharts 其他均需要 pip install 模块名 爬取步骤: …...