k8s快速入门
文章目录
- 一、Kubernetes(K8S)简介
- 1、概念
- 1.1 Kubernetes (K8S) 是什么
- 1.2 核心特性
- 1.3 部署方案
- 2、Kubernetes 集群架构
- 2.1 架构
- 2.2 重要概念 Pod
- 2.3 Kubernetes 组件
- 二、Kubernetes集群安装
- 1、安装方式介绍
- 2、minikubute安装
- 3、裸机搭建(Bare Metal)
- 3.1 概念介绍
- 3.2 集群安装
- 3.3 踩坑之路
- 4、快速体验
- 5、可视化安装
- 5.1 Kuboard v2 - kubernetes(推荐)
- 5.2 Kubernetes Dashboard
- 三、集群服务部署
- 1、部署应用Demo
- 2、常用命令详情
- 3、概念
- 3.1 工作负载分类
- 3.2 存在问题
- 四、Service
- 1、概念
- 2、Service简单Demo
- 3、对外暴露服务(重要)
- 4、多端口
- 5、总结
- 五、StatefulSet
- 1、StatefulSet介绍
- 1.1 概念
- 1.2 特性
- 2、部署 StatefulSet 类型的 Mongodb
- 六、数据持久化
- 1、概念
- 2、hostPath 挂载示例
- 3、高级抽象挂载
- 3.1 概述
- 3.2 各个层级表述
- 3.3 本地测试
- 七、ConfigMap & Secret
- 1、概述
- 2、ConfigMap
- 3、Secret
- 4、Demo使用
- 八、Helm & 命名空间
- 1、简介
- 2、Helm安装
- 3、安装MongoDb
- 4、命名空间
- 九、Ingress
- 1、介绍
- 2、使用
一、Kubernetes(K8S)简介
1、概念
官网:https://kubernetes.io/zh-cn/docs/home/
1.1 Kubernetes (K8S) 是什么
它是一个为 容器化 应用提供集群部署和管理的开源工具,由 Google 开发。K8S 是负责自动化运维管理多个跨机器 Docker 程序的集群
1.2 核心特性
- 服务发现与负载均衡:无需修改你的应用程序即可使用陌生的服务发现机制
- 存储编排:自动挂载所选存储系统,包括本地存储
- Secret和配置管理:部署更新Secrets和应用程序的配置时不必重新构建容器镜像,且不必将软件堆栈配置中的秘密信息暴露出来
- 批量执行:除了服务之外,Kubernetes还可以管理你的批处理和CI工作负载,在期望时替换掉失效的容器
- 水平扩缩:使用一个简单的命令、一个UI或基于CPU使用情况自动对应用程序进行扩缩
- 自动化上线和回滚:Kubernetes会分步骤地将针对应用或其配置的更改上线,同时监视应用程序运行状况以确保你不会同时终止所有实例
- 自动装箱:根据资源需求和其他约束自动放置容器,同时避免影响可用性
- 自我修复:重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器
1.3 部署方案
传统部署方式
应用直接在物理机上部署,机器资源分配不好控制,出现Bug时,可能机器的大部分资源被某个应用占用,导致其他应用无法正常运行,无法做到应用隔离
虚拟机部署
在单个物理机上运行多个虚拟机,每个虚拟机都是完整独立的系统,性能损耗大
容器部署
所有容器共享主机的系统,轻量级的虚拟机,性能损耗小,资源隔离,CPU和内存可按需分配;例如k8s可以轻松管理百万千万台机器的集群,可以为你提供集中式的管理集群机器和应用,不停机的灰度更新,确保高可用、高性能、高扩展
2、Kubernetes 集群架构
2.1 架构
-
master
主节点,控制平台,不需要很高性能,不跑任务,通常一个就行了,也可以开多个主节点来提高集群可用度。
-
worker
工作节点,可以是虚拟机或物理计算机,任务都在这里跑,机器性能需要好点;通常都有很多个,可以不断加机器扩大集群;每个工作节点由主节点管理
2.2 重要概念 Pod
K8S 调度、管理的最小单位,一个 Pod 可以包含一个或多个容器,每个 Pod 有自己的虚拟IP。一个工作节点可以有多个 pod,主节点会考量负载自动调度 pod 到哪个节点运行
2.3 Kubernetes 组件
kube-apiserver
K8S 的请求入口服务。API Server 负责接收 K8S 所有请求(来自 UI 界面或者 CLI 命令行工具),然后,API Server 根据用户的具体请求,去通知其他组件干活etcd
K8S 的存储服务。etcd 存储了 K8S 的关键配置和用户配置,K8S 中仅 API Server 才具备读写权限,其他组件必须通过 API Server 的接口才能读写数据kube-scheduler
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 重新部署服务cloud-controller
与云服务商交互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运行环境
二、Kubernetes集群安装
默认已经提前安装好Docker,docker安装可以参考:docker学习笔记
1、安装方式介绍
-
minikube
只是一个 K8S 集群模拟器,只有一个节点的集群,只为测试用,master 和 worker 都在一起
-
直接用云平台 Kubernetes (阿里/腾讯)
可视化搭建,只需简单几步就可以创建好一个集群。
优点:安装简单,生态齐全,负载均衡器、存储等都给你配套好,简单操作就搞定
-
裸机安装(Bare Metal)
至少需要两台机器(主节点、工作节点个一台),需要自己安装 Kubernetes 组件,配置会稍微麻烦点。
可以到各云厂商按时租用服务器,费用低,用完就销毁。
缺点:配置麻烦,缺少生态支持,例如负载均衡器、云存储。
2、minikubute安装
官网安装:https://minikube.sigs.k8s.io/docs/start/
Minikube:搭建部署单机 Kubernetes
minikube安装非常简单,支持各种平台,建议直接裸机(个人虚拟机安装一直有问题)
# 启动集群,据说不加版本会报错(我还是启动不了)
minikube start --kubernetes-version=v1.23.0
# 查看节点。kubectl 是一个用来跟 K8S 集群进行交互的命令行工具
kubectl get node
# 停止集群
minikube stop
# 清空集群
minikube delete --all
# 安装集群可视化 Web UI 控制台
minikube dashboard
minikube和云平台不多赘述,例如腾讯云的弹性容器服务 EKS,这里主要讲述逻辑集群的安装
3、裸机搭建(Bare Metal)
k8s集群搭建参考:https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/nd7yOvdY#nav_3
3.1 概念介绍
主节点需要组件
- docker(也可以是其他容器运行时)
- kubectl 集群命令行交互工具
- kubeadm 集群初始化工具
**工作节点需要组件 **文档
- docker(也可以是其他容器运行时)
- kubelet 管理 Pod 和容器,确保他们健康稳定运行
- kube-proxy 网络代理,负责网络相关的工作
3.2 集群安装
这里我基于centos7创建了三台虚拟机(2核4G,网络使用nat),以下是所有节点的配置,权限不够的话使用sudo提升权限
# 每个节点分别设置对应主机名
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2# 所有节点都修改 hosts
vim /etc/hosts
192.168.249.241 node1
192.168.249.242 node2
192.168.249.240 master# 所有节点关闭 SELinux
# 临时关闭
setenforce 0
# 永久关闭
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
# 查看selinux状态
getenforce# k8s不需要swap分区,如果安装Linux系统时创建了swap分区,那么就需要禁用swap
# 临时关闭swap分区
swapoff -a
# 修改配置文件永久关闭swap分区 ,或者vim /etc/fstab 删除或注释掉带有swap的行
sed -ri 's/.*swap.*/#&/' /etc/fstab# 所有节点确保防火墙关闭,确保网络通信
systemctl stop firewalld
systemctl disable firewalld# 设置时间同步
sudo yum install ntpdate -y
sudo ntpdate time.windows.com# 添加 k8s 安装源
cat <<EOF > kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
mv kubernetes.repo /etc/yum.repos.d/# 添加 Docker 安装源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 安装所需组件(所有节点)
yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 docker-ce# 启动 kubelet、docker,并设置开机启动
systemctl enable kubelet
systemctl start kubelet
systemctl enable docker
systemctl start docker# 修改 docker 配置
# kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了
cat <<EOF > daemon.json
{"exec-opts": ["native.cgroupdriver=systemd"],"registry-mirrors": ["https://ud6340vz.mirror.aliyuncs.com"]
}
EOF
mv daemon.json /etc/docker/
# 重启生效
systemctl daemon-reload
systemctl restart docker
在主节点master初始化集群,init的文档
# 初始化集群控制台 Control plane
# 失败了可以用 sudo kubeadm reset 重置
# 这里记得加上子网分配,教程不加也可以,可以试试
sudo kubeadm init --image-repository=registry.aliyuncs.com/google_containers --pod-network-cidr 10.244.0.0/16
#sudo kubeadm init --apiserver-advertise-address=192.168.249.139 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16
# 记得把 kubeadm join xxx 保存起来
# 忘记了重新获取:kubeadm token create --print-join-command# 复制授权文件,以便 kubectl 可以有权限访问集群
# 如果你其他节点需要访问集群,需要从主节点复制这个文件过去其他节点
# 如果是普通用户
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config# 如果是root用户
export KUBECONFIG=/etc/kubernetes/admin.conf# 在其他机器上创建 ~/.kube/config 文件也能通过 kubectl 访问到集群# 如果node节点添加进集群失败,可以删除节点重新添加
# 要删除 node1 这个节点,首先在 master 节点上依次执行以下两个命令
kubectl drain node1 --delete-local-data --force --ignore-daemonsets
kubectl delete node node1
# 执行后通过 kubectl get node 命令可以看到 node1 已被成功删除,接着在 k8snode1 这个 Node 节点上执行如下命令,这样该节点即完全从 k8s 集群中脱离开来,之后就可以重新执行命令添加到集群
kubeadm reset
然后把工作节点加入集群(只在工作节点跑)
sudo kubeadm join 192.168.249.140:6443 --token 5f20z7.9rbjijmnkhpz0sj2 \--discovery-token-ca-cert-hash sha256:b6b6b1d84ca8a0711667d654e8a676c0e17703715c5b16074896eecedbf8ca01
最后安装网络插件,否则 node 是 NotReady 状态(主节点跑)
# 查看状态
kubectl get nodes
# 网络插件,用来结点通信的,
# 很有可能国内网络访问不到这个资源,你可以网上找找国内的源安装 flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 这里一个方法是进入该网站手动讲内容复制下来,把内容保存到linux中命名kube-flannel.yml
https://github.com/flannel-io/flannel/blob/master/Documentation/kube-flannel.yml
# 执行
kubectl apply -f kube-flannel.yml
3.3 踩坑之路
首先了解一下基本的命令
# 查看所有的详细信息
kubectl get pod -A -owide
# 查看某一个容器详细运行状态,-n后跟的是命名空间,排查错误用
kubectl describe pod kube-flannel-ds-wclwt -n kube-flannel
# 查看日志
kubectl logs -f --tail 200 -n kube-flannel kube-flannel-ds-5bmpl
问题一
手动导入网络插件后通过查看日志发现镜像无法拉取,于是手动拉取导入,然后用tag打上与yml文件中的镜像一模一样的名字,这里我每个结点都是这样操作(按理说会自动同步过去其他结点,但是每个结点都报错了,所以我手动下载了;当然换个国内源也可以)
# 下载地址
https://github.com/flannel-io/flannel
# 比如yml中写的是docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0,首先下载对应的包
docker load < flanneld-v0.20.0-amd64.docker
# 查看一下
sudo docker images
# 找到对应的镜像打上对应标签
sudo docker tag quay.io/coreos/flannel:v0.20.0-amd64 docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0
问题二
手动下载后,查看describe日志发现能成功拉去镜像,但是容器无法启动,查看logs日志发现说没有分配子网podCIDR,通过kubeadm init初始化master节点时,flannel网络插件需要确保初始化命令配置了podCIDR如下启动参数,–pod-network-cidr=172.18.0.0/16
参考:k8s集群flannel部署错误异常排查:pod cidr not assigned
问题三
如果你运行 kubectl describe pod/pod-name
发现 Events 中有下面这个错误networkPlugin cni failed to set up pod "test-k8s-68bb74d654-mc6b9_default" network: open /run/flannel/subnet.env: no such file or directory
那么在每个节点创建文件/run/flannel/subnet.env
写入以下内容,配置后等待一会就好了(用来配置每个结点的子网信息)
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
4、快速体验
# 创建一次deployment部署
kubectl create deployment nginx --image=nginx
kubectl get deployment
kubectl get pod
# 创建service(端口映射)
kubectl expose deployment nginx --port=80 --type=NodePortkubectl get pod,svc -o wide
# 访问Nginx地址: http://任意节点的ip:图中Nginx的对外映射端口,http://192.168.249.240:30433# 删除pod和service(端口映射)
kubectl delete deployment nginx
kubectl delete svc/nginx
5、可视化安装
5.1 Kuboard v2 - kubernetes(推荐)
参考:安装 Kuboard v2
# 安装 Kuboard
kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml
kubectl apply -f https://addons.kuboard.cn/metrics-server/0.3.7/metrics-server.yaml
# 查看运行状态
kubectl get pods -l k8s.kuboard.cn/name=kuboard -n kube-system# 获取管理员token
echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep ^kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)#Kuboard Service 使用了 NodePort 的方式暴露服务,NodePort 为 32567;您可以按如下方式访问 Kuboard。
# http://任意一个Worker节点的IP地址:32567/
5.2 Kubernetes Dashboard
参考:Kubernetes Dashboard安装/部署和访问 Kubernetes 仪表板(Dashboard)
Kubernetes Dashboard 是 Kubernetes 的官方 Web UI。使用 Kubernetes Dashboard可以
- 向 Kubernetes 集群部署容器化应用
- 诊断容器化应用的问题
- 管理集群的资源
- 查看集群上所运行的应用程序
- 创建、修改Kubernetes 上的资源(例如 Deployment、Job、DaemonSet等)
- 展示集群上发生的错误
# 安装 Kubernetes Dashboard
kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/v2.0.0-beta5.yaml# Kubernetes Dashboard 当前,只支持使用 Bearer Token登录
# 创建 ServiceAccount 和 ClusterRoleBinding
kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/auth.yaml# 获取Bearer Token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
# 执行代理命令
kubectl proxy
# 如需要使用 nodePort 或 Ingress 的方式访问 Kubernetes Dashboard 请配置正确的 https 证书,或者使用 Firefox 浏览器,并忽略 HTTPS 校验错误。
# 访问路径,将上一个步骤中获得的 Token 输入到登录界面中,点击 Sign in 按钮,完成登录
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
三、集群服务部署
1、部署应用Demo
部署一个 nodejs web 应用,源码地址:Github
# 查看pod状态
kubectl get pod -owide
# 运行一个pod
kubectl run testapp --image=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1
# 通过yaml创建k8sPod
kubectl apply -f pod.yaml
kubectl apply -f deployment.yaml
创建pod.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:# 定义容器,可以多个containers:- name: test-k8s # 容器名字image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
创建deployment.yaml文件
apiVersion: apps/v1
# 定义资源的类型/角色,deployment为副本控制器,此处资源类型可以是Deployment、Job、Ingress、Service等
kind: Deployment
metadata:# 定义资源的名称,在同一个namespace空间中必须是唯一的name: test-k8s
spec:replicas: 2# 用来查找关联的 Pod,所有标签都匹配才行selector:matchLabels:app: test-k8s# 定义 Pod 相关数据template:metadata:labels:app: test-k8sspec:# 定义容器,可以多个containers:- name: test-k8s # 容器名字image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
命令行弹性伸缩,k8s会自动根据结点情况部署
# 命令行弹性扩容,也可以在yaml中进行编写
kubectl scale deployment test-k8s --replicas=3
# 修改镜像
kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error
# 把集群内端口某个pod映射到节点
kubectl port-forward test-k8s-5699487f75-bg82t 8090:8080
# 在master结点测试访问,这只是其中一个容器的,外网不能进行访问
curl localhost:8090
2、常用命令详情
# 部署应用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看 pod
kubectl get pod -o wide
# 查看 pod 详情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name [-f]
# 进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。
kubectl exec -it pod-name -- bash
# 伸缩扩展副本
kubectl scale deployment test-k8s --replicas=5
# 把集群内端口映射到节点
kubectl port-forward pod-name 8090:8080
# 查看历史
kubectl rollout history deployment test-k8s
# 回到上个版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision=2
# 删除部署
kubectl delete deployment test-k8s# =============更多命令============
# 查看全部
kubectl get all
# 重新部署
kubectl rollout restart deployment test-k8s
# 命令修改镜像,--record 表示把这个命令记录到操作历史中
kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record
# 暂停运行,暂停后,对 deployment 的修改不会立刻生效,恢复后才应用设置
kubectl rollout pause deployment test-k8s
# 恢复
kubectl rollout resume deployment test-k8s
# 输出到文件
kubectl get deployment test-k8s -o yaml >> app2.yaml
# 删除全部资源
kubectl delete all --all
3、概念
更多官网关于 Deployment 的介绍,将 Pod 指定到某个节点运行:nodeselector,限定 CPU、内存总量:文档
3.1 工作负载分类
https://kubernetes.io/zh/docs/concepts/workloads/
-
Deployment
适合无状态应用,所有pod等价,可替代
-
StatefulSet
有状态的应用,适合数据库这种类型。
-
DaemonSet
在每个节点上跑一个 Pod,可以用来做节点监控、节点日志收集等
-
Job & CronJob
Job 用来表达的是一次性的任务,而 CronJob 会根据其时间规划反复运行。
3.2 存在问题
- 每次只能访问一个 pod,没有负载均衡自动转发到不同 pod
- 访问还需要端口转发
- Pod 重创后 IP 变了,名字也变了
四、Service
1、概念
https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#headless-services
- Service 通过 label 关联对应的 Pod
- Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重创改变 IP
- 提供了负载均衡功能,自动转发流量到不同 Pod
- 可对集群外部提供访问端口
- 集群内部可通过服务名字访问
2、Service简单Demo
首先创建service.yaml
apiVersion: v1
kind: Service
metadata:name: test-k8s
spec:selector:# 要和pod对应app: test-k8s# 服务默认是这个type: ClusterIPports:- port: 8080 # 本 Service 的端口targetPort: 8080 # 容器端口
然后进行访问测试
# 创建service
kubectl apply -f service.yaml
# 查看服务
kubectl get service
kubectl get svc
# 查看服务详情,可以发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点
kubectl describe svc test-k8s
# 服务的默认类型是ClusterIP,只能在集群内部访问,我们可以进入到 Pod 里面访问
kubectl exec -it pod-name -- bash
curl http://test-k8s:8080
# 如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用)
kubectl port-forward service/test-k8s 8888:8080
curl http://localhost:8080
3、对外暴露服务(重要)
上面我们是通过端口转发的方式可以在外面访问到集群里的服务,如果想要直接把集群服务暴露出来,我们可以使用NodePort
和 Loadbalancer
类型的 Service
apiVersion: v1
kind: Service
metadata:name: test-k8s
spec:selector:app: test-k8s# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)type: NodePortports:- port: 8080 # 本 Service 的端口targetPort: 8080 # 容器端口nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
应用配置 kubectl apply -f service.yaml
;在节点上,我们可以 curl http://localhost:31000
或者curl http://[你的物理ip]:31000
访问到应用并且是有负载均衡的,网页的信息可以看到被转发到了不同的 Pod(可能有缓存)
Loadbalancer
也可以对外提供服务,这需要一个负载均衡器的支持,因为它需要生成一个新的 IP 对外服务,否则状态就一直是 pendding,这个很少用了,后面我们会讲更高端的 Ingress 来代替它。
4、多端口
https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#multi-port-services
多端口时必须配置 name
apiVersion: v1
kind: Service
metadata:name: test-k8s
spec:selector:app: test-k8stype: NodePortports:- port: 8080 # 本 Service 的端口name: test-k8s # 必须配置targetPort: 8080 # 容器端口nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767- port: 8090name: test-othertargetPort: 8090nodePort: 32000
5、总结
-
ClusterIP
默认的,仅在集群内可用
-
NodePort
暴露端口到节点,提供了集群外部访问的入口,端口范围固定 30000 ~ 32767
-
LoadBalancer
需要负载均衡器(通常都需要云服务商提供,裸机可以安装 METALLB 测试)会额外生成一个 IP 对外服务K8S 支持的负载均衡器:负载均衡器
-
Headless
适合数据库,clusterIp 设置为 None 就变成 Headless 了,不会再分配 IP,后面会再讲到具体用法
五、StatefulSet
1、StatefulSet介绍
1.1 概念
StatefulSet 是用来管理有状态的应用,例如数据库。 前面我们部署的应用,都是不需要存储数据,不需要记住状态的,可以随意扩充副本,每个副本都是一样的,可替代的。 而像数据库、Redis 这类有状态的,则不能随意扩充副本。StatefulSet 会固定每个 Pod 的名字
1.2 特性
- Service 的
CLUSTER-IP
是空的,Pod 名字也是固定的。 - Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
- Pod 重建不会改变名字,除了IP,所以不要用IP直连
2、部署 StatefulSet 类型的 Mongodb
创建statefulset和service
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:serviceName: mongodbreplicas: 3selector:matchLabels:app: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4#IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:name: mongodb
spec:selector:app: mongodbtype: ClusterIP# HeadLessclusterIP: Noneports:- port: 27017targetPort: 27017
操作,这里的test-k8s镜像使用了ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v3-mongo
# 扩容
kubectl scale --replicas=5 statefulset mongodb
# 查看状态信息
kubectl get endpoints mongodb -o yaml# 访问时,如果直接使用 Service 名字连接,会随机转发请求
# 要连接指定 Pod,可以这样pod-name.service-name# 运行一个临时 Pod 连接数据测试下
kubectl run mongodb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash# 访问某一个mongodb
mongo --host mongodb-0.mongodbshow dbs
use test
db.users.save({'_id':'shawn','name':'shawn22'})
db.users.find()# 查看集权状态
kubectl get all
六、数据持久化
1、概念
kubernetes 集群不会为你处理数据的存储,我们可以为数据库挂载一个磁盘来确保数据的安全。可以选择云存储、本地磁盘、NFS。
- 本地磁盘:可以挂载某个节点上的目录,但是这需要限定 pod 在这个节点上运行
- 云存储:不限定节点,不受集群影响,安全稳定;需要云服务商提供,裸机集群是没有的。
- NFS:不限定节点,不受集群影响
2、hostPath 挂载示例
文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath
把节点上的一个目录挂载到 Pod,但是已经不推荐使用了,该方法配置方式简单,需要手动指定 Pod 跑在某个固定的节点。仅供单节点测试使用;不适用于多节点集群
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:replicas: 1selector:matchLabels:app: mongodbserviceName: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错imagePullPolicy: IfNotPresentvolumeMounts:- mountPath: /data/db # 容器里面的挂载路径name: mongo-data # 卷名字,必须跟下面定义的名字一致volumes:- name: mongo-data # 卷名字hostPath:path: /data/mongo-data # 节点上的路径type: DirectoryOrCreate # 指向一个目录,不存在时自动创建
创建好数据后重启kubectl rollout restart statefulset mongodb
,发现数据还在,同时进入结点,可以发现数据保存在/data/db
,而进入该结点的宿主机,发现数据映射在/data/mongo-data
3、高级抽象挂载
3.1 概述
- 更好的分工,运维人员负责提供好存储,开发人员不需要关注磁盘细节,只需要写一个申请单。
- 方便云服务商提供不同类型的,配置细节不需要开发者关注,只需要一个申请单。
- 动态创建,开发人员写好申请单后,供应商可以根据需求自动创建所需存储卷。
3.2 各个层级表述
Storage Class (SC)
将存储卷划分为不同的种类,例如:SSD,普通磁盘,本地磁盘,按需使用。文档
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: slow
provisioner: kubernetes.io/aws-ebs
parameters:type: io1iopsPerGB: "10"fsType: ext4
Persistent Volume (PV)
描述卷的具体信息,例如磁盘大小,访问模式。文档,类型,Local 示例
apiVersion: v1
kind: PersistentVolume
metadata:name: mongodata
spec:capacity:storage: 2GivolumeMode: Filesystem # Filesystem(文件系统) Block(块)accessModes:- ReadWriteOnce # 卷可以被一个节点以读写方式挂载persistentVolumeReclaimPolicy: DeletestorageClassName: local-storagelocal:path: /root/datanodeAffinity:required:# 通过 hostname 限定在某个节点创建存储卷nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- node2
Persistent Volume Claim (PVC)
对存储需求的一个申明,可以理解为一个申请单,系统根据这个申请单去找一个合适的 PV
还可以根据 PVC 自动创建 PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mongodata
spec:accessModes: ["ReadWriteOnce"]storageClassName: "local-storage"resources:requests:storage: 2Gi
3.3 本地测试
网络云服务商封装了底层,只需要提交pvc申请即可成功,这里我用本地进行模拟,写到了一起,实际可以自行分开
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:replicas: 1selector:matchLabels:app: mongodbserviceName: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错imagePullPolicy: IfNotPresentvolumeMounts:- mountPath: /data/db # 容器里面的挂载路径name: mongo-data # 卷名字,必须跟下面定义的名字一致volumes:- name: mongo-data # 卷名字persistentVolumeClaim:claimName: mongodata---
apiVersion: v1
kind: Service
metadata:name: mongodb
spec:clusterIP: Noneports:- port: 27017protocol: TCPtargetPort: 27017selector:app: mongodbtype: ClusterIP
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:name: mongodata
spec:capacity:storage: 2GivolumeMode: Filesystem # Filesystem(文件系统) Block(块)accessModes:# 卷可以被一个节点以读写方式挂载- ReadWriteOnce persistentVolumeReclaimPolicy: DeletestorageClassName: local-storagelocal:path: /root/datanodeAffinity:required:# 通过 hostname 限定在某个节点创建存储卷nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mongodata
spec:accessModes: ["ReadWriteOnce"]storageClassName: "local-storage"resources:requests:storage: 2Gi
测试
# 运行
kubectl apply -f storage.yaml
# 查看各个层信息
kubectl get pv
kubectl get sc
kubectl get pvc
kubectl get pod -owide
# 需要进入node2结点去创建一下data路径,可能会报错,后面mongo的数据库就挂在到了node2的/data下面
七、ConfigMap & Secret
1、概述
参考文档:https://kubernetes.io/zh/docs/concepts/configuration/configmap/
数据库连接地址,这种可能根据部署环境变化的,我们不应该写死在代码里。Kubernetes 为我们提供了 ConfigMap,可以方便的配置一些变量
2、ConfigMap
创建configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: mongo-config
data:mongoHost: mongodb-0.mongodb
# 应用
kubectl apply -f configmap.yaml
# 查看
kubectl get configmap mongo-config -o yaml
kubectl get configmap
3、Secret
一些重要数据,例如密码、TOKEN,我们可以放到 secret 中。文档,配置证书。注意,数据要进行 Base64 编码。Base64 工具
创建secret.yaml
apiVersion: v1
kind: Secret
metadata:name: mongo-secret
# Opaque 用户定义的任意数据,更多类型介绍 https://kubernetes.io/zh/docs/concepts/configuration/secret/#secret-types
type: Opaque
data:# 数据要 base64。https://tools.fun/base64.htmlmongo-username: bW9uZ291c2Vymongo-password: bW9uZ29wYXNz
# 应用
kubectl apply -f secret.yaml
# 查看
kubectl get secret mongo-secret -o yaml
kubectl get secret
4、Demo使用
作为环境变量使用
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mongodb
spec:replicas: 3selector:matchLabels:app: mongodbserviceName: mongodbtemplate:metadata:labels:app: mongodbspec:containers:- name: mongoimage: mongo:4.4# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错imagePullPolicy: IfNotPresentenv:- name: MONGO_INITDB_ROOT_USERNAMEvalueFrom:secretKeyRef:name: mongo-secretkey: mongo-username- name: MONGO_INITDB_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mongo-secretkey: mongo-password# Secret 的所有数据定义为容器的环境变量,Secret 中的键名称为 Pod 中的环境变量名称# envFrom:# - secretRef:# name: mongo-secret
---
apiVersion: v1
kind: Service
metadata:name: mongodb
spec:selector:app: mongodbtype: ClusterIP# HeadLessclusterIP: Noneports:- port: 27017targetPort: 27017
挂载为文件(更适合证书文件)挂载后,会在容器中对应路径生成文件,一个 key 一个文件,内容就是 value,文档
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: mypodimage: redisvolumeMounts:- name: foomountPath: "/etc/foo"readOnly: truevolumes:- name: foosecret:secretName: mysecret
进行测试(test-k8s的镜像更换ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v4-configmap)
kubectl run mongodb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash
mongo --host mongodb-0.mongodb -u mongouser -p mongopass
show dbs
# 外部访问需要端口转发
八、Helm & 命名空间
1、简介
Helm官网:https://helm.sh/zh/
包搜索:https://artifacthub.io/
Helm
类似 npm,pip,docker hub, 可以理解为是一个软件库,可以方便快速的为我们的集群安装一些第三方软件。使用 Helm 我们可以非常方便的就搭建出来 MongoDB / MySQL 副本集群,YAML 文件别人都给我们写好了,直接使用
2、Helm安装
安装文档:https://helm.sh/zh/docs/intro/install/
# 脚本安装,不过可能会失败
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 手动进行安装
wget https://get.helm.sh/helm-v3.10.1-linux-amd64.tar.gz
tar -zxvf helm-v3.10.1-linux-amd64.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm
helm --help
3、安装MongoDb
# 安装
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-mongo bitnami/mongodb# 指定密码和架构
helm install my-mongo bitnami/mongodb --set architecture="replicaset",auth.rootPassword="mongopass"# 删除
helm ls
helm delete my-mongo# 查看密码
kubectl get secret my-mongo-mongodb -o json
kubectl get secret my-mongo-mongodb -o yaml > secret.yaml# 临时运行一个包含 mongo client 的 debian 系统
kubectl run mongodb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash# 进去 mongodb
mongo --host "my-mongo-mongodb" -u root -p mongopass# 也可以转发集群里的端口到宿主机访问 mongodb
kubectl port-forward svc/my-mongo-mongodb 27017:27018
4、命名空间
如果一个集群中部署了多个应用,所有应用都在一起,就不太好管理,也可以导致名字冲突等。我们可以使用 namespace 把应用划分到不同的命名空间,跟代码里的 namespace 是一个概念,只是为了划分空间
# 创建命名空间
kubectl create namespace testapp
# 部署应用到指定的命名空间
kubectl apply -f app.yml --namespace testapp
# 查询
kubectl get pod --namespace kube-system
# 查询命名空间
kubectl get ns
可以用 kubens 快速切换 namespace,首先进行下载安装
wget https://github.com/ahmetb/kubectx/releases/download/v0.9.4/kubens_v0.9.4_linux_x86_64.tar.gz
tar -zxvf kubens_v0.9.4_linux_x86_64.tar.gz
sudo mv kubens /usr/local/bin/kubens
# 查看所有命名空间
kubens
# 切换命名空间
kubens kube-system
# 回到上个命名空间
kubens -
# 切换集群
# kubectx minikube
九、Ingress
1、介绍
Ingress 为外部访问集群提供了一个 统一 入口,避免了对外暴露集群端口;功能类似 Nginx,可以根据域名、路径把请求转发到不同的 Service。可以配置 https
**跟 LoadBalancer 有什么区别?**LoadBalancer 需要对外暴露端口,不安全;无法根据域名、路径转发流量到不同 Service,多个 Service 则需要开多个 LoadBalancer;功能单一,无法配置 https
2、使用
文档:Ingress
要使用 Ingress,需要一个负载均衡器 + Ingress Controller如果是裸机(bare metal) 搭建的集群,你需要自己安装一个负载均衡插件,可以安装 METALLB如果是云服务商,会自动给你配置,否则你的外部 IP 会是 "pending"状态,无法使用。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: simple-example
spec:ingressClassName: nginxrules:- host: tools.funhttp:paths:- path: /easydocpathType: Prefixbackend:service:name: service1port:number: 4200- path: /svnbucketpathType: Prefixbackend:service:name: service2port:number: 8080
参考文档:
https://www.bilibili.com/video/BV1Tg411P7EB
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/9EX8Cp45
https://kuboard.cn/install/install-k8s.html
相关文章:
k8s快速入门
文章目录一、Kubernetes(K8S)简介1、概念1.1 Kubernetes (K8S) 是什么1.2 核心特性1.3 部署方案2、Kubernetes 集群架构2.1 架构2.2 重要概念 Pod2.3 Kubernetes 组件二、Kubernetes集群安装1、安装方式介绍2、minikubute安装3、裸机搭建(Bar…...
NG ZORRO知识点总结
NG ZORRO的常用属性,包括但不限于,结合代码 <button nz-button [nzType]"primary" [nzSize]"large" [nzLoading]"loading" [nzDisabled]"disabled" (click)"onClick()">点击我</button>nz-button是一个按钮组件…...
go中的值方法和指针方法
go中的值方法和指针方法1前言2 不同类型的对象调用不同类型的方法2.1 值对象可以调用值方法和指针方法3 指针对象可以调用值方法和指针方法4 !注意:结构体对象实现接口方法1前言 golang中在给结构体对象添加方法时,接收者参数类型可以有两种…...
OKR常见挑战以及应对方法探讨
背景 OKR是大家经常听到的一个词,也有不少团队说自己实行过,但每个实行过的团队都遇到过挑战。很多团队都感觉OKR有些空,很难落地,普通团队成员更是时常感觉无所适从,感觉就像看电影。2022年我们在更大的范围落地了OK…...
SpringAMQP消息队列(SpringBoot集成RabbitMQ)
一、初始配置1、导入maven坐标<!--rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>2、yml配置spring:rabbitmq:host: 你的rabbitmq的ipport: …...
DIDL5_数值稳定性和模型初始化
数值稳定性和模型初始化数值稳定性梯度不稳定的影响推导什么是梯度消失?什么是梯度爆炸?如何解决数值不稳定问题?——参数初始化参数初始化的几种方法默认初始化Xavier初始化小结当神经网络变得很深的时候,数值特别容易不稳定。我…...
火狐浏览器推拽开新的窗口
今天我测试的时候,发现我拖拽一下火狐会打开了新的窗口,谷歌就不会,所以我们要阻止一下默认行为const disableFirefoxDefaultDrop () > {const isFirefox navigator.userAgent.toLowerCase().indexOf(firefox) ! -1if (isFirefox) {docu…...
vrrp+mstp+osfp经典部署案例
LSW1和LSW2和LSW3和LSW4上面启用vrrpmstp组网: vlan 10 全走LSW1出再走AR2到外网,vlan 20 全走LSW2出再走AR3到外网 配置注意:mstp实例的根桥在哪,vrrp的主设备就是谁 ar2和ar3上开nat ar2和ar3可以考虑换成两台防火墙来做&…...
AI_News周刊:第二期
2023.02.13—2023.02.17 1.ChatGPT 登上TIME时代周刊封面 这一转变标志着自社交媒体以来最重要的技术突破。近几个月来,好奇、震惊的公众如饥似渴地采用了生成式人工智能工具,这要归功于诸如 ChatGPT 之类的程序,它对几乎任何查询做出连贯&a…...
【C++的OpenCV】第一课-opencv的间接和安装(Linux环境下)
第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意:官网为英文版本,可以使用浏览器自带的翻译插件进行翻译,真心不推荐大家去看别人翻译的&am…...
为什么建议使用你 LocalDateTime ,而不是 Date
为什么建议使用你 LocalDateTime ,而不是 Date? 在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗 通过阅读本篇文章你将了解到: 为什么需要LocalDate…...
【大数据】HADOOP-YARN容量调度器Spark作业实战
目录需求配置多队列的容量调度器验证队列资源需求 default 队列占总内存的40%,最大资源容量占总资源的60% ops 队列占总内存的60%,最大资源容量占总资源的80% 配置多队列的容量调度器 在yarn-site.xml里面配置使用容量调度器 <!-- 使用容量调度器…...
平面及其方程
一、曲面和交线的定义 空间解析几何中,任何曲面或曲线都看作点的几何轨迹。在这样的意义下,如果曲面SSS与三元方程: F(x,y,z)0(1)F(x,y,z)0\tag{1} F(x,y,z)0(1) 有下述关系: 曲面 SSS 上任一点的坐标都满足方程(1)(1)(1)不在曲…...
7 配置的封装
概述 IPC设备通常有三种配置信息:一是默认配置,存储了设备所有配置项的默认值,默认配置是只读的,不能修改;二是用户配置,存储了用户修改过的所有配置项;三是私有配置,存储了程序内部使用的一些配置项,比如:固件升级的URL、固件升级标志位等。恢复出厂设置的操作,实际…...
03_Docker 入门
03_Docker 入门 文章目录03_Docker 入门3.1 确保 Docker 已经就绪3.2 运行我们的第一个容器3.3 使用第一个容器3.4 容器命名3.5 重新启动已经停止的容器3.6 附着到容器上3.7 创建守护式容器3.8 容器内部都在干些什么3.9 Docker 日志驱动3.10 查看容器内的进程3.11 Docker 统计信…...
Python 为什么要 if __name__ == “__main__“:
各位读者,你们知道以下两个Python文件有什么区别吗? main1.py def main():output Helloprint(output)if __name__ "__main__":main()main2.py output Hello print(output)当我们直接运行 main1.py 与 main2.py 的时候,程序都…...
455. 分发饼干、376. 摆动序列、53. 最大子数组和
455.分发饼干 题目描述: 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块…...
基于Springbot+微信小程序的购药平台的设计与实现
基于Springbot微信小程序的购药平台的设计与实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、…...
aws lambda rust的sdk和自定义运行时
rust的aws sdk 参考资料 https://docs.aws.amazon.com/sdk-for-rust/latest/dg/getting-started.htmlhttps://awslabs.github.io/aws-sdk-rust/https://github.com/awslabs/aws-sdk-rusthttps://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rust_dev_preview rus sd…...
[安装之3] 笔记本加装固态和内存条教程(超详细)
由于笔记本是几年前买的了,当时是4000,现在用起来感到卡顿,启动、运行速度特别慢,就决定换个固态硬盘,加个内存条,再给笔记本续命几年。先说一下加固态硬盘SSD的好处:1.启动快 2.读取延迟小 3.写…...
极客时间左耳听风-高效学习
左耳听风——高效学习篇 P95 | 高效学习:端正学习态度 本人真实⬇️⬇️⬇️⬇️ “ 大部分人都认为自己爱学习,但是: 他们都是只有意识没有行动,他们是动力不足的人。 他们都不知道自己该学什么,他们缺乏方向和目标。…...
MSR寄存器访问
1.介绍 MSR是CPU的一组64位寄存器,每个MSR都有它的地址值(如下图所示),可以分别通过RDMSR 和WRMSR 两条指令进行读和写的操作。 如图中为8个P-state寄存器,地址分别为0xC001 0064 ~ 0xC001 006B,每个寄存…...
ArcGIS:模型构建器实现批量按掩膜提取影像
用研究区域的矢量数据来裁剪栅格数据集时,一般我们使用ArcGIS中的【按掩膜提取工具】。如果需要裁剪的栅格数据太多,处理起来非常的麻烦,虽然ArcGIS中有批处理的功能,但是还是需要手动选择输入输出数据。 如下图,鼠标…...
算法刷题打卡第94天: 找出给定方程的正整数解
找出给定方程的正整数解 难度:中等 给你一个函数 f(x, y) 和一个目标结果 z,函数公式未知,请你计算方程 f(x,y) z 所有可能的正整数 数对 x 和 y。满足条件的结果数对可以按任意顺序返回。 尽管函数的具体式子未知,但它是单调…...
浅析SAS协议(1):基本介绍
文章目录概述SAS协议发展历程SAS技术特性SAS设备拓扑SAS phySAS地址SAS设备类型SAS协议分层参考链接概述 SAS,全称Serial Attached SCSI,即串行连结SCSI,是一种采用了串行总线的高速互连技术。通过物理上使用串行总线连结,在链路…...
93.【Vue-细刷-02】
Vue-02(十六)、基本列表渲染 (v-for)1.使用v-for遍历数组2.使用v-for遍历对象3.使用v-for遍历字符串(十七)、列表过滤 (filter())1.⭐JS中Change属性的原生状态⭐2.使用watch监听实现3.const {xxx} this 在Vue的作用⭐⭐4.JS箭头函数参数的简写⭐5.使用computed进行计算实现(最…...
Allegro负片层不显示反盘的原因和解决办法
Allegro负片层不显示反盘的原因和解决办法 在用Allegro做PCB设计的时候,负片设计是较为常用的一种方式,有时会出现打开负片层却看不到反盘的情况,如下图 L2层是负片层 L2层仍然只能看到盘 如何才能看到反盘显示的效果,具体操作如下 首先确定L2层层叠里面设置的是负片...
ACM数论 裴蜀定理(贝祖定理)
一.内容定义 「裴蜀定理」,又称贝祖定理(Bzouts lemma)。是一个关于最大公约数的定理。其内容定义为:对于不全为零的任意整数 a 和 b,记二者的最大公约数为 g 即 gcd(a,b) g,则对于任意整数 x 和 y 都一定…...
基础篇—CSS Position(定位)解析
CSS Position(定位) position 属性指定了元素的定位类型。 position 属性的五个值: relativefixedabsolutesticky元素可以使用的顶部,底部,左侧和右侧属性定位。然而,这些属性无法工作,除非是先设定position属性。他们也有不同的工作方式,这取决于定位方法。 1、static…...
正则表达式与grep
基本正则表达式BRE集合 匹配字符匹配次数位置锚定 符号作用^尖角号,用于模式的最正常,如“^haha”,匹配以haha单词开头的行$美元符,用于模式的最右侧,如“haha$”,表示haha单词结尾的行^$组合符ÿ…...
做海报的话网站/关键词优化的技巧
首批中国人工智能产业发展联盟特约媒体以及联盟媒体专家委员会委员公布。 中国人工智能产业发展联盟媒体项目组成立会于2018年1月25日在京举行。会议由联盟办公室主任石霖主持。 我国人工智能领域进入了蓬勃发展阶段,各行各业形成了以人工智能为基础的科技创新体系…...
seo网站建设方案/对搜索引擎优化的认识
1.公式的转化 我们都知道在latex上编写公式非常简便,他有一套自己的语言支持。 但是复杂的公式在word上编写十分麻烦,那如何将latex上的公式无缝的对接到word上呢? 一个在线转变网站 使用: $$ \mathbf{G} \left[\begin{matrix}g…...
网站栏目结构设计/使用最佳搜索引擎优化工具
python实用函数实现 分割列表: def TyChunk(l: list, size: int):return list(map(lambda x: l[x * size: x * size size],list(range(0, ceil(len(l) / size)))))扭转列表: def TyTranspose(array):return [list(i) for i in list(zip(*array))]...
个人网站不备案会怎么样/网络广告的发布方式包括
定义一个Teacher(教师)类和一个 Student( 学生)类,者有一部分数据成员 是相同的,例如num(号码), name(姓名),sex(性别)。编写程序,将一个Student对象(学生)转换为Teacher(教师)类,只将以上3个相同的数据成员移植过去。…...
做网站的费用入账/网站模板及源码
...
php做的网站预览/每日新闻摘抄10一15字
1.内部类的概述 将类定义在另一个类的内部则成为内部类。其实就是类定义的位置发生了变化。 看下面代码: class Outer{int num10;class Inner{//属性int age20;//内部类定义函数public void print(){System.out.println("内部类");}}public void show(){…...