K8s中TSL证书如何续期

TSL是什么

image-20241017141303330

K8s中的作用是什么?

在 Kubernetes(K8s)中,TSL 指的是 Transport Layer Security,也就是传输层安全协议。它是用来保护在网络上传输的数据的安全性和隐私性。

TSL 在 Kubernetes 中的作用包括:

  1. 加密通信

    • TSL 确保 Kubernetes 各个组件(如 API Server、etcd、Kubelet 等)之间的通信是加密的,防止未经授权的用户截获敏感信息。
  2. 身份验证

    • TSL 证书被用来对客户端和服务器进行身份验证。Kubernetes 的 API Server 通常会使用 TSL 证书来验证客户端(如 kubectl 或其他服务)的身份,确保只有经过认证的用户或服务才能访问集群资源。
  3. 数据完整性

    • TSL 确保数据在传输过程中不会被篡改。通过加密哈希技术,它可以验证接收到的数据是否与发送时保持一致,防止攻击者在传输过程中修改数据。
  4. 支持 HTTPS

    • Kubernetes API Server 使用 TSL 来支持安全的 HTTPS 连接,而不是不安全的 HTTP。这样确保管理员、开发人员或其他组件通过 API 访问 Kubernetes 时的数据安全性。

总结一下就是:通过使用 TSL,Kubernetes 可以确保集群内的通信安全,防止常见的网络攻击如中间人攻击(MITM)。

K8s中TSL证书的具体使用形式

  1. CA证书(Certificate Authority Certificate):这是用于签发其他证书的根证书。它通常由集群管理员生成,用于签署 Kubernetes 集群中的各类证书,包括 API Server、kubelet 等组件。CA 证书的有效期一般较长(通常为 10 年),主要是因为更换 CA 证书的影响较大,涉及到重新签发和更新集群中所有其他证书的过程,维护成本较高。

  2. API Server证书:API Server 是 Kubernetes 集群中最核心的组件之一,它与客户端(如 kubectl)、其他控制组件(如 kube-scheduler 和 kube-controller-manager),以及集群节点通信时需要使用证书进行身份验证。API Server 证书的默认有效期通常为 1 年,主要是出于以下几个考虑:

    • 安全性:证书的有效期越短,定期轮换越频繁,能够减少密钥泄露或加密算法被攻破的风险。API Server 作为集群中重要的组件,通信和身份验证的安全性极为重要,因此缩短证书有效期能够减少潜在的安全风险。
    • 自动化更新:在现代 Kubernetes 集群中,已经引入了自动证书轮换机制。Kubernetes 会在证书接近过期时自动重新生成并更新证书,因此一年期的证书不会对集群的日常运行造成太大影响。(这块具体对版本的要求是1.8+,具体的详情可以查看一下官网的介绍:https://kubernetes.io/blog/2017/09/kubernetes-18-security-workloads-and/)

image-20241017152926639

K8s中TSL证书如何获取的

在 Kubernetes (K8s) 集群中,证书的生成方式取决于你使用的安装方法和具体的需求。Kubernetes 中的证书主要用于确保集群组件之间的安全通信。通常有两种方式生成和管理证书:自动生成手动生成

1. 自动生成证书

  • Kubeadm安装:如果你使用 kubeadm 进行集群安装,Kubernetes 会自动生成和管理集群组件所需的证书。在集群初始化时,kubeadm 会自动创建一个自签名的 CA(Certificate Authority,证书颁发机构)证书,并基于该 CA 生成 API Server、kubelet、etcd 等组件所需的其他证书。这些证书的默认有效期是预定义的,比如:

    • CA 证书的有效期通常为 10 年
    • 集群组件(如 API Server)的证书默认有效期为 1 年
  • 证书自动轮换:在现代 Kubernetes 版本中,集群组件的证书支持自动轮换。例如,API Server 和其他组件的证书接近过期时,Kubernetes 会自动更新证书,无需手动干预。

2. 手动申请和管理证书

  • 自定义证书:如果你的组织有更严格的安全要求或需要使用外部的证书颁发机构(CA)签发的证书,你可以手动生成和管理 Kubernetes 集群所需的证书。例如,使用 opensslcfssl 来生成你自己的证书并配置它们。
    • 在这种情况下,你需要确保每个 Kubernetes 组件(如 API Server、Controller Manager、Scheduler、kubelet、etcd)都配置好你手动申请的证书。
    • 手动申请证书的过程需要你手动管理证书的颁发、续期和更新,因此维护起来较为复杂。

3. 使用外部 CA

  • 你可以使用组织内部的证书颁发机构(如企业内部的 PKI 基础设施)或公开的 CA 来签发 Kubernetes 组件所需的证书。在这种情况下,你需要将 Kubernetes 中的组件配置为使用由该外部 CA 签发的证书,而不是使用 kubeadm 自动生成的证书。

如何进行续期

查看证书的过期时间

ca证书有效期
openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -text  |grep Not

image-20241017153216317

apiserver证书有效期
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text  |grep Not

image-20241017153303228

如何延长过期时间

**update-kubeadm-cert.sh**文件上传到K8s的Master节点

脚本的下载地址:https://github.com/yuyicai/update-kube-cert

脚本命令

#!/usr/bin/env bashset -o errexit
set -o pipefail
# set -o xtrace# set output color
NC='\033[0m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
# set default cri
CRI="docker"log::err() {printf "[$(date +'%Y-%m-%dT%H:%M:%S.%2N%z')][${RED}ERROR${NC}] %b\n" "$@"
}log::info() {printf "[$(date +'%Y-%m-%dT%H:%M:%S.%2N%z')][INFO] %b\n" "$@"
}log::warning() {printf "[$(date +'%Y-%m-%dT%H:%M:%S.%2N%z')][${YELLOW}WARNING${NC}] \033[0m%b\n" "$@"
}check_file() {if [[ ! -r ${1} ]]; thenlog::err "can not find ${1}"exit 1fi
}# get x509v3 subject alternative name from the old certificate
cert::get_subject_alt_name() {local cert=${1}.crtlocal alt_namecheck_file "${cert}"alt_name=$(openssl x509 -text -noout -in "${cert}" | grep -A1 'Alternative' | tail -n1 | sed 's/[[:space:]]*Address//g')printf "%s\n" "${alt_name}"
}# get subject from the old certificate
cert::get_subj() {local cert=${1}.crtlocal subjcheck_file "${cert}"subj=$(openssl x509 -text -noout -in "${cert}" | grep "Subject:" | sed 's/Subject:/\//g;s/\,/\//;s/[[:space:]]//g')printf "%s\n" "${subj}"
}cert::backup_file() {local file=${1}if [[ ! -e ${file}.old-$(date +%Y%m%d) ]]; thencp -rp "${file}" "${file}.old-$(date +%Y%m%d)"log::info "backup ${file} to ${file}.old-$(date +%Y%m%d)"elselog::warning "does not backup, ${file}.old-$(date +%Y%m%d) already exists"fi
}# check certificate expiration
cert::check_cert_expiration() {local cert=${1}.crtlocal cert_expirescert_expires=$(openssl x509 -text -noout -in "${cert}" | awk -F ": " '/Not After/{print$2}')printf "%s\n" "${cert_expires}"
}# check kubeconfig expiration
cert::check_kubeconfig_expiration() {local config=${1}.conflocal certlocal cert_expirescert=$(grep "client-certificate-data" "${config}" | awk '{print$2}' | base64 -d)cert_expires=$(openssl x509 -text -noout -in <(printf "%s" "${cert}") | awk -F ": " '/Not After/{print$2}')printf "%s\n" "${cert_expires}"
}# check etcd certificates expiration
cert::check_etcd_certs_expiration() {local certlocal certscerts=("${ETCD_CERT_CA}""${ETCD_CERT_SERVER}""${ETCD_CERT_PEER}""${ETCD_CERT_HEALTHCHECK_CLIENT}""${ETCD_CERT_APISERVER_ETCD_CLIENT}")for cert in "${certs[@]}"; doif [[ ! -r ${cert} ]]; thenprintf "%-50s%-30s\n" "${cert}.crt" "$(cert::check_cert_expiration "${cert}")"fidone
}# check master certificates expiration
cert::check_master_certs_expiration() {local certslocal kubeconfslocal certlocal confcerts=("${CERT_CA}""${CERT_APISERVER}""${CERT_APISERVER_KUBELET_CLIENT}""${FRONT_PROXY_CA}""${FRONT_PROXY_CLIENT}")# add support for super_admin.conf, which was added after k8s v1.30.if [ -f "${CONF_SUPER_ADMIN}.conf" ]; thenkubeconfs=("${CONF_CONTROLLER_MANAGER}""${CONF_SCHEDULER}""${CONF_ADMIN}""${CONF_SUPER_ADMIN}")else kubeconfs=("${CONF_CONTROLLER_MANAGER}""${CONF_SCHEDULER}""${CONF_ADMIN}")fiprintf "%-50s%-30s\n" "CERTIFICATE" "EXPIRES"for conf in "${kubeconfs[@]}"; doif [[ ! -r ${conf} ]]; thenprintf "%-50s%-30s\n" "${conf}.config" "$(cert::check_kubeconfig_expiration "${conf}")"fidonefor cert in "${certs[@]}"; doif [[ ! -r ${cert} ]]; thenprintf "%-50s%-30s\n" "${cert}.crt" "$(cert::check_cert_expiration "${cert}")"fidone
}# check all certificates expiration
cert::check_all_expiration() {cert::check_master_certs_expirationcert::check_etcd_certs_expiration
}# generate certificate whit client, server or peer
# Args:
#   $1 (the name of certificate)
#   $2 (the type of certificate, must be one of client, server, peer)
#   $3 (the subject of certificates)
#   $4 (the validity of certificates) (days)
#   $5 (the name of ca)
#   $6 (the x509v3 subject alternative name of certificate when the type of certificate is server or peer)
cert::gen_cert() {local cert_name=${1}local cert_type=${2}local subj=${3}local cert_days=${4}local ca_name=${5}local alt_name=${6}local ca_cert=${ca_name}.crtlocal ca_key=${ca_name}.keylocal cert=${cert_name}.crtlocal key=${cert_name}.keylocal csr=${cert_name}.csrlocal common_csr_conf='distinguished_name = dn\n[dn]\n[v3_ext]\nkeyUsage = critical, digitalSignature, keyEncipherment\n'for file in "${ca_cert}" "${ca_key}" "${cert}" "${key}"; docheck_file "${file}"donecase "${cert_type}" inclient)csr_conf=$(printf "%bextendedKeyUsage = clientAuth\n" "${common_csr_conf}");;server)csr_conf=$(printf "%bextendedKeyUsage = serverAuth\nsubjectAltName = %b\n" "${common_csr_conf}" "${alt_name}");;peer)csr_conf=$(printf "%bextendedKeyUsage = serverAuth, clientAuth\nsubjectAltName = %b\n" "${common_csr_conf}" "${alt_name}");;*)log::err "unknow, unsupported certs type: ${YELLOW}${cert_type}${NC}, supported type: client, server, peer"exit 1;;esac# gen csropenssl req -new -key "${key}" -subj "${subj}" -reqexts v3_ext \-config <(printf "%b" "${csr_conf}") \-out "${csr}" >/dev/null 2>&1# gen certopenssl x509 -in "${csr}" -req -CA "${ca_cert}" -CAkey "${ca_key}" -CAcreateserial -extensions v3_ext \-extfile <(printf "%b" "${csr_conf}") \-days "${cert_days}" -out "${cert}" >/dev/null 2>&1rm -f "${csr}"
}cert::update_kubeconf() {local cert_name=${1}local kubeconf_file=${cert_name}.conflocal cert=${cert_name}.crtlocal key=${cert_name}.keylocal subjlocal cert_base64check_file "${kubeconf_file}"# get the key from the old kubeconfgrep "client-key-data" "${kubeconf_file}" | awk '{print$2}' | base64 -d >"${key}"# get the old certificate from the old kubeconfgrep "client-certificate-data" "${kubeconf_file}" | awk '{print$2}' | base64 -d >"${cert}"# get subject from the old certificatesubj=$(cert::get_subj "${cert_name}")cert::gen_cert "${cert_name}" "client" "${subj}" "${CERT_DAYS}" "${CERT_CA}"# get certificate base64 codecert_base64=$(base64 -w 0 "${cert}")# set certificate base64 code to kubeconfsed -i 's/client-certificate-data:.*/client-certificate-data: '"${cert_base64}"'/g' "${kubeconf_file}"rm -f "${cert}"rm -f "${key}"
}cert::update_etcd_cert() {local subjlocal subject_alt_namelocal cert# generate etcd server,peer certificate# /etc/kubernetes/pki/etcd/server# /etc/kubernetes/pki/etcd/peerfor cert in ${ETCD_CERT_SERVER} ${ETCD_CERT_PEER}; dosubj=$(cert::get_subj "${cert}")subject_alt_name=$(cert::get_subject_alt_name "${cert}")cert::gen_cert "${cert}" "peer" "${subj}" "${CERT_DAYS}" "${ETCD_CERT_CA}" "${subject_alt_name}"log::info "${GREEN}updated ${BLUE}${cert}.conf${NC}"done# generate etcd healthcheck-client,apiserver-etcd-client certificate# /etc/kubernetes/pki/etcd/healthcheck-client# /etc/kubernetes/pki/apiserver-etcd-clientfor cert in ${ETCD_CERT_HEALTHCHECK_CLIENT} ${ETCD_CERT_APISERVER_ETCD_CLIENT}; dosubj=$(cert::get_subj "${cert}")cert::gen_cert "${cert}" "client" "${subj}" "${CERT_DAYS}" "${ETCD_CERT_CA}"log::info "${GREEN}updated ${BLUE}${cert}.conf${NC}"done# restart etcdcase $CRI in"docker")docker ps | awk '/k8s_etcd/{print$1}' | xargs -r -I '{}' docker restart {} >/dev/null 2>&1 || true;;"containerd")crictl ps | awk '/etcd-/{print$(NF-1)}' | xargs -r -I '{}' crictl stopp {} >/dev/null 2>&1 || true;;esaclog::info "restarted etcd with ${CRI}"
}cert::update_master_cert() {local subjlocal subject_alt_namelocal conf# generate apiserver server certificate# /etc/kubernetes/pki/apiserversubj=$(cert::get_subj "${CERT_APISERVER}")subject_alt_name=$(cert::get_subject_alt_name "${CERT_APISERVER}")cert::gen_cert "${CERT_APISERVER}" "server" "${subj}" "${CERT_DAYS}" "${CERT_CA}" "${subject_alt_name}"log::info "${GREEN}updated ${BLUE}${CERT_APISERVER}.crt${NC}"# generate apiserver-kubelet-client certificate# /etc/kubernetes/pki/apiserver-kubelet-clientsubj=$(cert::get_subj "${CERT_APISERVER_KUBELET_CLIENT}")cert::gen_cert "${CERT_APISERVER_KUBELET_CLIENT}" "client" "${subj}" "${CERT_DAYS}" "${CERT_CA}"log::info "${GREEN}updated ${BLUE}${CERT_APISERVER_KUBELET_CLIENT}.crt${NC}"# generate kubeconf for controller-manager,scheduler and kubelet# /etc/kubernetes/controller-manager,scheduler,admin,kubelet.conf,super_admin(added after k8s v1.30.)if [ -f "${CONF_SUPER_ADMIN}.conf" ]; thenconf_list="${CONF_CONTROLLER_MANAGER} ${CONF_SCHEDULER} ${CONF_ADMIN} ${CONF_KUBELET} ${CONF_SUPER_ADMIN}"else conf_list="${CONF_CONTROLLER_MANAGER} ${CONF_SCHEDULER} ${CONF_ADMIN} ${CONF_KUBELET}"fifor conf in ${conf_list}; doif [[ ${conf##*/} == "kubelet" ]]; then# https://github.com/kubernetes/kubeadm/issues/1753set +egrep kubelet-client-current.pem /etc/kubernetes/kubelet.conf >/dev/null 2>&1kubelet_cert_auto_update=$?set -eif [[ "$kubelet_cert_auto_update" == "0" ]]; thenlog::info "does not need to update kubelet.conf"continuefifi# update kubeconfcert::update_kubeconf "${conf}"log::info "${GREEN}updated ${BLUE}${conf}.conf${NC}"# copy admin.conf to ${HOME}/.kube/configif [[ ${conf##*/} == "admin" ]]; thenmkdir -p "${HOME}/.kube"local config=${HOME}/.kube/configlocal config_backupconfig_backup=${HOME}/.kube/config.old-$(date +%Y%m%d)if [[ -f ${config} ]] && [[ ! -f ${config_backup} ]]; thencp -fp "${config}" "${config_backup}"log::info "backup ${config} to ${config_backup}"ficp -fp "${conf}.conf" "${HOME}/.kube/config"log::info "copy the admin.conf to ${HOME}/.kube/config"fidone# generate front-proxy-client certificate# /etc/kubernetes/pki/front-proxy-clientsubj=$(cert::get_subj "${FRONT_PROXY_CLIENT}")cert::gen_cert "${FRONT_PROXY_CLIENT}" "client" "${subj}" "${CERT_DAYS}" "${FRONT_PROXY_CA}"log::info "${GREEN}updated ${BLUE}${FRONT_PROXY_CLIENT}.crt${NC}"# restart apiserver, controller-manager, scheduler and kubeletfor item in "apiserver" "controller-manager" "scheduler"; docase $CRI in"docker")docker ps | awk '/k8s_kube-'${item}'/{print$1}' | xargs -r -I '{}' docker restart {} >/dev/null 2>&1 || true;;"containerd")crictl ps | awk '/kube-'${item}'-/{print $(NF-1)}' | xargs -r -I '{}' crictl stopp {} >/dev/null 2>&1 || true;;esaclog::info "restarted ${item} with ${CRI}"donesystemctl restart kubelet || truelog::info "restarted kubelet"
}main() {local node_type=$1# read the optionsARGS=`getopt -o c: --long cri: -- "$@"`eval set -- "$ARGS"# extract options and their arguments into variables.while truedocase "$1" in-c|--cri)case "$2" in"docker"|"containerd")CRI=$2shift 2;;*)echo 'Unsupported cri. Valid options are "docker", "containerd".'exit 1;;esac;;--)shiftbreak;;*)echo "Invalid arguments."exit 1;;esacdoneCERT_DAYS=3650KUBE_PATH=/etc/kubernetesPKI_PATH=${KUBE_PATH}/pki# master certificates path# apiserverCERT_CA=${PKI_PATH}/caCERT_APISERVER=${PKI_PATH}/apiserverCERT_APISERVER_KUBELET_CLIENT=${PKI_PATH}/apiserver-kubelet-clientCONF_CONTROLLER_MANAGER=${KUBE_PATH}/controller-managerCONF_SCHEDULER=${KUBE_PATH}/schedulerCONF_ADMIN=${KUBE_PATH}/adminCONF_SUPER_ADMIN=${KUBE_PATH}/super-adminCONF_KUBELET=${KUBE_PATH}/kubelet# front-proxyFRONT_PROXY_CA=${PKI_PATH}/front-proxy-caFRONT_PROXY_CLIENT=${PKI_PATH}/front-proxy-client# etcd certificates pathETCD_CERT_CA=${PKI_PATH}/etcd/caETCD_CERT_SERVER=${PKI_PATH}/etcd/serverETCD_CERT_PEER=${PKI_PATH}/etcd/peerETCD_CERT_HEALTHCHECK_CLIENT=${PKI_PATH}/etcd/healthcheck-clientETCD_CERT_APISERVER_ETCD_CLIENT=${PKI_PATH}/apiserver-etcd-clientcase ${node_type} in# etcd)# # update etcd certificates#   cert::update_etcd_cert# ;;master)# check certificates expirationcert::check_master_certs_expiration# backup $KUBE_PATH to $KUBE_PATH.old-$(date +%Y%m%d)cert::backup_file "${KUBE_PATH}"# update master certificates and kubeconflog::info "${GREEN}updating...${NC}"cert::update_master_certlog::info "${GREEN}done!!!${NC}"# check certificates expiration after certificates updatedcert::check_master_certs_expiration;;all)# check certificates expirationcert::check_all_expiration# backup $KUBE_PATH to $KUBE_PATH.old-$(date +%Y%m%d)cert::backup_file "${KUBE_PATH}"# update etcd certificateslog::info "${GREEN}updating...${NC}"cert::update_etcd_cert# update master certificates and kubeconfcert::update_master_certlog::info "${GREEN}done!!!${NC}"# check certificates expiration after certificates updatedcert::check_all_expiration;;check)# check certificates expirationcert::check_all_expiration;;*)log::err "unknown, unsupported cert type: ${node_type}, supported type: \"all\", \"master\""printf "Documentation: https://github.com/yuyicai/update-kube-certexample:'\033[32m./update-kubeadm-cert.sh all\033[0m' update all etcd certificates, master certificates and kubeconf/etc/kubernetes├── admin.conf├── super-admin.conf├── controller-manager.conf├── scheduler.conf├── kubelet.conf└── pki├── apiserver.crt├── apiserver-etcd-client.crt├── apiserver-kubelet-client.crt├── front-proxy-client.crt└── etcd├── healthcheck-client.crt├── peer.crt└── server.crt'\033[32m./update-kubeadm-cert.sh master\033[0m' update only master certificates and kubeconf/etc/kubernetes├── admin.conf├── super-admin.conf├── controller-manager.conf├── scheduler.conf├── kubelet.conf└── pki├── apiserver.crt├── apiserver-kubelet-client.crt└── front-proxy-client.crt
"exit 1;;esac
}main "$@"

image-20241017153706770

Master节点执行相应脚本
# 给update-kubeadm-cert.sh证书授权可执行权限
chmod +x update-kubeadm-cert.sh

image-20241017153757134

# 执行下面命令,修改证书过期时间,把时间延长到10年
./update-kubeadm-cert.sh all

image-20241017153900671

查询是否签发正常
# 在k8s-master1节点查询Pod是否正常,能查询出数据说明证书签发完成
kubectl get pods -n kube-system

image-20241017154042877

进一步确认是否延期成功
#  查看apiserver证书
[root@master01 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text  |grep NotNot Before: Oct 17 07:38:48 2024 GMTNot After : Oct 15 07:38:48 2034 GMT
您在 /var/spool/mail/root 中有新邮件
# 查看etcd证书
[root@master01 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt  -noout -text  |grep NotNot Before: Oct 17 07:38:48 2024 GMTNot After : Oct 15 07:38:48 2034 GMT
# 查看fron-proxy证书
[root@master01 ~]# openssl x509 -in /etc/kubernetes/pki/front-proxy-ca.crt  -noout -text  |grep NotNot Before: Sep 10 07:54:00 2024 GMTNot After : Sep  8 07:54:00 2034 GMT

image-20241017154247287

致谢

参考文章:

https://www.cnblogs.com/hujinzhong/p/14985449.html

https://blog.csdn.net/weixin_45248492/article/details/139200457?spm=1001.2014.3001.5506

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

铜业机器人剥片 - SNK施努卡

SNK施努卡有色行业电解车间铜业机器人剥片 铜业机器人剥片技术是针对传统人工剥片效率低下、工作环境恶劣及生产质量不稳定的痛点而发展起来的自动化解决方案。 面临人工剥片的诸多挑战&#xff0c;包括低效率、工作环境差、人员流动大以及产品质量控制不精确等问题。 人工剥片…

OSPF特殊区域及其他特性

不用的链路这状态信息没必要一直保存&#xff0c;要不路由器承受不了。用OSPF 特殊区域解决 1. Stub区域和Totally Stub区域 R1作为ASBR引入多个外部网段&#xff0c;如果Area 2是普通区域&#xff0c;则R3将向该区域注入5类和4类LSA。 当把Area 2配置为Stub区域后&#xff1a…

51单片机之蜂鸣器驱动

1.简介 蜂鸣器是一种一体化结构的电子讯响器&#xff0c;采用直流电压供电&#xff0c;广泛应用于计算机、打印机、 复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。   压电式蜂鸣器主要…

Linux练习_2账户管理

题目描述1 建立用户组 [rootlocalhost ~]# groupadd -g 2000 shengchan [rootlocalhost ~]# groupadd -g 2001 caiwu [rootlocalhost ~]# groupadd -g 2002 jishu [rootlocalhost ~]# tail -3 /etc/group shengchan:x:2000: caiwu:x:2001: jishu:x:2002: [rootlocalhost ~]# 建…

【IC每日一题】

IC每日一题 1 组合逻辑VS时序逻辑1.1 组合逻辑1.1.1 竞争冒险1.1.2 解决方法 1.2 时序逻辑1.3 比较1.4 场景 2 计数器2.1 代码片段法2.2 实现计数器--异步复位&#xff0c;带clear端&#xff0c;计10则归0&#xff1b; 1 组合逻辑VS时序逻辑 1.1 组合逻辑 组合逻辑&#xff1…

SSM-Springboot笔记(2)- SpringBoot常用开发技能

1 SpringBoot常用开发技能 1.1 项目架构 创建项⽬配置启动类建⽴对应的包&#xff0c;先建⽴这些包&#xff0c;其他⽤到再补充 controller service mapper domain utils1.2 开发HTTP接⼝GET请求 GET请求 场景&#xff1a;⼀般的查询接⼝就是get请求 注解&#xff1a;GetMappin…

Android在kts中使用navigation及Args

Android在kts中使用navigation及Args 前言&#xff1a; ​ 之前在项目中使用过navigation&#xff0c;但都是以Groory的方式&#xff0c;最近一年多使用kts后忍不住把项目都改成kts的方式&#xff0c;不过其中也遇到不少坑&#xff0c;今天就讲解一下如何在kts中使用navigati…

MyBatis缓存详解(一级缓存、二级缓存、缓存查询顺序)

固态硬盘缺陷&#xff1a;无法长时间使用&#xff0c;而磁盘只要不消磁&#xff0c;只要不受到磁影响&#xff0c;就可以长期使用&#xff0c;因此绝大多数企业还是使用磁盘来存储数据 像mysql这种关系型数据库中的数据存储在磁盘中&#xff0c;为方便查询&#xff0c;减少系统…

springboot襄阳华侨城奇幻度假区服务平台-计算机毕业设计源码93560

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3 开发技术 1.3.1 B/S架构 1.3.2 Spring Boot框架 1.3.3 Java语言 1.3.4 MySQL数据库 1.4论文章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 登录流程 2.2.2数据删除流程 2.3 系统…

2024年好用不踩雷的8款图纸加密软件推荐!CAD图纸加密软件!

在2024年&#xff0c;随着信息安全需求的提升&#xff0c;特别是对于设计、建筑、制造等行业的CAD图纸保护&#xff0c;图纸加密软件的选择尤为重要。以下推荐了8款优质的CAD图纸加密软件&#xff0c;这些软件不仅提供了强大的加密功能&#xff0c;还在易用性和兼容性方面表现出…

创新业态下金融头部机构在 FICC 平台建设上的思考与实践

近年来&#xff0c;FICC 投资交易呈现活跃多元态势&#xff0c;创新转型稳步推进。FICC 平台电子化方兴未艾&#xff0c;是机构提升服务效率和质量的一大着力点。因此&#xff0c;在 FICC 平台建设上&#xff0c;许多机构都进行了深入研究&#xff0c;积累了丰富的实践经验。 …

MongoDB快速入门

MongoDB 概念 什么是 MongoDB MongoDB 是在2007年由DoubleClick公司的几位核心成员开发出的一款分布式文档数据库&#xff0c;由C语言编写。 目的是为了解决数据大量增长的时候系统的可扩展性和敏捷性。MongoDB要比传统的关系型数据库简单很多。 在MongoDB中数据主要的组织…

Spring boot 配置文件的加载顺序

Spring Boot 在启动时会扫描以下位置的 application.properties 或者 application.yml 文件作为全局配置文件&#xff1a; –file:./config/–file:./–classpath:/config/–classpath:/以下是按照优先级从高到低的顺序&#xff0c;如下所示&#xff1a; Spring Boot 会全部扫…

医院信息化与智能化系统(10)

医院信息化与智能化系统(10) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…

自由学习记录(15)

Java注解 else if的省略问题&#xff08;可能看花&#xff09; else if也是取最近的if连通&#xff0c;看上去加了{}就可以正常执行了&#xff0c;缩进要命&#xff0c;不提示真容易看错&#xff0c; 组合数公式和数组参数 在 C 中&#xff0c;数组作为函数参数时&#xff0c;…

【课件分享】蓝光光盘及光驱团标解读

关注我们 - 数字罗塞塔计划 - 10月26日&#xff0c;非常感谢陶光毅老师携特邀嘉宾许斌老师和游泳总能够在百忙之中抽空莅临数字罗塞塔计划直播间&#xff0c;为大家带来蓝光光盘及光驱团标解读。作为标准的起草者&#xff0c;你们的专业见解和宝贵经验&#xff0c;让我们对T/CE…

Lucas带你手撕机器学习——SVM支持向量机

#1024程序员节&#xff5c;征文# 支持向量机&#xff08;SVM&#xff09;的详细讲解 什么是SVM&#xff1f; 支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种用于分类和回归的监督学习算法。它的主要任务是从给定的数据中找到一个最佳的决策…

Windows/Linux(服务器)查看显卡的名称

文章目录 1. 使用 nvidia-smi&#xff08;适用于 NVIDIA 显卡&#xff09;2. 使用 wmic 命令&#xff08;Windows&#xff09; 1. 使用 nvidia-smi&#xff08;适用于 NVIDIA 显卡&#xff09; 如果服务器上安装了 NVIDIA 驱动程序&#xff0c;可以使用 nvidia-smi 工具来查看…

vue使用xlsx以及file-saver进行下载xlsx文件以及Unit8Array、ArrayBuffer、charCodeAt的使用

先说Unit8Array、ArrayBuffer、charCodeAt的使用下面会用到这三个 Unit8Array&#xff1a;数组类型表示一个 8 位无符号整型数组&#xff0c;创建时内容被初始化为 0。创建完后&#xff0c;可以以对象的方式或使用数组下标索引的方式引用数组中的元素。 new Uint8Array(); //…

Docker中如何控制服务启动顺序实现探讨

文章目录 一、Docker概述二、Docker三剑客1. Compose2. Machine3. Swarm 三、简要需求1. 样例工程2. 代码模块3. 调用方向4. 期望启动顺序 四、思路分析1.各走各路1.&#xff09;docker-compose -f指定不同配置文件2.&#xff09;docker-compose up -d service-name指定服务名3…