Kubernetes 的用法和解析 -- 5
一.企业级镜像仓库Harbo
准备:另起一台新服务器,并配置docker yum源,安装docker 和 docker-compose
1.1 上传harbor安装包并安装
[root@harbor ~]# tar xf harbor-offline-installer-v2.5.3.tgz
[root@harbor ~]# cp harbor.yml.tmpl harbor.yml
[root@harbor ~]# vim harbor.yml
hostname: 192.168.58.146 # http related config
http:# port for http, default is 80. If https enabled, this port will redirect to https portport: 80
# 注释所有https的内容[root@harbor ~]# sh install.sh
1.2 浏览器访问
默认账号:admin 默认密码:Harbor12345
1.3 k8s使用harbor仓库
# 两台node节点执行
[root@kube-node1 ~]# vim /etc/docker/daemon.json #不存在则创建
{ "insecure-registries": ["192.168.58.146"] }# 重启docker:
[root@kube-node1 ~]# systemctl restart docker
1.4 上传镜像到仓库
[root@kube-node1 ~]# docker login http://192.168.246.168
username:admin
password:
[root@kube-node1 ~]# docker pull daocloud.io/library/nginx
[root@kube-node1 ~]# docker tag daocloud.io/library/nginx 192.168.58.146/library/nginx:v1.0
1.5 创建secret.yaml文件
[root@kube-node1 ~]# cat ~/.docker/config.json |base64 -w 0
ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjU4LjE0NiI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXoiCgkJfQoJfQp9#创建 secret.yaml 文件
[root@kube-master ~]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:name: login
type: kubernetes.io/dockerconfigjson
data:.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjU4LjE0NiI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXo[root@kube-master ~]# kubectl apply -f secret.yaml
1.6 k8s-pod 使用镜像
[root@kube-master ~]# vim harbor-pod.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:name: show
spec:replicas: 2selector:matchLabels:app: showtemplate:metadata:labels:app: showspec:containers:- name: showimage: 192.168.58.146/library/nginx:v1.0ports:- containerPort: 80imagePullSecrets:- name: login---
apiVersion: v1
kind: Service
metadata:name: show-service
spec:type: NodePortselector:app: showports:- port: 80targetPort: 80nodePort: 32000 #范围:30000 - 32765
浏览器访问:192.168.58.146:32000
二.水平扩展/收缩与滚动更新
2.1 水平扩展/收缩
2.1.1 创建一个deployment
[root@kube-master ~]# vim deployment.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: dep01labels:name: dep01
---
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp
spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.16.1ports:- containerPort: 80[root@kube-master ~]# kubectl apply -f deployment.yaml
2.1.2 通过声明方式扩展
[root@kub-k8s-master prome]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dep01 2/2 2 2 4h41m我们将dep01的副本数量变成4个,现在2个
[root@kub-k8s-master prome]# vim deployment.yaml #修改如下内容
将replicas: 2
修改为:
replicas: 4
[root@kub-k8s-master prome]# kubectl apply -f deployment.yaml --record
deployment.apps/dep01 configured--record kubectl apply 每次更新应用时 Kubernetes 都会记录下当前的配置,保存为一个 revision(版次),这样就可以回滚到某个特定 revision。
检查nginx-deployment 创建后的状态信息:
[root@kub-k8s-master prome]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dep01 4/4 4 4 4h53m
返回结果中四个状态字段含义:
DESIRED:
如果有就表示用户期望的 Pod 副本个数(spec.replicas 的值);CURRENT:
当前处于 Running 状态的 Pod 的个数;UP-TO-DATE:
当前处于最新版本的 Pod 的个数,所谓最新版本指的是 Pod 的 Spec 部分与 Deployment 里 Pod 模板里定义的完全一致;AVAILABLE:
当前已经可用的 Pod 的个数,即:既是 Running 状态,又是最新版本,并且已经处于 Ready(健康检查正确)状态的 Pod 的个数。只有这个字段,描述的才是用户所期望的最终状态。
2.1.3 通过edit方式收缩
[root@kub-k8s-master prome]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
dep01 4/4 4 4 4h59m将dep01的副本将4变为3个
[root@kub-k8s-master prome]# kubectl edit deployment/dep01# reopened with the relevant failures.
#
apiVersion: apps/v1
...
spec:progressDeadlineSeconds: 600replicas: 3 #将这里原来的4改为3revisionHistoryLimit: 10selector:matchLabels:
...
保存退出,vim的方式
[root@kub-k8s-master prome]# kubectl edit deployment/dep01
deployment.apps/dep01 edited
2.2 滚动更新
概念:
将一个集群中正在运行的多个 Pod 版本,交替地逐一升级的过程,就是"滚动更新"。
2.2.1 进行版本的升级
创建一个新的deploy
[root@kub-k8s-master prome]# cp nginx-depl.yml nginx-depl02.yml
[root@kub-k8s-master prome]# vim nginx-depl02.yml
apiVersion: apps/v1
kind: Deployment
metadata:name: dep02 #注意修改
spec:selector:matchLabels:app: web1replicas: 2template:metadata:name: testnginx9labels:app: web1spec:containers:- name: testnginx9image: daocloud.io/library/nginx:1.14 #注意修改ports:- containerPort: 80
[root@kub-k8s-master prome]# kubectl apply -f nginx-depl02.yml
deployment.apps/dep02 created
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep01-58f6d4d4cb-997jw 1/1 Running 0 16m
dep01-58f6d4d4cb-g6vtg 1/1 Running 0 5h32m
dep01-58f6d4d4cb-k6z47 1/1 Running 0 5h32m
dep02-78dbd944fc-47czr 1/1 Running 0 44s
dep02-78dbd944fc-4snsj 1/1 Running 0 25s将nginx的版本从1.14升级到1.16
[root@kub-k8s-master prome]# kubectl edit deployment/dep02
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
...
spec:containers:- image: daocloud.io/library/nginx:1.16 #将这里原来的nginx:1.14修改为nginx:1.16imagePullPolicy: Alwaysname: testnginx9ports:- containerPort: 80
...
保存退出,vim的方式
[root@kub-k8s-master prome]# kubectl edit deployment/dep02
deployment.apps/dep01 edited
这时可以通过查看 Deployment 的 Events,看到这个"滚动更新"的流程
[root@kub-k8s-master prome]# kubectl describe deployment dep02
...
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal ScalingReplicaSet 50s deployment-controller Scaled up replica set dep02-846bf8775b to 2Normal ScalingReplicaSet 9s deployment-controller Scaled up replica set dep02-58f8d5678 to 1Normal ScalingReplicaSet 8s deployment-controller Scaled down replica set dep02-846bf8775b to 1Normal ScalingReplicaSet 8s deployment-controller Scaled up replica set dep02-58f8d5678 to 2Normal ScalingReplicaSet 5s deployment-controller Scaled down replica set dep02-846bf8775b to 0
如此交替进行,新 ReplicaSet 管理的 Pod 副本数,从 0 个变成 1 个,再变成 2 个,最后变成 3 个。而旧的 ReplicaSet 管理的 Pod 副本数则从 3 个变成 2 个,再变成 1 个,最后变成 0 个。这样,就完成了这一组 Pod 的版本升级过程。
2.2.2 验证
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep02-78dbd944fc-69t8x 1/1 Running 0 11h
dep02-78dbd944fc-7cn86 1/1 Running 0 11h
[root@kub-k8s-master prome]# kubectl exec -it dep02-78dbd944fc-69t8x /bin/bash
root@dep02-78dbd944fc-69t8x:/# nginx -v
nginx version: nginx/1.16.1
root@dep02-78dbd944fc-69t8x:/# exit
2.2.3 滚动更新的好处
在升级刚开始的时候,集群里只有 1 个新版本的 Pod。如果这时,新版本 Pod 有问题启动不起来,那么"滚动更新"就会停止,从而允许开发和运维人员介入。而在这个过程中,由于应用本身还有两个旧版本的 Pod 在线,所以服务并不会受到太大的影响。
2.3 版本回滚
2.3.1 查看版本历史
[root@kub-k8s-master prome]# kubectl rollout history deployment/dep02
deployment.apps/dep02
REVISION CHANGE-CAUSE
1 <none>
2 <none>
2.3.2 回滚到以前的旧版本:
把整个 Deployment 回滚到上一个版本:
[root@kub-k8s-master prome]# kubectl rollout undo deployment/dep02
deployment.apps/dep02 rolled back
查看回滚状态
[root@kub-k8s-master prome]# kubectl rollout status deployment/dep02
deployment "dep02" successfully rolled out
验证:
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep02-8594cd6447-pqtxk 1/1 Running 0 55s
dep02-8594cd6447-tt4h4 1/1 Running 0 51s
[root@kub-k8s-master prome]# kubectl exec -it dep02-8594cd6447-tt4h4 /bin/bash
root@dep02-8594cd6447-tt4h4:/# nginx -v
nginx version: nginx/1.14.2
2.3.3 回滚到更早之前的版本
-
使用 kubectl rollout history 命令查看每次 Deployment 变更对应的版本。
[root@kub-k8s-master prome]# kubectl rollout history deployment/dep02
deployment.apps/dep02
REVISION CHANGE-CAUSE
2 <none>
3 <none>#默认配置下,Kubernetes 只会保留最近的几个 revision,可以在 Deployment 配置文件中通过 revisionHistoryLimit: 属性增加 revision 数量。
由于在创建这个 Deployment 的时候,指定了--record 参数,会将创建这些版本时执行的 kubectl 时文件中的配置,都会记录下来。
查看每个版本对应的 Deployment 的 API 对象的细节:
[root@kub-k8s-master prome]# kubectl rollout history deployment/dep02 --revision=3
deployment.apps/dep02 with revision #3
Pod Template:Labels: app=web1pod-template-hash=8594cd6447Containers:testnginx9:Image: daocloud.io/library/nginx:1.14Port: 80/TCPHost Port: 0/TCPEnvironment: <none>Mounts: <none>Volumes: <none>
2.在 kubectl rollout undo 命令行最后,加上要回滚到的指定版本的版本号,就可以回滚到指定版本了。
[root@kub-k8s-master prome]# kubectl rollout undo deployment/dep02 --to-revision=2
deployment.apps/dep02 rolled back#验证:
[root@kub-k8s-master prome]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep02-78dbd944fc-8nvxl 1/1 Running 0 86s
dep02-78dbd944fc-sb9sj 1/1 Running 0 88s
[root@kub-k8s-master prome]# kubectl exec -it dep02-78dbd944fc-8nvxl /bin/bash
root@dep02-78dbd944fc-8nvxl:/# nginx -v
nginx version: nginx/1.16.1
三.DeamonSet详解
3.1 何为DaemonSet
介绍DaemonSet我们先来思考一个问题:相信大家都接触过监控系统比如zabbix,监控系统需要在被监控机安装一个agent,安装agent通常会涉及到以下几个场景:
- 所有节点都必须安装agent以便采集监控数据
- 新加入的节点需要配置agent,手动或者运行脚本
k8s中经常涉及到在node上安装部署应用,它是如何解决上述的问题的呢?答案是DaemonSet。DaemonSet守护进程简称DS,适用于在所有节点或部分节点运行一个daemon守护进程。
DaemonSet 的主要作用,是让你在 k8s 集群里,运行一个 Daemon Pod。
这个 Pod 有如下三个特征:
这个 Pod 运行在 k8s 集群里的每一个节点(Node)上;
每个节点上只有一个这样的 Pod 实例;
当有新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来;而当旧节点被删除后,它上面的 Pod 也相应地会被回收掉。
举例:
各种网络插件的 Agent 组件,都必须运行在每一个节点上,用来处理这个节点上的容器网络;
各种存储插件的 Agent 组件,也必须运行在每一个节点上,用来在这个节点上挂载远程存储目录,操作容器的 Volume 目录;
各种监控组件和日志组件,也必须运行在每一个节点上,负责这个节点上的监控信息和日志搜集。
3.2 DaemonSet 的 API 对象的定义
所有node节点分别下载镜像
# docker pull daocloud.io/daocloud/fluentd-elasticsearch:1.20
# docker pull daocloud.io/daocloud/fluentd-elasticsearch:v2.2.0
fluentd-elasticsearch 镜像功能:
通过 fluentd 将每个node节点上面的Docker 容器里的日志转发到 ElasticSearch 中。
编写daemonset配置文件
Yaml文件内容如下
[root@k8s-master ~]# mkdir set
[root@k8s-master ~]# cd set/
[root@k8s-master set]# vim fluentd-elasticsearch.yaml # DaemonSet 没有 replicas 字段
apiVersion: apps/v1
kind: DaemonSet #创建资源的类型
metadata:name: fluentd-elasticsearchnamespace: kube-systemlabels:k8s-app: fluentd-logging
spec:selector:matchLabels:name: fluentd-elasticsearchtemplate:metadata:labels:name: fluentd-elasticsearchspec:tolerations: #容忍污点- key: node-role.kubernetes.io/master #污点effect: NoSchedule #描述污点的效应containers:- name: fluentd-elasticsearchimage: daocloud.io/daocloud/fluentd-elasticsearch:1.20resources: #限制使用资源limits: #定义使用内存的资源上限memory: 200Mirequests: #实际使用cpu: 100mmemory: 200MivolumeMounts:- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: truevolumes:- name: varloghostPath: #定义卷使用宿主机目录path: /var/log- name: varlibdockercontainershostPath:path: /var/lib/docker/containers
DaemonSet 没有 replicas 字段
selector :
选择管理所有携带了 name=fluentd-elasticsearch 标签的 Pod。
Pod 的模板用 template 字段定义:
定义了一个使用 fluentd-elasticsearch:1.20 镜像的容器,而且这个容器挂载了两个 hostPath 类型的 Volume,分别对应宿主机的 /var/log 目录和 /var/lib/docker/containers 目录。
fluentd 启动之后,它会从这两个目录里搜集日志信息,并转发给 ElasticSearch 保存。这样,通过 ElasticSearch 就可以很方便地检索这些日志了。Docker 容器里应用的日志,默认会保存在宿主机的 /var/lib/docker/containers/{{. 容器 ID}}/{{. 容器 ID}}-json.log 文件里,这个目录正是 fluentd 的搜集目标。
DaemonSet 如何保证每个 Node 上有且只有一个被管理的 Pod ?
DaemonSet Controller,首先从 Etcd 里获取所有的 Node 列表,然后遍历所有的 Node。这时,它就可以很容易地去检查,当前这个 Node 上是不是有一个携带了 name=fluentd-elasticsearch 标签的 Pod 在运行。
检查结果有三种情况:
1. 没有这种 Pod,那么就意味着要在这个 Node 上创建这样一个 Pod;指定的 Node 上创建新 Pod 用 nodeSelector,选择 Node 的名字即可。
2. 有这种 Pod,但是数量大于 1,那就说明要把多余的 Pod 从这个 Node 上删除掉;删除节点(Node)上多余的 Pod 非常简单,直接调用 Kubernetes API 就可以了。
3. 正好只有一个这种 Pod,那说明这个节点是正常的。
tolerations:
DaemonSet 还会给这个 Pod 自动加上另外一个与调度相关的字段,叫作 tolerations。这个字段意思是这个 Pod,会"容忍"(Toleration)某些 Node 的"污点"(Taint)。
tolerations 字段,格式如下:
apiVersion: v1
kind: Pod
metadata:name: with-toleration
spec:tolerations:- key: node.kubernetes.io/unschedulable #污点的keyoperator: Exists #将会忽略value;只要有key和effect就行effect: NoSchedule #污点的作用
含义是:"容忍"所有被标记为 unschedulable"污点"的 Node;"容忍"的效果是允许调度。可以简单地把"污点"理解为一种特殊的 Label。
正常情况下,被标记了 unschedulable"污点"的 Node,是不会有任何 Pod 被调度上去的(effect: NoSchedule)。可是,DaemonSet 自动地给被管理的 Pod 加上了这个特殊的 Toleration,就使得这些 Pod 可以忽略这个限制,保证每个节点上都会被调度一个 Pod。如果这个节点有故障的话,这个 Pod 可能会启动失败,DaemonSet 会始终尝试下去,直到 Pod 启动成功。
DaemonSet 的"过人之处",其实就是依靠 Toleration 实现的
DaemonSet 是一个控制器。在它的控制循环中,只需要遍历所有节点,然后根据节点上是否有被管理 Pod 的情况,来决定是否要创建或者删除一个 Pod。
更多种类的Toleration
可以在 Pod 模板里加上更多种类的 Toleration,从而利用 DaemonSet 实现自己的目的。
比如,在这个 fluentd-elasticsearch DaemonSet 里,给它加上了这样的 Toleration:
tolerations:
- key: node-role.kubernetes.io/mastereffect: NoSchedule
这是因为在默认情况下,Kubernetes 集群不允许用户在 Master 节点部署 Pod。因为,Master 节点默认携带了一个叫作node-role.kubernetes.io/master的"污点"。所以,为了能在 Master 节点上部署 DaemonSet 的 Pod,就必须让这个 Pod"容忍"这个"污点"。
3.3 DaemonSet实践
3.3.1 创建 DaemonSet 对象
[root@k8s-master set] # kubectl create -f fluentd-elasticsearch.yaml
DaemonSet 上一般都加上 resources 字段,来限制它的 CPU 和内存使用,防止它占用过多的宿主机资源。
创建成功后,如果有 3 个节点,就会有 3 个 fluentd-elasticsearch Pod 在运行
[root@k8s-master set]# kubectl get pod -n kube-system -l name=fluentd-elasticsearch
NAME READY STATUS RESTARTS AGE
fluentd-elasticsearch-6lmnb 1/1 Running 0 21m
fluentd-elasticsearch-9fd7k 1/1 Running 0 21m
fluentd-elasticsearch-vz4n4 1/1 Running 0 21m
3.3.2 查看 DaemonSet 对象
[root@k8s-master set]# kubectl get ds -n kube-system fluentd-elasticsearch
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 3 3 3 3 3 <none> 22m
注:k8s 里比较长的 API 对象都有短名字,比如 DaemonSet 对应的是 ds,Deployment 对应的是 deploy。
3.3.3 DaemonSet 版本管理
[root@k8s-master set]# kubectl rollout history daemonset fluentd-elasticsearch -n kube-system
daemonset.apps/fluentd-elasticsearch
REVISION CHANGE-CAUSE
1 <none>
3.3.4 DaemonSet 的容器镜像版本到 v2.2.0
[root@k8s-master set]# kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=daocloud.io/daocloud/fluentd-elasticsearch:v2.2.0 --record -n=kube-system
daemonset.apps/fluentd-elasticsearch image updated
这个 kubectl set image 命令里,第一个 fluentd-elasticsearch 是 DaemonSet 的名字,第二个 fluentd-elasticsearch 是容器的名字。
--record 参数:
升级使用到的指令会自动出现在 DaemonSet 的 rollout history 里面,如下所示:
[root@k8s-master set]# kubectl rollout history daemonset fluentd-elasticsearch -n kube-system
daemonset.apps/fluentd-elasticsearch
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=daocloud.io/daocloud/fluentd-elasticsearch:v2.2.0 --record=true --namespace=kube-system
有了版本号,也就可以像 Deployment 一样,将 DaemonSet 回滚到某个指定的历史版本了。
相关文章:

Kubernetes 的用法和解析 -- 5
一.企业级镜像仓库Harbo 准备:另起一台新服务器,并配置docker yum源,安装docker 和 docker-compose 1.1 上传harbor安装包并安装 [rootharbor ~]# tar xf harbor-offline-installer-v2.5.3.tgz [rootharbor ~]# cp harbor.yml.tmpl harbor…...
HTML选择题试题——附答案
单选题 HTML的缩写是什么? A) Hyper Tool Markup LanguageB) Hyperlinks and Text Markup LanguageC) Hyper Text Markup LanguageD) Home Tool Markup Language 下列哪个标签用于定义文档的主体内容? A) <head>B) <body>C) <title>D)…...

html之CSS的高级选择器应用
文章目录 一、CSS高级选择器有哪些呢?二、高级选择器的应用1、层次选择器后代选择器子选择器相邻兄弟选择器通用兄弟选择器 2、结构伪类选择器(不常用)3、属性选择器E[attr]E[attrval]E[attr^val]E[attr$val]E[attr*val] 一、CSS高级选择器有…...
elementui+ <el-date-picker type=“datetime“/>时间组件的当前时间的180天之内的禁止选择处理
需求1如下:当前时间180天不可选择,180天之后可以选择,之前的时间都禁止选择 页面代码如下: <el-date-picker v-model"temp.expire_time" :picker-options"pickerOption" type"datetime" placeh…...

全网好听的BGM都在这里下载,赶紧收藏好了
无论是自媒体创作者还是从事视频剪辑工作的朋友,对于BGM的选择都很重要,一首适配的BGM能大大提升你作品的质量,还能让作品更优秀。哪里才能找到好听又免费的BGM?下面推荐几个我多年收藏的6个音效、音频素材网站,赶紧收…...

Spark编程实验一:Spark和Hadoop的安装使用
目录 一、目的与要求 二、实验内容 三、实验步骤 1、安装Hadoop和Spark 2、HDFS常用操作 3、Spark读取文件系统的数据 四、结果分析与实验体会 一、目的与要求 1、掌握在Linux虚拟机中安装Hadoop和Spark的方法; 2、熟悉HDFS的基本使用方法; 3、掌…...

代理和AOP
一:java代理 整体分为两种:静态代理和动态代理 静态代理:23种设计模式里面有个代理模式,那个就是静态代理。 动态代理:分为编译时增强(AspectJ)和运行时增强(JDK动态代理和CGLIB动态代理) 1:静态代理 这种代理在我们日常生活中其…...
Solidity-3-类型
Solidity 是一种静态类型语言,这意味着每个变量(状态变量和局部变量)都需要在编译时指定变量的类型。 “undefined”或“null”值的概念在Solidity中不存在,但是新声明的变量总是有一个 默认值 ,具体的默认值跟类型相…...

【mask转json】文件互转
mask图像转json文件 当只有mask图像时,可使用下面代码得到json文件 import cv2 import os import json import sysdef func(file:str) -> dict:png cv2.imread(file)gray cv2.cvtColor(png, cv2.COLOR_BGR2GRAY)_, binary cv2.threshold(gray,10,255,cv2.TH…...

华清远见嵌入式学习——ARM——作业1
要求: 代码: mov r0,#0 用于加mov r1,#1 初始值mov r2,#101 终止值loop: cmp r1,r2addne r0,r0,r1addne r1,r1,#1bne loop 效果:...

如何在公网环境使用固定域名远程访问内网BUG管理系统协同办公
文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…...
k8s pod网络排查教程
1、背景 背景:在日常的k8s运维中,经常会遇到pod之间网络无法访问,域名无法解释的情况。且容器中网络排查命令不全,导致无法准确定位问题。 2、nsenter介绍 #Centos 下载方式 $ yum install util-linux -ynsenter 是一个 Linux …...
Apollo Planning——换道:LANE_CHANGE_DECIDER
LaneChangeDecider 是lanefollow 场景下,所调用的第一个task,它的作用主要有两点:判断当前是否进行变道,以及变道的状态,并将结果存在变量lane_change_status中;变道过程中将目标车道的reference line放置到…...

Python 爬虫之简单的爬虫(三)
爬取动态网页(上) 文章目录 爬取动态网页(上)前言一、大致内容二、基本思路三、代码编写1.引入库2.加载网页数据3.获取指定数据 总结 前言 之前的两篇写的是爬取静态网页的内容,比较简单。接下来呢给大家讲一下如何去…...

为突发事件提供高现势性数据支撑!大势智慧助力中山市2023应急测绘保障演练举行
12月14日,2023年度中山市应急测绘保障演练在中山树木园举行,市自然资源局总工程师邓宇文出席本次演练活动。来自全市自然资源、应急管理部门和部分测绘单位的近70人现场观摩了演练。本次演练由中山市自然资源局主办、中山市自然资源信息中心承办…...

图片速览 OOD用于零样本 OOD 检测的 CLIPN:教 CLIP 说不
PAPERCODEhttps://arxiv.org/pdf/2308.12213v2.pdfhttps://github.com/xmed-lab/clipn 文章创新 以往由CLIP驱动的零样本OOD检测方法,只需要ID的类名,受到的关注较少。 本文提出了一种新的方法,即CLIP说“不”(CLIPN)…...

a16z:加密行业2024趋势“无缝用户体验”
近日,知名加密投资机构a16z发布了“Big ideas 2024”,列出了加密行业在 2024 年几个具备趋势的“大想法”,其中 Seamless UX(无缝用户体验)赫然在列。 从最为直观的理解上,Seamless UX 是在强调用户在使用产…...

C# WPF上位机开发(属性页面的设计)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 在软件开发中,属性或者参数设置是很重要的一个部分。这个时候如果不想通过动态添加控件的方法来处理的话,那么可以通过tab控…...

macOS 安装 oh-my-zsh 后 node 报错 command not found : node
最近为了让终端中显示 git 分支的名称,安装了 oh-my-zsh ,安装之后呢,我原先安装的 Volta、 node 都没法用了,报错如下: 这时候粗略判断应该是系统变量出了问题,oh-my-zsh 的变量文件是 ~/.zshrc࿰…...
AI 绘画 | Stable Diffusion 视频数字人
前言 本篇文章教会你如何利用Stable Diffusion WEB UI,使用一个人物图片转换成为一个口播视频。本篇内容的教程以WINDOWS系统为例,教你如何安装使用。 先看视频效果 彭于晏图片生成口播视频 安装 首先需要在windows电脑上安装ffmpeg,按照本教程《在 Windows PC 上轻松下载并…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...