初识k8s(概述、原理、安装)

文章目录

  • 概述
    • 由来
    • 主要功能
  • K8S架构
    • 架构图
    • 组件说明
      • Cluster
      • Master
      • Node
      • kubectl
    • 组件处理流程
  • K8S概念组成
    • Pod
    • Pod控制器
      • ReplicationController(副本控制器)
      • ReplicaSet (副本集)
      • Deployment
      • StatefulSet (有状态副本集)
      • DaemonSet
      • Job
      • Cronjob
    • Service
      • ClusterIP
      • NodePort
      • LoadBalancer
      • ExternalName
    • Endpoint
    • 网络
    • Ingress Controller
  • K8S安装
    • 安装方式选择
      • Minikube
      • Kubeadmin
      • 二进制包
    • K8S集群准备
      • 环境准备(一个Master两个Node)
      • 初始化环境(三台)
      • 安装docker(三台)
    • 安装K8S集群
      • 安装kubeadm, kubelet and kubectl(三台)
      • 配置kubeadm(master)
      • 下载镜像(三台)
      • 初始化master
      • 加入node
      • 安装网络插件
      • 测试常用命令
    • K8s资源清单
      • 什么是资源
      • 资源分类
      • 资源清单
    • 工作负载型资源(workload)
      • Pod
      • Pod控制器Replicaset
      • Pod控制器Deployment
  • 参考博客

本篇内容属于资料整理,非笔者操作笔记,用于学习记录,其中有问题的地方请指出。

概述

由来

kubernetes,简称K8s,是用8代替8个字符“kubernete”而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,即我们常说的容器编排工具,K8S的目标是让部署容器化的应用简单并且高效

k8s是谷歌开源的容器编排工具,其实也是管理应用的全生命周期的一个工具,Kubernetes在Docker技术之上,为容器化的应用提供了资源调度、部署运行、服务发现和扩容缩容等丰富多样的功能,从创建应用,应用部署,应用提供服务,扩容缩容,应用更新,都非常的方便,而且可以做到故障自愈,例如一个服务器挂了,可以自动将这个服务器上的服务调度到另外一个主机上进行运行,无需进行人工干涉。如果你曾经用过Docker部署容器,那么可以将Docker看成Kubernetes底层使用的组件,Kubernetes是Docker的上层封装,通过它可以很方便的进行Docker集群的管理。

主要功能

基于容器的应用部署、维护和滚动升级

  • 自我修复
  • 负载均衡和服务发现
  • 跨机器和跨地区的集群调度
  • 自动伸缩、水平扩展
  • 无状态服务和有状态服务
  • 广泛的Volume存储卷的支持
  • 插件机制保证扩展性

K8S架构

架构图

在这里插入图片描述

组件说明

Cluster

Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用.
Kubernetes Cluster由Master和Node组成,节点上运行着若干Kubernetes服务。

Master

  1. API server
    提供了k8s各类资源对象(pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个系统 的数据总线和数据中心。
  2. Controlle Manager (kube-controller-manager):
    kubernets 里面所有资源对象的自动化控制中心,可以理解为资源对象的大总管;保证集群中各种资 源的状态和用户定义(yaml)的状态一致, 如果出现偏差, 则修正资源的状态(维护容器的数量始终和 定义的一样)。
  3. Scheduler (kube-scheduler):
    负责资源调度(pod调度)的进程,调度器的职责主要是通过调度算 法为新创建的pod在集群中寻找最合适的node,并将pod调度到Node上。
  4. Controlle Manager (kube-controller-manager)
    kubernets 里面所有资源对象的自动化控制中心,可以理解为资源对象的大总管;保证集群中各种资源的状态和用户定义(yaml)的状态一致, 如果出现偏差, 则修正资源的状态(维护容器的数量始终和定义的一样)。
  5. Scheduler (kube-scheduler)
    负责资源调度(pod调度)的进程,调度器的职责主要是通过调度算 法为新创建的pod在集群中寻找最合适的node,并将pod调度到Node上。
  6. Etcd
    Etcd(分布式键值存储)是Kubernetes集群中的一个关键组件。用于持久化存储集群中所有的资源对象,如Node、Service、Pod、RC、Namespace等;API Server提供了操作etcd的封装接口API,这些API基本上都是集群中资源对象的增删改查及监听资源变化的接口。
    Etcd是由CoreOS开发的一种高可用性、一致性和分布式的键值存储系统,它作为Kubernetes的后端数据库,负责存储集群状态信息、配置数据和访问控制列表等。Etcd使用Raft一致性算法1来保证数据的一致性和可靠性,并提供了简单的API接口供其他组件进行读写操作。
    Etcd在Kubernetes中扮演着存储和共享集群配置、元数据和状态信息的角色,为集群的正常运行提供支持。

Node

  1. Kubelet
    负责pod对应的容器创建、启停等任务,同时与master 节点密切协作,处理 Master 节点下发到本 节点的任务,按照 PodSpec 描述来管理Pod 和其中的容器,实现集群管理的基本功能。

  2. kube-proxy
    实现Kubernetes Service的服务发现与负载均衡机制的重要组件,比如要通过外网访问k8s就需要该组 件进行代理,容器与容器之间负载均衡也需要kube-proxy。

  3. Docker Engine
    Docker引擎,负责本机的容器创建和管理工作。

kubectl

kubectl是Kubernetes的命令行工具,用于与Kubernetes集群进行交互和管理。它允许用户通过命令行界面执行各种操作,如创建、删除、更新和查看Kubernetes资源对象(如Pods、Services、Deployments等)。

使用kubectl命令来管理Kubernetes集群,例如:

  • 创建和启动应用程序的Pods、Deployments和Services;
  • 扩展和缩小应用程序的副本数量;
  • 查看和监视集群中的资源状态;
  • 更新和回滚应用程序的配置;
  • 调试和故障排除集群中的问题;
  • 管理命名空间、访问控制和安全策略等。

kubectl提供了丰富的命令选项和参数,可用于满足各种需求。通过与Kubernetes API进行通信,kubectl使得与Kubernetes集群交互变得方便和直观。

组件处理流程

  1. 通过Kubectl提交一个创建RC的请求,该请求通过API Server被写入etcd中;(存储请求)
  2. 此时Controller Manager通过API Server的监听资源变化的接口监听到这个RC事件,分析之后,发现当前集群中还没有它所对应的Pod实例,于是根据RC里的Pod模板定义生成一个Pod对象,通过API Server写入etcd;(创建pod)
  3. 接下来,此事件被Scheduler发现,它立即执行一个复杂的调度流程,为这个新Pod选定一个落户的Node,然后通过API Server将这一结果写入到etcd中;(Pod分配Node)
  4. 随后,目标Node上运行的Kubelet进程通过API Server监测到这个“新生的”Pod,并按照它的定义,启动该Pod并任劳任怨地负责它的下半生,直到Pod的生命结束。(接管Pod)
  5. 接着,通过Kubectl提交一个新的映射到该Pod的Service的创建请求;
  6. Controller Manager会通过Label标签查询到相关联的Pod实例,然后生成Service的Endpoints信息(可被访问的服务端点,即一个状态为running的pod),并通过API Server写入到etcd中;
  7. 接下来,所有Node上运行的Proxy进程通过API Server查询并监听Service对象与其对应的Endpoints信息,建立一个软件方式的负载均衡器来实现Service访问到后端Pod的流量转发功能。

K8S概念组成

Pod

Pod是K8S中可以创建的最小部署单元,一个Pod代表集群上正在运行的一个进程。Pod代表部署的一个单位,K8S中单个应用的实例,它可能由单个容器或多个容器共享组成。

Pod中的容器共享两种资源:网络和存储。

  • 每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口;
  • Pod可以指定一组共享存储volumes。

Pod管理方式不同,也分为:

  • 自助式Pod:Pod退出了,不会被创建。
  • 控制器管理的Pod:始终会维持Pod的副本数。

Pod控制器

Kubernetes 中内建了很多 controller(控制器),这些相当于一个状态机,用来控制 Pod 的具体状态和行为。

ReplicationController(副本控制器)

确保Pod的数量始终保持设定的个数,如果容器异常退出会自动创建新的Pod来替代,也支持Pod的滚动更新。 已经废弃的Pod建议使用ReplicaSet 。
滚动更新:创建新的版本,然后删除旧的版本,实现版本的最新滚动更新。

ReplicaSet (副本集)

它和ReplicationController没有根本的区别,它支持集合式的Selector(选择多个Pod),但是它不直接使用,由一个声明式更新的控制器叫Deployment来负责管理。
有状态服务:通常指需要持久状态的服务 (Mysql),无状态:通常指无需存储服务状态的服务(tomcat)。

Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的 ReplicationController 来方便的管理应用,只需要在Deployment中描述你想要的目标状态是什么,Deployment controller就会帮你将Pod和Replica Set的实际状态改变到你的目标状态。

典型的应用场景包括;

  • 定义 Deployment 来创建 Pod 和 ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续 Deployment

但是Deployment只能负责管理那些无状态的应用。

StatefulSet (有状态副本集)

负责管理有状态的应用。

使用场景如:

  • 稳定的持久化存储,Pod重新调度后还能访问到相同的持久化数据
  • 稳定的网络标志,Pod重新调度后PodName和HostName不变
  • 有序部署Pod,有序删除Pod

DaemonSet

用来确保每一个Node上只运行一个Pod副本,Node加入集群时为他们创建一个Pod,当有Node从集群中移除时,Pod会被回收,删除DaemonSet将会删除它创建的所有Pod。

使用场景:
为每一个Node创建一个日志收集的Pod

Job

负责批处理任务,即仅执行一次任务。
比如:某个应用生成了一大堆数据集,现在需要临时启动一个Pod去清理这些数据集,清理完成后,这个Pod就可以结束了。 这些不需要一直处于运行状态的应用,就用Job这个类型的控制器去控制。如果Pod运行过程中意外中止了,Job负责重启Pod。如果Pod任务执行完了,就不需要再启动了。

Cronjob

周期性作业。
使用场景:
周期性的执行备份数据库

Service

我们不应该期望 Kubernetes Pod 是健壮的,而是要假设 Pod 中的容器很可能因为各种原因发生故障而死掉。Deployment 等 controller 会通过动态创建和销毁 Pod 来保证应用整体的健壮性。换句话说,Pod 是脆弱的,但应用是健壮的。每个 Pod 都有自己的 IP 地址。当 controller 用新 Pod 替代发生故障的 Pod 时,新 Pod 会分配到新的 IP 地址。

这样就产生了一个问题:

如果一组 Pod 对外提供服务(比如 HTTP),它们的 IP 很有可能发生变化,那么客户端如何找到并访问这个服务呢?Kubernetes 给出的解决方案是 Service

Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。

Kubernetes Service 从逻辑上代表了一组 Pod,具体是哪些 Pod 则是由 label 来挑选。Service 有自己 IP,而且这个 IP 是不变的。客户端只需要访问 Service 的 IP,Kubernetes 则负责建立和维护 Service 与 Pod 的映射关系。无论后端 Pod 如何变化,对客户端不会有任何影响,因为 Service 没有变。
在这里插入图片描述

ClusterIP

给service指定默认的ClusterIP,这种方式分配的ip只能在集群内部访问。

NodePort

在每个节点上都监听一个同样的端口号(30000-32767),ClusterIP和路由规则会自动创建。集群外部可以访问:联系到集群内部服务,可以配合外部负载均衡使用。
简单理解:使用端口映射方式去访问容器

LoadBalancer

要配合支持公有云负载均衡使用比如GCE、AWS。其实也是NodePort,不过除了使用一个Cluster IP和nodePort之外,还会向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的nodePort),实现从集群外通过LB访问服务。

ExternalName

创建一个dns别名指到service name上,主要是防止service name发生变化,要配合dns插件使用。

理解Service:
在这里插入图片描述

Endpoint

是可被访问的服务端点,即一个状态为running的pod,它是service访问的落点,只有service关联的pod才可能成为endpoint。简单理解:endpoint 用来记录一个service对应的所有pod的访问地址。
在这里插入图片描述

网络

  • 节点网络
    各主机(Master、Node、ETCD等)自身所属的网络,地址配置在主机的网络接口,用于各主机之间的通信,又称为节点网络。
  • Pod网络
    专用于Pod资源对象的网络,它是一个虚拟网络,用于为各Pod对象设定IP地址等网络参数,其地址配置在Pod中容器的网络接口上。Pod网络需要借助kubenet插件或CNI插件实现。
  • Service网络
    专用于Service资源对象的网络,它也是一个虚拟网络,用于为K8S集群之中的Service配置IP地址,但是该地址不会配置在任何主机或容器的网络接口上,而是通过Node上的kube-proxy配置为iptables或ipvs规则,从而将发往该地址的所有流量调度到后端的各Pod对象之上。
    在这里插入图片描述

Ingress Controller

Service 是后端真实服务的抽象,一个 Service 可以代表多个相同的后端服务。

Ingress 是反向代理规则,用来规定 HTTP/S 请求应该被转发到哪个 Service 上,比如根据请求中不同的 Host 和 url 路径让请求落到不同的 Service 上。

Ingress Controller 就是一个反向代理程序,它负责解析 Ingress 的反向代理规则,如果 Ingress 有增删改的变动,所有的 Ingress Controller 都会及时更新自己相应的转发规则,当 Ingress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service。
在这里插入图片描述

K8S安装

安装方式选择

安装部署主要方式分为三大类:minikube(单机) ,kubeadmin,二进制包(生产环境) , 我们这里采用kubeadmin的方式来安装。

Minikube

最为单机运行的k8s集群,直接使用官网感受一下,点击launch terminal ,浏览器下发会弹出命令界面。

Kubeadmin

配置基础环境 -> 安装kubeadmin部署工具 -> 使用kubeadmin配置master 、node、网络、dashboard等等。下面使用这种方式安装。

二进制包

相比上述两种有些复杂,但是可以通过二进制安装学到不少东西。

K8S集群准备

在这里插入图片描述

环境准备(一个Master两个Node)

推荐配置:内存4G以上,CPU 2 核以上 ,安装ContOS的磁盘 100G以上,网络使用桥接。

  1. 设置静态IP(三台)
    可以通过可视化界面修改
vi /etc/sysconfig/network-scripts/ifcfg-ens32
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"         # 使用静态IP地址,默认为dhcp
IPADDR="192.168.241.100"   # 设置的静态IP地址
NETMASK="255.255.255.0"    # 子网掩码
GATEWAY="192.168.241.1"    # 网关地址
DNS1="192.168.241.1"       # DNS服务器
DNS2="119.29.29.29"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"             #是否开机启用
## 删除 
rm -f /etc/udev/rule.d/70-persistent-net.rules
reboot 查看ip,和上网
  1. 分别设置主机名
hostnamectl set-hostname k8smaster
hostnamectl set-hostname k8snode01
hostnamectl set-hostname k8snode02
  1. 确保网络ok
ping www.baidu.com

初始化环境(三台)

  1. 设置hosts
 vi /etc/hosts
172.16.7.252 k8snode02
172.16.7.251 k8snode01
172.16.7.250 k8smaster
  1. 关闭防火墙
 # 关闭防火墙,并禁止开机启动
systemctl stop firewalld && systemctl disable firewalld
# 查看防火墙状态
systemctl status firewalld
  1. 禁用selinux
 # 临时禁用
setenforce 0

# 永久禁用 
vim /etc/sysconfig/selinux
修改:SELINUX=disabled	

#查看selinux的状态信息
/usr/sbin/sestatus
  1. 禁用交换分区
# 临时关闭
swapoff -a

# 永久关闭
vi /etc/fstab
# 注释掉以下字段
/dev/mapper/cl-swap  swap swap defaults  0 0
  1. 创建k8s配置
# 写入配置
cat <<EOF >  /etc/sysctl.d/k8s.conf
	net.bridge.bridge-nf-call-ip6tables = 1
	net.bridge.bridge-nf-call-iptables = 1
	net.ipv4.ip_forward = 1
    vm.swappiness=0 
	EOF
# 执行命令使修改生效
modprobe br_netfilter
# 查看
sysctl -p /etc/sysctl.d/k8s.conf
  1. kube-proxy开启ipvs的前置条件
# 保证在节点重启后能自动加载所需模块
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
	EOF
# 加上执行权限
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 查看是否已经正确加载所需的内核模块
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 安装了ipset软件包
yum -y install ipset
# 为了便于查看ipvs的代理规则,安装管理工具ipvsadm
yum -y install ipvsadm
  1. 同步时间
yum -y install ntp ntpdate
ntpdate cn.pool.ntp.org
hwclock --systohc
timedatectl

安装docker(三台)

菜鸟教程安装

  1. 卸载旧版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
   
  1. 安装
# 预装工具
yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置docker源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 更新yum缓存
sudo yum makecache fast
# 查看版本
yum list docker-ce --showduplicates | sort -r
# 安装指定版本
yum install docker-ce-18.06.3.ce-3.el7                  
# 安装(最新版本)
sudo yum -y install docker-ce
  1. 配置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://5pfmrxk8.mirror.aliyuncs.com"]
}
EOF
  1. 启动
systemctl daemon-reload && systemctl start docker && systemctl enable docker

注意:确认一下iptables filter表中FOWARD链的默认策略(pllicy)为ACCEPT

iptables -nvL

Chain INPUT (policy ACCEPT 9 packets, 760 bytes)
pkts bytes target     prot opt in     out     source            destination         
 
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

如果不是ACCEPT,则修改

iptables  -P FORWARD  ACCEPT
8.8.8.8

kubeadm初始化警告”cgroupfs“解决

安装K8S集群

安装kubeadm, kubelet and kubectl(三台)

  1. 配置yum路径
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
  1. 安装kubeadm, kubelet and kubectl
yum install -y kubelet-1.15.6 kubeadm-1.15.6 kubectl-1.15.6
  1. 启动
systemctl enable kubelet && systemctl start kubelet

配置kubeadm(master)

  1. 创建kubeadm配置文件
kubeadm config print init-defaults --kubeconfig ClusterConfiguration > kubeadm.yml
  1. 编辑配置文件
vim  kubeadm.yml
#只需要Master创建,创建好之后修改配置文件内容
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.1.250 #master地址
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: k8smaster
  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: registry.cn-hangzhou.aliyuncs.com/google_containers #修改镜像
kind: ClusterConfiguration
kubernetesVersion: v1.15.0
networking:
  dnsDomain: cluster.local
  podSubnet: "192.168.0.0/16" # 集群的网络
  serviceSubnet: 10.96.0.0/12 #子网掩码
scheduler: {}
# 开启 IPVS 模式,在 scheduler:{}下面加上  --- 然后复制下面内容
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
  SupportIPVSProxyMode: true
mode: ipvs

下载镜像(三台)

  1. 查看所需镜像列表
kubeadm config images list --config kubeadm.yml
# 拉取镜像 - 不要执行下面这个命令
kubeadm config images pull --config kubeadm.yml
# 注意:由于下载很慢,所以采用已经打包好的镜像

docker镜像批量打包
由于在内网环境或网速较慢的时候,下载镜像比较慢,所以可以将镜像打包成文件进行拷贝。这里写了一个批量打包镜像的语句。
批量打包镜像:

将机器上的所有镜像打包到haha.tar文件里面。
docker save $(docker images | grep -v REPOSITORY | awk 'BEGIN{OFS=":";ORS=" "}{print $1,$2}') -o k8simgs.tar

#打包指定镜像:
docker save imgName2:version imgName2:version-o /打包的镜像名.tar

#机器之间拷贝文件
scp -r /k8simgs.tar root@192.168.1.100:/

# 加载镜像:
docker load -i  /k8simgs.tar

然后docker images就可以看到拷贝过来的镜像了。

  1. 上传打包好的镜像
# 使用ftp工具上传到目录
/root/k8simgs.tar 

在这里插入图片描述

  1. 在三台机器加载镜像
#拷贝文件到另外两个centos
scp -r /root/k8simgs.tar root@192.168.0.114:/root/k8simgs.tar

也可以把压缩包上传到三个cenos分别再加载。

  1. 加载镜像
docker load -i  /root/k8simgs.tar

在这里插入图片描述

初始化master

  1. 初始化,进入主节点kubeadm.yml 所在目录执行
kubeadm init --config=kubeadm.yml 

在这里插入图片描述
如果要重新初始化可以执行:kubeadm reset 重置。

  1. Master执行配置,从上面输出中拷贝
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  1. 验证成功
kubectl get node 
# 并且拷贝命令到个节点执行

在这里插入图片描述
kubeadm初始化警告”cgroupfs“解决

加入node

  • 将 slave 加入到集群拷贝命令,从上面输出中拷贝,不要拷贝我的,要拷贝你自己的日志里面
kubeadm join 172.16.40.252:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:9f792d9c1bf57977ff22f317b599504a733b3f66688273ac3aa7505931f8e378 
  • 验证是否加入成功
kubectl get nodes

在这里插入图片描述
这里的status是NotReady是因为容器之间还没通信。

  • 加入失败
    如果 slave 节点加入 master 时配置有问题可以在 slave 节点上使用 kubeadm reset 重置配置再使用 kubeadm join 命令重新加入即可。希望在 master 节点删除 node ,可以使用 kubeadm delete nodes 删除。
    可以使用:journalctl -f -u kubelet查看错误日志
    k8s 集群 节点状态显示notready

  • Pod 状态查看

kubectl get pod -n kube-system -o wide

由此可以看出 coredns 尚未运行,此时我们还需要安装网络插件。

安装网络插件

  • 容器网络
    容器之间需要通信需要安装网络插件,我们使用CNI插件 ,容器网络是容器选择连接到其他容器、主和外部网络的机制。容器的 runtime 提供了各种网络模式,每种模式都会产生不同的体验。例如,Docker 默认情况下可以为容器配置以下网络:

  • bridge 网络:这是 Docker 默认的网络模式。在此模式下,Docker 守护进程会创建一个名为 docker0 的虚拟网桥,并为每个新容器分配一个 IP 地址。容器可以通过此网桥与宿主机和其他容器进行通信。它还使用 NAT(Network Address Translation)来实现容器与外部网络的通信。

  • none: 容器没有网络接口。容器仅能通过 Unix Socket 进行与宿主机通信。这种模式适用于一些特殊的用例,如只需要运行某些系统工具的容器。

  • host: 容器与宿主机共享网络栈。容器直接使用宿主机的网络接口和 IP 地址,因此容器可以通过宿主机的 IP 直接与外部网络通信。这意味着容器与宿主机共享相同的网络命名空间。

  • 自定义网桥:用户定义的网桥,具有更多的灵活性、隔离性和其他便利功能
    默认的网络模式不适用,这里使用CNI。

  1. 什么是 CNI
    CNI(Container Network Interface) 是一个标准的,通用的接口。在容器平台,Docker,Kubernetes,Mesos 容器网络解决方案 flannel(Docker提供),calico(Kubernetes提供),weave(Mesos 提供)。只要提供一个标准的接口,就能为同样满足该协议的所有容器平台提供网络功能,而 CNI 正是这样的一个标准接口协议。

  2. Kubernetes 中的 CNI 插件
    CNI 的初衷是创建一个框架,用于在配置或销毁容器时动态配置适当的网络配置和资源。插件负责为接口配置和管理 IP 地址,并且通常提供与 IP 管理、每个容器的 IP 分配、以及多主机连接相关的功能。容器运行时会调用网络插件,从而在容器启动时分配 IP 地址并配置网络,并在删除容器时再次调用它以清理这些资源。
    运行时或协调器决定了容器应该加入哪个网络以及它需要调用哪个插件。然后,插件会将接口添加到容器网络命名空间中,作为一个 veth 对的一侧。接着,它会在主机上进行更改,包括将 veth 的其他部分连接到网桥。再之后,它会通过调用单独的 IPAM(IP地址管理)插件来分配 IP 地址并设置路由。
    在 Kubernetes 中,kubelet 可以在适当的时间调用它找到的插件,为通过 kubelet 启动的 pod进行自动的网络配置。
    Kubernetes 中可选的 CNI 插件如下:Flannel、Calico、Canal 、Weave, 这里使用Calico

  3. 什么是 Calico
    Calico 为容器和虚拟机提供了安全的网络连接解决方案,并经过了大规模生产验证(在公有云和跨数千个集群节点中),可与 Kubernetes,OpenShift,Docker,Mesos,DC / OS 和 OpenStack 集成。
    Calico 还提供网络安全规则的动态实施。使用 Calico 的简单策略语言,您可以实现对容器,虚拟机工作负载和裸机主机端点之间通信的细粒度控制。

  4. 安装 Calico(三台)参考官方文档安装

kubectl apply -f https://docs.projectcalico.org/v3.9/manifests/calico.yaml

注意如果node下载不了,直接在所有节点通过docker pull下载

  1. 验证成功
    watch kubectl get pods --all-namespaces
  2. 查看Nodes
    kubectl get nodes

测试常用命令

  1. 检查组件运行状态
kubectl get cs

# 输出如下
NAME                 STATUS    MESSAGE             ERROR
# 调度服务,主要作用是将 POD 调度到 Node
scheduler            Healthy   ok                  
# 自动化修复服务,主要作用是 Node 宕机后自动修复 Node 回到正常的工作状态
controller-manager   Healthy   ok                  
# 服务注册与发现
etcd-0               Healthy   {"health":"true"} 
  1. 检查 Master 状态
kubectl cluster-info

# 输出如下
# 主节点状态
Kubernetes master is running at https://172.16.33.165:6443

# DNS 状态
KubeDNS is running at
 https://172.16.33.165:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
  1. 检查 Nodes 状态
kubectl get nodes

# 输出如下,STATUS 为 Ready 即为正常状态
[root@kmaster-01 calico]# kubectl get nodes
NAME         STATUS   ROLES    AGE   VERSION
kmaster-01   Ready    master   22m   v1.15.2
knode-01     Ready    <none>   11m   v1.15.2
  1. 查看全部 Pods 的状态
kubectl get pods  

kubectl get pods  等价于 kubectl get pods  -n default    ,default是默认的名称空间

kubectl get pods  -n kube-system

# kube-system 是k8s内部组件的名称空间,
输出如下,需要等待一小段实践,STATUS 为 Running 即为运行成功
NAME                     READY   STATUS    RESTARTS   AGE
nginx-755464dd6c-qnmwp   1/1     Running   0          90m
nginx-755464dd6c-shqrp   1/1     Running   0          90m
  1. 查看已部署的服务
kubectl get deployment

# 输出如下
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/2     2            2           91m
  1. 映射服务,让用户可以访问
kubectl expose deployment nginx --port=80 --type=LoadBalancer

# 输出如下
service/nginx exposed
  1. 查看已发布的服务
kubectl get services

# 输出如下
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        44h
# 由此可见,Nginx 服务已成功发布并将 80 端口映射为 31738
nginx        LoadBalancer   10.108.121.244   <pending>     80:31738/TCP   88m
  1. 查看服务详情
kubectl describe service nginx

# 输出如下
Name:                     nginx
Namespace:                default
Labels:                   run=nginx
Annotations:              <none>
Selector:                 run=nginx
Type:                     LoadBalancer
IP:                       10.108.121.244
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31738/TCP
Endpoints:                192.168.17.5:80,192.168.8.134:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
  1. 验证是否成功
    通过浏览器访问 Master 服务器
    http://172.16.33.165:31738/
    此时 Kubernetes 会以负载均衡的方式访问部署的 Nginx 服务,能够正常看到 Nginx 的欢迎页即表示成功。容器实际部署在其它 Node 节点上,通过访问 Node 节点的 IP:Port 也是可以的。
  2. 停止服务
kubectl delete deployment nginx

# 输出如下
deployment.extensions "nginx" deleted

kubectl delete service nginx

# 输出如下
service "nginx" deleted
# 看系统日志
cat /var/log/messages

# 用kubectl 查看日志

# 注意:使用Kubelet describe 查看日志,一定要带上 命名空间,否则会报如下错误
[root@node2 ~]# kubectl describe pod coredns-6c65fc5cbb-8ntpv
Error from server (NotFound): pods "coredns-6c65fc5cbb-8ntpv" not found

kubectl describe pod kubernetes-dashboard-849cd79b75-s2snt --namespace kube-system

kubectl logs -f pods/monitoring-influxdb-fc8f8d5cd-dbs7d -n kube-system

kubectl logs --tail 200 -f kube-apiserver -n kube-system |more

kubectl logs --tail 200 -f podname -n jenkins

# 用journalctl查看日志非常管用

journalctl -u kube-scheduler

journalctl -xefu kubelet

journalctl -u kube-apiserver


journalctl -u kubelet |tail

journalctl -xe


# 用docker查看日志

docker logs c36c56e4cfa3  (容器id)

#   换3.9版本
#   先现在node
# 杀死所有正在运行的容器
docker kill $(docker ps -a -q)

删除所有已经停止的容器
docker rm $(docker ps -a -q)

删除所有未打 dangling 标签的镜
docker rmi $(docker images -q -f dangling=true)

删除所有镜像
docker rmi $(docker images -q)

强制删除 无法删除的镜像
docker rmi -f <IMAGE_ID>
docker rmi -f $(docker images -q)

 ~/.bash_aliases
 
杀死所有正在运行的容器.
alias dockerkill='docker kill $(docker ps -a -q)'
 
 删除所有已经停止的容器.
alias dockercleanc='docker rm $(docker ps -a -q)'
 
删除所有未打标签的镜像.
alias dockercleani='docker rmi $(docker images -q -f dangling=true)'
 
 删除所有已经停止的容器和未打标签的镜像.
alias dockerclean='dockercleanc || true && dockercleani'

K8s资源清单

什么是资源

k8s中所有的内容都被抽象为资源,资源实例化之后,叫做对象。简单理解资源清单就是一个编写好的资源文件,k8s根据资源清单来进行pod的创建

资源分类

  1. 名称空间级别
    这一类资源仅在此名称空间下生效,k8s的系统组件是默认放在kube-system名称空间下的,而kubectl get pod等价于kubectl get pod -n default,因此查看不到k8s的系统组件。
  • 工作负载型资源(workload):Pod【k8s最小组成部分,共享网络栈共享存储卷】、ReplicaSet【RS,调度器、控制器,通过标签去控制pod的创建、副本数量】、Deployment【控制器,通过控制RS的创建去创建pod】、StatefulSet【为有状态服务所建立的管理器】、DaemonSet【可以在每一个节点都运行一个pod的组件】、Job【工作、任务】、CronJob【轮询工作、轮询任务,为批处理而生的】(ReplicationController在v1.11版本被废弃)
  • 服务发现及负载均衡型资源(ServiceDiscovery LoadBalance):Service【简称svc,服务,将服务暴露出去】、Ingress【将服务暴露出去】、…
  • 配置与存储型资源:Volume(存储卷)【给pod提供持久化的能力】、CSI(容器存储接口,可以扩展各种各样的第三方存储卷)
  • 特殊类型的存储卷:ConfigMap(当配置中心来使用的资源类型)【一般用来存储配置文件达到热更新的状态】、Secret(保存敏感数据)【加密方案存储数据,一般用来保存密码文件、密钥等等】、DownwardAPI(把外部环境中的信息输出给容器)【类似于CSI】
  1. 集群级别
    不管在任何名称空间下定义,在其他的名称空间下都能看得到,在定义的时候无需指定名称空间 例如:Namespace【名称空间】、Node【节点】、Role【角色】、ClusterRole、RoleBinding、ClusterRoleBinding

  2. 元数据级别
    提供一个指标,不像是名称空间类型又不像集群级别,本质上更像是在两者之间,但是它有自己的特点,所以更应该作为一个单独的分类,例如HPA【通过cpu的利用率进行平滑扩展】就是一个很明显的元数据类型,通过指标进行操作。
    根据一些指标去进行对应的操作
    例如:HPA、PodTemplate【pod模板】、LimitRange【资源限制】

资源清单

  1. 什么是资源清单
    k8s一般都是通过定义资源清单的方式去创建资源,资源清单等价于剧本,写好了每一步应该如何去做。在k8s中,一般使用yaml格式的文件来创建符合我们预期期望的资源,这样的yaml文件我们一般称为资源清单。
  2. 资源清单定义格式
    必须存在的字段:
    在这里插入图片描述具体定义使用yaml格式如下:
apiVersion: group/apiversion #如果没有给定group名称,那么默认为core,可以使用kubectl api-versions命令获取当前k8s版本上所有的apiversion版本信息(每个版本可能不同)
kind: #资源类别
metadata: #资源元数据
  name: 
  namespace: 
  lables: 
  annotations: #主要目的是方便用户阅读查找
spec: #期望的状态(disired state)
status: #当前状态,本字段由Kubernetes自身维护,用户不能去定义
apiVersion: v1
kind: Pod #定义pod资源
metadata:
  name: myapp-pod #pod的名字
  labels:
    app: myApp #pod标签
    version: v1 #pod的版本
spec: #pod的详细配置
 containers: #pod包含的多个容器配置
  - name: app #第一个容器
    image: myapp:v1 #容器版本
  - name: myapp  # 第二个容器,报错,删除后没有问题
    image: myapp:v1 #容器版本
  1. 常见命令
    查看pod的yml清单配置语法
kubectl explain pod

# 这个命令会告诉我们,编写一个pod资源的yml清单应该使用那些语法
kubectl explain pod.apiVersion

在这里插入图片描述2. 导出yml资源清单

kubectl get pods          # 查看有那些pod
kubectl  get  pod  pod的名字  -o yaml    

在这里插入图片描述

工作负载型资源(workload)

Pod

Pod是K8S中可以创建的最小部署单元,一个Pod代表集群上正在运行的一个进程。Pod代表部署的一个单位:K8S中单个应用的实例,它可能由单个容器或多个容器共享组成。

演示案例:把一个Nignx容器运行在一个Pod中

  1. 创建资源文件
vi poddemo.yaml       # 内容如下
  1. 添加如下内容
apiVersion: v1
kind: Pod
metadata:
  name: app-pod #pod名字
  labels:
    app: app-label #pod的标签
    version: v1
spec:
 containers:
  - name: app #容器名字
image: nginx #容器镜像
imagePullPolicy: IfNotPresent #或者 Never 从本地找镜像
  1. 根据资源文件创建pod
kubectl apply -f poddemo.yaml
  1. 相关命令
kubectl get pod # 查看pod
kubectl get pod -o wide # 详细信息,包括ip
kubectl describe pod app-pod # 查询pod描述 可以看到那个pod启动状态
kubectl logs app-pod -c app  # 查看pod里面那个容器的启动状态
kubectl delete pod app-pod # 删除指定pod
kubectl delete -f poddemo.yaml # 删除全部
kubectl create -f poddemo.yaml # 效果和kubectl apply差不多

Pod控制器Replicaset

通常不直接部署及管理Pod,而是借助控制器Controller进行管理,包括 ReplicationController(老版本的)、ReplicaSet、Deployment、StatefulSet、Job等。Pod控制器通常包含三个组成部分:标签选择器、期望的副本数、Pod模板。
Replicaset是ReplicationController的替代者,确保Pod副本数在任一时刻都精确满足期望值,可以进行扩缩容,也可以进行升级。

  1. 创建资源文件
vi rs.yaml
  1. 加入如下内容
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-example #RS的名字
spec:
  replicas: 2  #创建2个pod副本
  selector: #选择什么样的pod
    matchLabels:
      app: rs-demo  #选择名字叫rs-demo的pod
  template:  #定义pod的模板
    metadata:
      labels:
        app: rs-demo #pod的标签,正好被RS选择
    spec:
      containers: #pod中的容器配置
      - name: myapp
        image: nginx
        imagePullPolicy: Never #IfNotPresent如果不存在再去网络拉取
        ports: #暴露容器的端口
        - name: http
          containerPort: 80
  1. 创建ReplicaSet
kubectl create -f rs.yaml
  1. 相关命令
kubectl get pods

在这里插入图片描述删除pod后会自动复制

Kubectl delete pod --all

在这里插入图片描述显示标签

kubectl get pods --show-labels 

在这里插入图片描述修改标签

kubectl label pod rs-example-knjhx app=rs-demo1 --overwrite=true

在这里插入图片描述更改后lable后重新补齐

Pod控制器Deployment

Deployment构建于ReplicaSet之上, 支持事件和状态查看,回滚,版本记录,暂停和启动升级,多种自动更新方案:Recreate(先删除再新建),Deployment支持RollingUpdate(滚动升级,逐步替换)

什么是滚动升级:如有三个副本,先建立一个新的副本,然后删除一个老的副本,再建立一个新的副本,删除一个老的副本
在这里插入图片描述

  1. 准备镜像(可以跳过)
    我们基于tomcat准备三个不同版本的tomcat镜像,为Deployment做滚动升级做准备,您可以按照如下步骤打包三个tomcat镜像,也可以使用课件资料中的resources/tomcatimgs.tar我已经准备好的资源镜像包,如果使用我的镜像包,就上传tomcatimgs.tar到三个k8s服务器(/root目录),执行docker load -i /root/tomcatimgs.tar 即可加载三个版本的镜像。
    在这里插入图片描述
  • 下载tomcat镜像
docker pull tomcat
  • 运行tomcat容器
docker run -id --name=tomcat -p 8080:8080 tomcat
  • 准备index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"  import="java.net.InetAddress"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>index.jsp</title>
</head>
<body>
   <h2>v1</h2>
	 <%
		 InetAddress addr = InetAddress.getLocalHost();
		 out.println("主机地址:"+addr.getHostAddress());
	 	 out.println("主机名:"+addr.getHostName()); 
      %>
</body>
</html>
  • 创建镜像
    修改分别得到tomcat:v1 tomcat:v2 tomcat:v3
docker exec -it tomcat /bin/bash 进入容器
mkdir /usr/local/tomcat/webapps/ROOT
exit 退出容器

vim index.jsp 创建页面,拷贝上面jsp内容
docker cp index.jsp tomcat:/usr/local/tomcat/webapps/ROOT/
http://192.168.0.113:8080/ 访问测试
docker commit tomcat tomcat:v1 构建镜像:tomat:v1

修改index.jsp内容: <h2>v2</h2>
docker cp index.jsp tomcat:/usr/local/tomcat/webapps/ROOT/
http://192.168.0.113:8080/ 访问测试
docker commit tomcat tomcat:v2 构建镜像:tomat:v2

修改index.jsp内容: <h2>v3</h2>
docker cp index.jsp tomcat:/usr/local/tomcat/webapps/ROOT/
http://192.168.0.113:8080/ 访问测试
docker commit tomcat tomcat:v3 构建镜像:tomat:v3
  • 拷贝镜像
    打包三个镜像共享给其他节点
docker save tomcat:v1 tomcat:v2 tomcat:v3 -o /root/tomcatimgs.tar
# 其他两个节点做
scp -r tomcatimgs.tar root@192.168.0.114:/root
  • 加载镜像
docker load -i /root/tomcatimgs.tar
  1. Deployment控制pod

(1) 创建pod

  • 创建资源文件
vi deploy.yaml
  • 加入如下内容
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-example
spec:
  replicas: 2
  selector:
    matchLabels:
      app: deploy-demo
  template:
    metadata:
      labels:
        app: deploy-demo
    spec:
      containers:
      - name: myapp
        image: tomcat:v1 #这里是对应我们三个tomcat镜像
        imagePullPolicy: Never #IfNotPresent如果不存在再去网络拉取
        ports:
        - name: http
          containerPort: 8080
  • 创建Deployment
kubectl apply -f deploy.yaml

需要注意:三个k8s机器上都要有镜像:tomcat:v1;tomcat:v2:tomcat:v3

  • 查看pods
kubectl get pods -o wide  # 查看pod详情
curl 192.168.32.168:8080  # 访问容器,通过pod的网络访问,外网目前访问不到
kubectl get deployments   # 查看deployments

(2) 扩容缩容

  • 方式一
    使用命令修改pod数量
kubectl scale deployment deploy-example --replicas=3  # 修改pod数量到 3 个
  • 方式2
    直接修改yaml文件的方式进行扩容
spec:
replicas: 5
  • 方式3
    通过打补丁的方式进行扩容 - 了解
kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'

(3) 版本更新
这里有两种方式:1)滚动更新(rolling update) ; 2)重新创建(recreate) 。默认为滚动更新
1)滚动更新:使用2个ReplicaSet,RS1删除一个旧的pod,RS2创建一个新的pod,依次类推实现pod滚动升级
2)重新创建:使用1个ReplicaSet,删除一个,创建一个,依次类推
在这里插入图片描述方式1:yaml改镜像版本并应用

  1. 复制资源文件进行修改
    cp deploy.yaml deploy1.yaml

  2. 把镜像版本修改为tomcat:v2 ,进行镜像升级vi deploy1.yaml

  3. 应用资源文件
    kubectl apply -f deploy1.yaml

  4. 查看Replicaset
    kubectl get rs 查看deployement
    在这里插入图片描述多一个deployeement,原本的 3 个pod已经被干掉变成了 0 ,创建了新的 2 个 pod ,因为我新的资源文件中的replicas值为2

  5. 查看,访问,测试一下,容器中的项目版本已经更新

kubectl get pods -o wide  # 查看pod网络
curl 192.168.32.179:8080  # 访问pod

在这里插入图片描述方式2:命令设置镜像

  1. 设置镜像版本
kubectl set image deployment/deploy-example myapp=tomcat:v2
# deploy-example : deployment的名字
# myapp=tomcat:v2  镜像名=镜像:版本
  1. 查看rs
kubectl get rs  

在这里插入图片描述
3. 查看pod

kubectl get pods

在这里插入图片描述
4. 访问容器内容

curl 192.168.185.220:8080

在这里插入图片描述(4) 版本还原

  1. 查看历史
kubectl rollout history deploy deploy-example

在这里插入图片描述
2. 查看具体版本

kubectl rollout history deploy deploy-example --revision=1

在这里插入图片描述
在这里插入图片描述
3. 回退版本

kubectl rollout undo deploy deploy-example --to-revision=1

在这里插入图片描述

参考博客

  • 一文解读云原生(转)
  • K8s – Service

  1. Raft(Raft一致性算法)是一种用于分布式系统中实现一致性的共识算法。它旨在提供容错性和可理解性,使得在网络不可靠或节点故障的情况下,分布式系统仍能保持一致性。
    Raft算法通过选举一个领导者(称为"leader")来管理复制状态机的日志复制过程。领导者负责接收客户端请求,并将它们复制到其他节点上的日志中。当多数节点确认接收到日志后,该日志被认为是已提交的,然后被应用到状态机中。这种方式确保了一致性。
    Raft算法关注三个关键问题:领导选举、日志复制和安全性。领导选举确保了集群中只有一个领导者,避免冲突和混乱。日志复制确保了所有节点持有相同的日志序列,从而达到一致性。安全性方面,Raft算法使用了多数派原则,在大多数节点正常运行的情况下,才能保证系统的正常运行。
    相比于一些其他共识算法,如Paxos,Raft算法更易于理解和实现。由于其简洁性和可理解性,Raft算法被广泛应用于分布式系统,包括Kubernetes集群中的Etcd组件。 ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

6 时间序列(不同位置的装置如何建模): GRU+Embedding

很多算法比赛经常会遇到不同的物体产生同含义的时间序列信息&#xff0c;比如不同位置的时间序列信息&#xff0c;风力发电、充电桩用电。经常会遇到该如此场景&#xff0c;对所有数据做统一处理喂给模型&#xff0c;模型很难学到区分信息&#xff0c;因此设计如果对不同位置的…

【Linux】常见指令(一)

前言: Linux有许多的指令&#xff0c;通过学习这些指令&#xff0c;可以对目录及文件进行操作。 文章目录 一、基础指令1. ls—列出目录内容2. pwd—显示当前目录3. cd—切换目录重新认识指令4. touch—创建文件等5. mkdir—创建目录6. rmdir指令 && rm 指令7. man—显…

linux源码编译安装llvm

目录 1 建立文件夹llvm 2 下载源码到llvm文件夹 3 解压上述文件 4 将解压后的3个文件夹改名&#xff0c;并移动到llvm-9.0.0.src中&#xff1a; 5 在llvm文件夹内建立build文件夹&#xff0c;并进入该文件夹&#xff1a; 6 执行cmake命令 7 make 8 安装 9 安装成功后…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--机器人、强化学习

专属领域论文订阅 VX 扫吗关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有帮助可以扫吗关注&#xff0c;每日准时为你推送最新论文 分类: 大语言模型LLM视觉模型VLM扩散模型视觉导航…

Git Docker 学习笔记

注意&#xff1a;该文章摘抄之百度&#xff0c;仅当做学习笔记供小白使用&#xff0c;若侵权请联系删除&#xff01; 目录 列举工作中常用的几个git命令&#xff1f; 提交时发生冲突&#xff0c;你能解释冲突是如何产生的吗&#xff1f;你是如何解决的&#xff1f; git的4个…

安全通信网络

1.网络架构 1&#xff09;应保证网络设备的业务处理能力满足业务高峰期需要。 设备CPU和内存使用率的峰值不大于设备处理能力的70%。 在有监控环境的条件下&#xff0c;应通过监控平台查看主要设备在业务高峰期的资源&#xff08;CPU、内存等&#xff09;使用 情况&#xff…

双数据源同步的思考

双数据源同步的思考 目录概述需求&#xff1a; 设计思路实现思路分析1.简单实现 2.Spring mybatis 技术 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wa…

geemap学习笔记053:纹理特征

前言 纹理特征通常描述了遥感影像中像素之间的空间关系和变化&#xff0c;对于地物分类、目标检测以及图像分割等遥感应用非常有价值。本节将会介绍Earth Engine中提供的一些纹理特征计算方法&#xff0c;包括熵和灰度共生矩阵。 1 导入库并显示数据 import ee import geema…

.NET发展如火如荼,这回.Net 8的野心确实不小

随着三天.NET Conf 2023的会议结束了&#xff0c;.Net 8正式发布了。 .Net 8是官方号称有史以来性能最快的一个版本了。 .Net 8 增加了数以千计的性能、稳定性和安全性改进&#xff0c;以及平台和工具增强功能&#xff0c;有助于提高开发人员的工作效率和创新速度。 反正就是快…

【Leetcode 965.】判断单值二叉树

单值二叉树&#xff1a; 示例一&#xff1a; 示例二&#xff1a; 代码&#xff1a; bool isUnivalTree(struct TreeNode* root) {if(rootNULL)return true;if(root->left&&root->left->val!root->val)return false;if(root->right&&root-&…

【2024系统架构设计】案例分析- 1软件架构设计

目录 一 基础知识 二 历年真题 案例分析前文回顾: 【2024系统架构设计】 系统架构设计师第二版-大数据架构理论设计与实践 【2024系统架构设计】 系统架构设计师第二版-云原生架构设计理论与实践

opencv#30 线性滤波

均值滤波原理 均值滤波步骤 Step1:求和。 Step2:计算平均值。 所谓均值滤波&#xff0c;就是求平均值的意思。我们假设在一个3*3的范围内有一个图像&#xff0c;其中这个图像每一个像素可能含有噪声&#xff0c;也可能不含噪声&#xff0c;我们是不知道的&#xff0c;因此通…

力扣1143. 最长公共子序列(动态规划)

Problem: 1143. 最长公共子序列 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 我们先假设已经将两个字符串转换为两个char类型的数组&#xff08;t1,t2&#xff09;便于比较 1.如果t1[i] t2[j],有三种决策&#xff1a;&#xff08;i1&#xff0c;j1&#xff09;&a…

【江科大】STM32:TIM输入捕获(理论部分)

文章目录 IC&#xff08;Input Capture&#xff09;输入捕获PWM频率 知识点补充1. 滤波器的工作原理&#xff1a;2. 边沿检测器&#xff1a;自动化清零CNT输入捕获的基本结构PWMI基本结构滤波器和分频器的区别误差分析pwm.cmain.cIC.c PWM模式测频率和占空比 IC&#xff08;Inp…

架构篇08:架构设计三原则

文章目录 合适原则简单原则演化原则小结 成为架构师是每个程序员的梦想&#xff0c;但并不意味着把编程做好就能够自然而然地成为一个架构师&#xff0c;优秀程序员和架构师之间还有一个明显的鸿沟需要跨越&#xff0c;这个鸿沟就是“不确定性”。 对于编程来说&#xff0c;本…

神经网络算法与逻辑回归:优势与差异

神经网络算法和逻辑回归都是预测模型中的重要工具&#xff0c;但它们在处理复杂和非线性问题时表现出不同的性能。本文将深入探讨神经网络算法相对于逻辑回归的优势&#xff0c;以及它们在不同场景下的适用性。 一、引言 神经网络算法和逻辑回归都是预测模型中的重要工具&…

Ubuntu用gparted重新分配空间

ubuntu系统使用过程中安装系统时预先留的空间不够使用怎么办&#xff1f; 这么办&#xff01; 首先 使用df -h 查看当前空间使用情况 已经分配的空间重新规划 &#xff1f; 先将已分配的空间中的多余空间分离出来&#xff1b; 假设我想将挂载点/home下的一部分空间分给挂载…

数据结构之使用顺序表写出通讯录

前言 昨天我们踏入了数据结构的深山&#xff0c;并且和顺序表battle了一番&#xff0c;虽说最后赢了&#xff0c;但同时也留下了一个问题&#xff1a;如何从顺序表的增删查改加强到通讯录的的增删查改&#xff0c;别急&#xff0c;今天就带你一探究竟。 一.回顾与思考 我们昨…

20.云原生之GitLab CICD实战

云原生专栏大纲 文章目录 GitLab RunnerGitLab Runner 介绍Gitlab Runner工作流程 Gitlab集成Gitlab RunnerGitLab Runner 版本选择Gitlab Runner部署docker-compose方式安装kubesphere中可视化方式安装helm方式安装 配置gitlab-runner配置gitlab-ci.ymlgitlab-ci.yml 介绍编写…

i18n多国语言Internationalization的动态实现

一、数据动态的更新 在上一篇i18n多国语言Internationalization的实现-CSDN博客&#xff0c;可能会遇到一个问题&#xff0c;我们在进行英文或中文切换时&#xff0c;并没有办法对当前的数据进行动态的更新。指的是什么意思呢&#xff1f;当前app.js当中一个组件内容&#xff…