Kubernetes系列之Helm介绍篇

image

本次系列使用的所需部署包版本都使用的目前最新的或最新稳定版,安装包地址请到公众号内回复【K8s实战】获取

介绍


Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来管理 Charts。有点类似于 Ubuntu 中的 APT 或 CentOS 中的 YUM。Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata,以便于应用程序的分发。对于应用发布者而言,可以通过 Helm 打包应用、管理应用依赖关系、管理应用版本并发布应用到软件仓库。对于使用者而言,使用 Helm 后不用需要编写复杂的应用部署文件,可以以简单的方式在 Kubernetes 上查找、安装、升级、回滚、卸载应用程序。

Helm 工作原理


这张图描述了 Helm 的几个关键组件 Helm(客户端)、Tiller(服务器)、Repository(Chart 软件仓库)、Chart(软件包)之间的关系。

image

下载解压


[root@master-01 ~]# mkdir /opt/helm&&cd /opt/helm[root@master-01 helm]#wget https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz[root@master-01 helm]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz[root@master-01 helm]# tar xf helm-v2.12.3-linux-amd64.tar.gz [root@master-01 helm]# cd linux-amd64/[root@master-01 linux-amd64]# mv helm /usr/bin/[root@master-01 linux-amd64]# helm versionClient: &version.Version{SemVer:"v2.12.3", GitCommit:"79d07943b03aea2b76c12644b4b54733bc5958d6", GitTreeState:"clean"}Error: could not find tiller

创建RBAC角色


创建 Kubernetes 的服务帐号和绑定角色

[root@master-01 helm]#kubectl create serviceaccount --namespace kube-system tiller[root@master-01 helm]#kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

为 Tiller 设置帐号

使用 kubectl patch 更新 API 对象

[root@master-01 helm]# kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'deployment.extensions "tiller-deploy" patched

查看是否授权成功

[root@master-01 helm]# kubectl get deploy --namespace kube-system tiller-deploy --output yaml|grep serviceAccountserviceAccount: tillerserviceAccountName: tiller

初始化Tiller


tiller是以Deployment部署在k8s集群中的,使用helm init就可以直接安装

因为tiller默认是去storage.googleapis.com拉镜像,所以我们要改成国内源 

[root@master-01 ]# helm initCreating /root/.helm Creating /root/.helm/repository Creating /root/.helm/repository/cache Creating /root/.helm/repository/local Creating /root/.helm/plugins Creating /root/.helm/starters Creating /root/.helm/cache/archive Creating /root/.helm/repository/repositories.yaml Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com Error: Looks like "https://kubernetes-charts.storage.googleapis.com" is not a valid chart repository or cannot be reached: Get https://kubernetes-charts.storage.googleapis.com/index.yaml: dial tcp 216.58.200.16:443: connect: connection refused

更换国内源

[root@master-01 ~]# helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts"stable" has been added to your repositories

再次初始化

[root@master-01 ~]# helm init$HELM_HOME has been configured at /root/.helm.Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.To prevent this, run `helm init` with the --tiller-tls-verify flag.For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installationHappy Helming!

查看pod状态

[root@master-02 ~]# kubectl -nkube-system get po -owideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEScoredns-5d668bd598-dt4qm 1/1 Running 0 5h1m 172.17.79.3 192.168.209.132 <none> <none>coredns-5d668bd598-f5g96 1/1 Running 1 18h 172.17.44.2 192.168.209.131 <none> <none>kubernetes-dashboard-cb55bd5bd-gc84g 1/1 Running 0 3h25m 172.17.47.2 192.168.209.133 <none> <none>tiller-deploy-58cf8bbc46-ss5nq 0/1 ImagePullBackOff 3 79s 172.17.44.4 192.168.209.131 <none> <none>

解决无法 pull tiller

默认镜像用的是gcr.io/kubernetes-helm/tiller:v2.12.3,国内无法下载,需要替换成国内地址

修改tiller pod 镜像地址为registry.cn-beijing.aliyuncs.com/minminmsn/tiller:v2.12.3

[root@master-01 helm]# kubectl -nkube-system edit deploy tiller-deploydeployment.extensions/tiller-deploy edited[root@master-02 ~]# kubectl -nkube-system get po -owideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEScoredns-5d668bd598-dt4qm 1/1 Running 0 5h3m 172.17.79.3 192.168.209.132 <none> <none>coredns-5d668bd598-f5g96 1/1 Running 1 18h 172.17.44.2 192.168.209.131 <none> <none>kubernetes-dashboard-cb55bd5bd-gc84g 1/1 Running 0 3h27m 172.17.47.2 192.168.209.133 <none> <none>tiller-deploy-5bd5fcdbbd-zdrnj 1/1 Running 0 44s 172.17.58.2 192.168.209.130 <none> <none>

结果

[root@master-01 ~]# helm versionClient: &version.Version{SemVer:"v2.12.3", GitCommit:"eecf22f77df5f65c823aacd2dbd30ae6c65f186e", GitTreeState:"clean"}Server: &version.Version{SemVer:"v2.12.3", GitCommit:"eecf22f77df5f65c823aacd2dbd30ae6c65f186e", GitTreeState:"clean"}

示例演示


新建一个helm chart

[root@master-01 helm]# helm create mychartCreating mychart

该命令创建了一个 mychart 目录,该目录结构如下所示。这里我们主要关注目录中的 Chart.yaml、values.yaml、NOTES.txt 和 Templates 目录。

[root@master-01 helm]# tree mychart/mychart/├── charts├── Chart.yaml├── templates│ ├── deployment.yaml│ ├── _helpers.tpl│ ├── ingress.yaml│ ├── NOTES.txt│ ├── service.yaml│ └── tests│ └── test-connection.yaml└── values.yaml3 directories, 8 files

Chart.yaml 用于描述这个 Chart的相关信息,包括名字、描述信息以及版本等。

values.yaml 用于存储 templates 目录中模板文件中用到变量的值。

NOTES.txt 用于介绍 Chart 部署后的一些信息,例如:如何使用这个 Chart、列出缺省的设置等。

Templates 目录下是 YAML 文件的模板,该模板文件遵循 Go template 语法。

Templates 目录下 YAML 文件模板的值默认都是在 values.yaml 里定义的,比如在 deployment.yaml 中定义的容器镜像。

image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

其中的 .Values.image.repository 的值就是在 values.yaml 里定义的 nginx,.Values.image.tag 的值就是 stable。

[root@master-01 helm]#cat mychart/values.yaml|grep repositoryrepository: nginx[root@master-01 helm]#cat mychart/values.yaml|grep tagtag: stable

以上两个变量值是在 create chart 的时候就自动生成的默认值,你可以根据实际情况进行修改。

修改应用介绍信息

[root@master-01 helm]# cat mychart/Chart.yamlapiVersion: v1appVersion: "1.0"description: A Helm chart for Kubernetesname: mychartversion: 0.1.0

修改应用具体编排信息

[root@master-01 helm]# cat mychart/values.yaml # Default values for mychart.# This is a YAML-formatted file.# Declare variables to be passed into your templates.replicaCount: 1image:repository: nginxtag: stablepullPolicy: IfNotPresentnameOverride: ""fullnameOverride: ""service:type: ClusterIPport: 80ingress:enabled: falseannotations: {}# kubernetes.io/ingress.class: nginx# kubernetes.io/tls-acme: "true"paths: []hosts:- chart-example.localtls: []# - secretName: chart-example-tls# hosts:# - chart-example.localresources: {}# We usually recommend not to specify default resources and to leave this as a conscious# choice for the user. This also increases chances charts run on environments with little# resources, such as Minikube. If you do want to specify resources, uncomment the following# lines, adjust them as necessary, and remove the curly braces after 'resources:'.# limits:# cpu: 100m# memory: 128Mi# requests:# cpu: 100m# memory: 128MinodeSelector: {}tolerations: []affinity: {}

检查配置语法

[root@master-01 helm]# helm lint mychart==> Linting mychart[INFO] Chart.yaml: icon is recommended1 chart(s) linted, no failures

如果文件格式错误,可以根据提示进行修改。

打包应用

[root@master-01 helm]# helm package mychartSuccessfully packaged chart and saved it to: /opt/helm/mychart-0.1.0.tgz

mychart 目录会被打包为一个 mychart-0.1.0.tgz 格式的压缩包,该压缩包会被放到当前目录下,并同时被保存到了 Helm 的本地缺省仓库目录中。

查看本地仓库

[root@master-01 helm]# helm repo listNAME URL stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/chartslocal http://127.0.0.1:8879/charts

启动本地仓库

[root@master-01 helm]# helm serve &[1] 25758[root@master-01 helm]# Regenerating index. This may take a moment.Now serving you on 127.0.0.1:8879

默认情况只监听127.0.0.1,如果你要绑定到其它网络接口,可使用以下命令:

[root@master-01 helm]#helm serve --address 192.168.209.130:8879 &

部署应用

[root@master-01 helm]# helm install local/mychart --name test-01NAME: test-01LAST DEPLOYED: Tue Mar 12 16:38:04 2019NAMESPACE: defaultSTATUS: DEPLOYEDRESOURCES:==> v1/ServiceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEtest-01-mychart ClusterIP 10.254.105.20 <none> 80/TCP 2s==> v1/DeploymentNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEtest-01-mychart 1 0 0 0 1s==> v1/Pod(related)NAME READY STATUS RESTARTS AGEtest-01-mychart-7d84ff968f-76d2l 0/1 Pending 0 1sNOTES:1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=test-01" -o jsonpath="{.items[0].metadata.name}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl port-forward $POD_NAME 8080:80

完成部署后,现在 Nginx 就已经部署到 Kubernetes 集群上。在本地主机上执行提示中的命令后,就可在本机访问到该 Nginx 实例。

[root@master-01 helm]# export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=test-1" -o jsonpath="{.items[0].metadata.name}")[root@master-01 helm]# echo "Visit http://127.0.0.1:8080 to use your application"Visit http://127.0.0.1:8080 to use your application[root@master-01 helm]# kubectl port-forward $POD_NAME 8081:80Forwarding from 127.0.0.1:8081 -> 80Forwarding from [::1]:8081 -> 80

在本机访问

[root@master-01 ~]# curl 127.0.0.1:8081<!DOCTYPE html><html><head><title>Welcome to nginx!</title><style>body {width: 35em;margin: 0 autofont-family: Tahoma, Verdana, Arial, sans-serif;}......

使用helm ls 可以看到已经部署的Release和对应的Chart

[root@master-01 ~]# helm lsNAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACEtest-1 1 Tue Mar 12 18:19:41 2019 DEPLOYED mychart-0.1.0 1.0 default

使用helm status可以看到Release状态

[root@master-01 ~]# helm status test-1LAST DEPLOYED: Tue Mar 12 18:19:41 2019NAMESPACE: defaultSTATUS: DEPLOYEDRESOURCES:==> v1/ServiceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEtest-1-mychart ClusterIP 10.254.184.247 <none> 80/TCP 7m17s==> v1/DeploymentNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEtest-1-mychart 1 1 1 1 7m17s==> v1/Pod(related)NAME READY STATUS RESTARTS AGEtest-1-mychart-85459fd5cd-z6twn 1/1 Running 0 7m16sNOTES:1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=test-1" -o jsonpath="{.items[0].metadata.name}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl port-forward $POD_NAME 8080:80

升级和回退一个应用

从上面 helm ls 输出的结果中我们可以看到有一个 Revision(更改历史)字段,该字段用于表示某一个 Release 被更新的次数,我们可以用该特性对已部署的 Release 进行回退

修改 Chart.yaml 文件

将版本号从 0.1.0 修改为 0.2.0, 然后使用 helm package 命令打包并发布到本地仓库。

[root@master-01 helm]# cat mychart/Chart.yaml apiVersion: v1appVersion: "1.0"description: A Helm chart for Kubernetesname: mychartversion: 0.2.0[root@master-01 helm]# helm package mychartSuccessfully packaged chart and saved it to: /opt/helm/mychart-0.2.0.tgz

查看本地仓库Chart信息

可以看到本地有两个版本了

[root@master-01 ~]# helm search mychart -lNAME CHART VERSIONAPP VERSIONDESCRIPTION local/mychart0.2.0 1.0 A Helm chart for Kuberneteslocal/mychart0.1.0 1.0 A Helm chart for Kubernetes

升级应用

现在用 helm upgrade 命令将已部署的 mike-test 升级到新版本。你可以通过 --version 参数指定需要升级的版本号,如果没有指定版本号,则缺省使用最新版本。

[root@master-01 ~]# helm upgrade test-1 local/mychartRelease "test-1" has been upgraded. Happy Helming!LAST DEPLOYED: Tue Mar 12 18:33:18 2019NAMESPACE: defaultSTATUS: DEPLOYEDRESOURCES:==> v1/Pod(related)NAME READY STATUS RESTARTS AGEtest-1-mychart-85459fd5cd-z6twn 1/1 Running 0 13m==> v1/ServiceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEtest-1-mychart ClusterIP 10.254.184.247 <none> 80/TCP 13m==> v1/DeploymentNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEtest-1-mychart 1 1 1 1 13mNOTES:1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=test-1" -o jsonpath="{.items[0].metadata.name}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl port-forward $POD_NAME 8080:80

完成后,可以看到已部署的 mike-test 被升级到 0.2.0 版本。

[root@master-01 ~]# helm lsNAME REVISIONUPDATED STATUS CHART APP VERSIONNAMESPACEtest-1 2 Tue Mar 12 18:33:18 2019DEPLOYEDmychart-0.2.01.0 default

回退应用

如果更新后的程序由于某些原因运行有问题,需要回退到旧版本的应用。首先我们可以使用 helm history 命令查看一个 Release 的所有变更记录。

[root@master-01 ~]# helm history test-1REVISIONUPDATED STATUS CHART DESCRIPTION 1 Tue Mar 12 18:19:41 2019SUPERSEDEDmychart-0.1.0Install complete2 Tue Mar 12 18:33:18 2019DEPLOYED mychart-0.2.0Upgrade complete

我们可以使用下面的命令对指定的应用进行回退。

[root@master-01 ~]# helm rollback test-1 1Rollback was a success! Happy Helming!

我们使用 helm ls 和 helm history 命令都可以看到 mychart 的版本已经回退到 0.1.0版本。

[root@master-01 ~]# helm lsNAME REVISIONUPDATED STATUS CHART APP VERSIONNAMESPACEtest-1 3 Tue Mar 12 18:35:52 2019DEPLOYEDmychart-0.1.01.0 default [root@master-01 ~]# helm history test-1REVISIONUPDATED STATUS CHART DESCRIPTION 1 Tue Mar 12 18:19:41 2019SUPERSEDEDmychart-0.1.0Install complete2 Tue Mar 12 18:33:18 2019SUPERSEDEDmychart-0.2.0Upgrade complete3 Tue Mar 12 18:35:52 2019DEPLOYED mychart-0.1.0Rollback to 1

删除应用

如果需要删除一个已部署的 Release,可以利用 helm delete 命令来完成删除。

[root@master-01 ~]# helm delete test-1release "test-1" deleted

确认应用是否删除,该应用已被标记为 DELETED 状态。

[root@master-01 ~]# helm ls -a test-1NAME REVISIONUPDATED STATUSCHART APP VERSIONNAMESPACEtest-1 3 Tue Mar 12 18:35:52 2019DELETEDmychart-0.1.01.0 default

也可以使用 --deleted 参数来列出已经删除的 Release

[root@master-01 ~]# helm ls --deletedNAME REVISIONUPDATED STATUSCHART APP VERSIONNAMESPACEtest-1 3 Tue Mar 12 18:35:52 2019DELETEDmychart-0.1.01.0 default

从上面的结果也可以看出,默认情况下已经删除的 Release 只是将状态标识为 DELETED 了 ,但该 Release 的历史信息还是继续被保存的。

[root@master-01 ~]# helm hist test-1REVISIONUPDATED STATUS CHART DESCRIPTION 1 Tue Mar 12 18:19:41 2019SUPERSEDEDmychart-0.1.0Install complete 2 Tue Mar 12 18:33:18 2019SUPERSEDEDmychart-0.2.0Upgrade complete 3 Tue Mar 12 18:35:52 2019DELETED mychart-0.1.0Deletion complete

如果要移除指定 Release 所有相关的 Kubernetes 资源和 Release 的历史记录,可以用如下命令:

[root@master-01 ~]# helm delete --purge test-1release "test-1" deleted

再次查看已删除的 Release,已经无法找到相关信息

[root@master-01 ~]# helm hist test-1Error: release: "test-1" not found[root@master-01 ~]# helm ls[root@master-01 ~]# helm ls --deleted[root@master-01 ~]# helm ls -a test-1

部署一个应用示例


部署 Wordpress

这里以一个典型的三层应用 Wordpress 为例,包括 MySQL、PHP 和 Apache。由于测试环境暂时没有可用的 PersistentVolume(持久卷,简称 PV),这里暂时将其关闭。关于 Persistent Volumes 的相关信息我们会在后续的相关文章进行讲解。

[root@master-01 helm]# helm install --name wordpress-test --set "persistence.enabled=false,mariadb.persistence.enabled=false,serviceType=NodePort" stable/wordpressNAME: wordpress-testLAST DEPLOYED: Tue Mar 12 19:13:45 2019NAMESPACE: defaultSTATUS: DEPLOYEDRESOURCES:==> v1beta1/DeploymentNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEwordpress-test-mariadb 1 1 1 0 3swordpress-test-wordpress 1 1 1 0 3s==> v1/Pod(related)NAME READY STATUS RESTARTS AGEwordpress-test-mariadb-59cfd7c475-27chl 0/1 Pending 0 3swordpress-test-wordpress-6fc9b7cc7f-dt7fq 0/1 ContainerCreating 0 3s==> v1/SecretNAME TYPE DATA AGEwordpress-test-mariadb Opaque 2 4swordpress-test-wordpress Opaque 2 4s==> v1/ConfigMapNAME DATA AGEwordpress-test-mariadb 1 4swordpress-test-mariadb-tests 1 4s==> v1/ServiceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEwordpress-test-mariadb ClusterIP 10.254.153.229 <none> 3306/TCP 4swordpress-test-wordpress NodePort 10.254.154.132 <none> 80:43629/TCP,443:34204/TCP 3sNOTES:1. Get the WordPress URL:Or running:export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services wordpress-test-wordpress)export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")echo http://$NODE_IP:$NODE_PORT/admin2. Login with the following credentials to see your blogecho Username: userecho Password: $(kubectl get secret --namespace default wordpress-test-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)

部署完成后,用以上提示信息生成访问地址和用户名密码

[root@master-01 helm]# export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services wordpress-test-wordpress)DE_IP:$NODE_PORT/admin[root@master-01 helm]# export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")[root@master-01 helm]# echo http://$NODE_IP:$NODE_PORT/adminhttp://192.168.209.130:43629/admin[root@master-01 helm]# echo Username: userUsername: user[root@master-01 helm]# echo Password: $(kubectl get secret --namespace default wordpress-test-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)Password: aOTe96YaSP

查看服务状态

[root@master-01 helm]# kubectl get podNAME READY STATUS RESTARTS AGEdnstools-6b77cc4988-b5smz 1/1 Running 0 23hnginx-7899755b7-7s8fl 1/1 Running 0 24htests-1-mychart-7d84ff968f-76d2l 1/1 Running 0 170mwordpress-test-mariadb-59cfd7c475-27chl 1/1 Running 1 14mwordpress-test-wordpress-6fc9b7cc7f-dt7fq 1/1 Running 4 14m

访问测试

image

image

好了,进行到这 hlem基本使用就结束了,敬请期待后续分享,谢谢!

往期文章一览

1、Kubernetes集群搭建之系统初始化配置篇

2、Kubernetes集群搭建之企业级环境中基于Harbor搭建自己的私有仓库

3、Kubernetes集群搭建之Etcd集群配置篇

4、Kubernetes集群搭建之CNI-Flanneld部署篇

5、Kubernetes集群搭建之Master配置篇

6、Kubernetes系列之Coredns and Dashboard介绍篇

7、Kubernetes系列之监控Metres-server实战篇

END

如果您觉得不错,请别忘了转发、分享、点赞让更多的人去学习, 您的举手之劳,就是对小编最好的支持,非常感谢!

image

转载于:https://www.cnblogs.com/guigujun/p/10550256.html

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

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

相关文章

HTNL笔记整合

简述概括了HTML 的部分内容&#xff0c;不是很完善&#xff0c;希望能给予你们相对的帮助。 一下文件的整合百度云链接&#xff1a;HTML整合笔记 第一章 HTML入门 课时1&#xff1a;HTML初识 1、英文名&#xff08;Hyper Text Markup Language&#xff09;超文本标签语言 对…

EXCEL 图表 只在拐点的时候显示数字

EXCEL图表只在折线的拐点显示数值&#xff0c;中间不需要显示。同时往下拐的&#xff0c;显示在上方&#xff0c;往上的显示在下方&#xff0c;这样数值不会挡住线。 首先&#xff0c;做一些模拟数据 因为起点和终点数值必须显示&#xff0c;所以单元格&#xff0c;C2 D2 C19 D…

浅谈Vue之双向绑定

VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。那么Object.defineProperty究竟是该如何使用的呢&#xff1f;先看个例子 <!DOCTYPE html> <html lang"en"><h…

【AtCoder】AGC017

A - Biscuits dp[i][0/1]表示当前和是偶数还是奇数&#xff0c;直接转移即可 #include <bits/stdc.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar( ) #define enter putchar…

SQL语法(1、安装操作)

1、数据库的系统概述及安装与基本使用 bilibili可查找安装视频百度了解一下 – 使用超级管理员登录 CONN sys/change_on_install AS SYSDBA ; – 创建c##scott用户 CREATE USER c##scott IDENTIFIED BY tiger ; – 为用户授权 GRANT CONNECT,RESOURCE,UNLIMITED TABLESPACE…

java 中文字符和unicode编码值相互转化

java 中文字符和unicode编码值相互转化 https://blog.csdn.net/u011366045/article/details/79235217 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/u011366045/article/details/792352171、引用工具 import com.alibaba.…

Object 及toString() 方法的重写

Object: 是所有的类的父类 &#xff0c;Object中所有的方法 &#xff0c; 子类都能使用 &#xff0c; 接口不是Object子类。 Person: /*将父类的equals方法 重写* 不改变父类的源代码 equals 比较内存地址* 比较两个成员变量 变量值相等 返回true 不等 返回false* 重…

SQL语法练习

SQL语法练习https://blog.csdn.net/qq_30764991/article/details/81952197员工表建表语句: CREATE TABLE EMP ( ENAME VARCHAR2(30), EMPNO NUMBER(5), DEPTNO NUMBER(5), JOB VARCHAR2(20), HIREDATE DATE, COMM NUMBER(6,2), SAL NUMBER(6,2) ); 部门表建表语句: CREATE TA…

第22章:MongoDB-聚合操作--聚合管道--$out

①$out$out&#xff1a;利用此操作可以将查询结果输出到指定的集合里面。②范例&#xff1a;将投影的结果输出到集合里③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳转载于:https://www.cnblogs.com/Lucky-stars/p/10555296.html

SQL简单查询

1、简单查询 使用Oracle sql developer使用前&#xff0c;必须开启的服务&#xff1a; 查询emp表上的数据&#xff1a; select * from emp; Null为空&#xff0c;空不代表等于没有&#xff0c;null&#xff01;0. 重新连接后&#xff0c;注意大小写及空格位&#xff01; 简…

实用小技巧(一):UIScrollView中上下左右滚动方向的判断

https://www.jianshu.com/p/93e8459b6dae 2017.06.01 01:13* 字数 674 阅读 1201评论 0喜欢 12017.06.01 01:13* 字数 674 阅读 1201评论 0喜欢 1 版本记录 版本号 时间 V1.0 2017.05.31 前言 ios中又很多实用的小技巧&#xff0c;实现不难很实用&#xff0c;以后我会慢慢的…

less.js

1.变量 2.混入 3.带参的混入 4.选择器的继承&#xff0c;貌似还不支持 5.嵌套规则 6.运算 7.颜色函数 8.条件语句与控制&#xff0c;貌似不支持 9.命名空间 10.注释 11.作用域 12.字符的插入 13.转义 14.JavaScript 的赋值转载于:https://www.cnblogs.com/I-am-fine/archive/20…

SQL限定查询

1、限定查询与排序显示 1.1限定查询的认识&#xff1a; 列&#xff1a;表中有大数据的信息&#xff0c;对数据进行筛选&#xff0c;查询到自己想要的信息。 &#xff08;数据过多显示过慢&#xff0c;或者死机&#xff0c;在已有的样本数据库容器CDB转换为PDB之中&#xff09;…

Centos6.10源码部署zabbix-3.2.6

环境&#xff1a;Centos6.10 已有lnmp环境 mysql5.7 php7.2 创建zabbix数据库 mysql> create database zabbix character set utf8 collate utf8_bin; mysql> grant all privileges on zabbix.* to zabbixlocalhost identified by zabbix; 创建zabbix用户 shell> …

浅谈五大Python Web框架

http://www.csdn.net/article/2011-02-17/292058 导读&#xff1a;作者飞龙写了一篇《浅谈Python Web框架》&#xff0c;文中他介绍了几个Python Web框架和自己对选择框架的分析。在他看来&#xff0c;用Django来快速开发一些Web运用是很不错的选择。以下是文章内容&#xff1a…

主流浏览器和内核及Web标准

目前网络市场的浏览器主流&#xff1a; 课时3&#xff1a;web标准 WEB标准 w3c 万维网联盟组织&#xff0c;制定web标准的机构。 网页主要由三部分组成&#xff1a; 结构&#xff08;Structure&#xff09;、 表现&#xff08;Presentation&#xff09; 行为&#xff08;Beh…

质量属性六个常见属性场景(《淘宝网》为例) 15

六个最常见的系统质量属性分别是&#xff1a;可用性&#xff08;Availability&#xff09;、可修改性&#xff08;Modifiability&#xff09;、性能&#xff08;Performance&#xff09;、安全性&#xff08;Security&#xff09;、可测试性&#xff08;Testability&#xff09…

机器学习中的损失函数 (着重比较:hinge loss vs softmax loss)

https://blog.csdn.net/u010976453/article/details/78488279 1. 损失函数 损失函数&#xff08;Loss function&#xff09;是用来估量你模型的预测值 f(x)f(x) 与真实值 YY 的不一致程度&#xff0c;它是一个非负实值函数&#xff0c;通常用 L(Y,f(x))L(Y,f(x)) 来表示。损失函…

HTML入门第一和第二章

课时4&#xff1a;HTML初识 1、英文名&#xff08;Hyper Text Markup Language&#xff09;超文本标签语言 对网页上的内容进行描述 课时5&#xff1a;HTML骨架 课时6&#xff1a;我的第一个页面及其标签简介 课时7&#xff1a;骨架记忆法 课时8&#xff1a;什么是标签及其分…

mysql 指令

// 授予用户某些权限GRANT ALL ON *.* TO USERHOST;// 进入mysql访问特定数据库mysql -u user -p database_name// 查看数据表结构DESCRIBE table_name;// 加载文本数据到tableLOAD DATA LOCAL INFILE file_path INTO TABLE table_name;// UPDATE语句UPDATE table_name SET col…