这段时间学习了一下 git jenkins docker  最近也在看  Kubernetes  感觉写得很赞  也是对自己对于K8S 有了进一步得理解  感谢 倪 大神得Blog 也希望看到这篇Blog 得人  有点帮助   ‘“Kubernetes初体验”   转自    http://time-track.cn/kubernetes-trial.html

Kubernetes Cluster

Kubernetes is a production-grade, open-source platform that orchestrates the placement (scheduling) and execution of application containers within and across computer clusters.

Kubernetes将底层的计算资源连接在一起对外体现为一个计算集群,并将资源高度抽象化。部署应用时Kubernetes会以更高效的方式自动的将应用分发到集群内的机器上面,并调度运行。几个Kubernetes集群包含两种类型的资源:

  • Master节点:协调控制整个集群。

  • Nodes节点:运行应用的工作节点。

如下图:

Masters manage the cluster and the nodes are used to host the running applications.

Master负责管理整个集群,协调集群内的所有行为。比如调度应用,监控应用的状态等。

Node节点负责运行应用,一般是一台物理机或者虚机。每个Node节点上面都有一个Kubelet,它是一个代理程序,用来管理该节点以及和Master节点通信。除此以外,Node节点上还会有一些管理容器的工具,比如Docker或者rkt等。生产环境中一个Kubernetes集群至少应该包含三个Nodes节点。

当部署应用的时候,我们通知Master节点启动应用容器。然后Master会调度这些应用将它们运行在Node节点上面。Node节点和Master节点通过Master节点暴露的Kubernetes API通信。当然我们也可以直接通过这些API和集群交互。

Kubernetes提供了一个轻量级的Minikube应用,利用它我们可以很容器的创建一个只包含一个Node节点的Kubernetes Cluster用于日常的开发测试。

安装Minikube

Minikube的Github:https://github.com/kubernetes/minikube

Minikube提供OSX、Linux、Windows版本,本文测试环境为OSX,且以当时最新的版本为例。实际操作时,尽量到官网查看最新的版本及安装命令。

MacOS安装:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.15.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

Linux安装:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.15.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

Minikube要正常使用,还必须安装kubectl,并且放在PATH里面。kubectl是一个通过Kubernetes API和Kubernetes集群交互的命令行工具。安装方法如下:

MACOS安装:

wget https://storage.googleapis.com/kubernetes-release/release/v1.5.1/bin/darwin/amd64/kubectl
chmod +x kubectl
mv kubectl /usr/local/bin/kubectl

Linux安装:

wget https://storage.googleapis.com/kubernetes-release/release/v1.5.1/bin/linux/amd64/kubectl
chmod +x kubectl
mv kubectl /usr/local/bin/kubectl

因为Minikube使用Docker Machine管理Kubernetes的虚机,所以我们还需要安装一些虚机的driver,这里推荐使用Virtualbox,因为安装简单(从官网下载安装即可),而且后面可以简单的登录到VM里面去进行一些操作。其它driver的安装请参考官方文档:https://github.com/kubernetes/minikube/blob/master/DRIVERS.md

安装完以后,我们可以使用一下命令进行一些信息查看:

minikube version    # 查看版本
minikube start --vm-driver=virtualbox # 启动Kubernetes Cluster,这里使用的driver是Virtualbox kubectl version # 查看版本
kubectl cluster-info # 查看集群信息
kubectl get nodes # 查看当前可用的Node,使用Minikube创建的cluster只有一个Node节点

至此,我们已经用Minikube创建了一个Kubernetes Cluster,下面我们在这个集群上面部署一个应用。

Only For Chinese

在进行下一节部署具体应用前我们先要做一件事情。Kubernetes在部署容器应用的时候会先拉一个pause镜像,这个是一个基础容器,主要是负责网络部分的功能的,具体这里不展开讨论。最关键的是Kubernetes里面镜像默认都是从Google的镜像仓库拉的(就跟docker默认从docker hub拉的一样),但是因为GFW的原因,中国用户是访问不了Google的镜像仓库gcr.io的(如果你可以ping通,那恭喜你)。庆幸的是这个镜像被传到了docker hub上面,虽然中国用户访问后者也非常艰难,但通过一些加速器之类的还是可以pull下来的。如果没有VPN等科学上网的工具的话,请先做如下操作:

minikube ssh    # 登录到我们的Kubernetes VM里面去
docker pull hub.c.163.com/allan1991/pause-amd64:3.0
docker tag hub.c.163.com/allan1991/pause-amd64:3.0 gcr.io/google_containers/pause-amd64:3.0

我们先从其他镜像仓库(这里我使用的是HNA CloudOS容器云平台提供的镜像仓库)下载Kubernetes需要的基础网络容器pause,Mac OSX上面kubectl 1.5.1版本需要的是pause-amd64:3.0,然后我将其打成gcr.io/google_containers/pause-amd64:3.0。这样Kubernetes VM就不会从gcr.io拉镜像了,而是会直接使用本地的镜像。

关于这个问题,Kubernetes上面还专门有个issue讨论,有兴趣的可以看看:https://github.com/kubernetes/kubernetes/issues/6888

OK,接着我们可以进行下一步了。

Deploy an App

在Kubernetes Cluster上面部署应用,我们需要先创建一个Kubernetes Deployment。这个Deployment负责创建和更新我们的应用实例。当这个Deployment创建之后,Kubernetes master就会将这个Deployment创建出来的应用实例部署到集群内某个Node节点上。而且自应用实例创建后,Deployment controller还会持续监控应用,直到应用被删除或者部署应用的Node节点不存在。

A Deployment is responsible for creating and updating instances of your application

这里我们依旧使用kubectl来创建Deployment,创建的时候需要制定容器镜像以及我们要启动的个数(replicas),当然这些信息后面可以再更新。这里我用Go写了一个简单的Webserver,返回“Hello World”,监听端口是8090.我们就来启动这个应用(镜像地址:registry.hnaresearch.com/public/hello-world:v1.0 备用镜像地址:hub.c.163.com/allan1991/hello-world:v1.0)

kubectl run helloworld --image=registry.hnaresearch.com/public/hello-world:v1.0 --port=8090

这条命令执行后master寻找一个合适的node来部署我们的应用实例(我们只有一个node)。我们可以使用kubectl get deployment来查看我们创建的Deployment:

➜  ~ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
helloworld 1 1 1 1 53m

默认应用部署好之后是只在Kubernetes Cluster内部可见的,有多种方法可以让我们的应用暴露到外部,这里先介绍一种简单的:我们可以通过kubectl proxy命令在我们的终端和Kubernetes Cluster直接创建一个代理。然后,打开一个新的终端,通过Pod名(Pod后面会有讲到,可以通过kubectl get pod查看Pod名字)就可以访问了:

➜  ~ kubectl proxy
Starting to serve on 127.0.0.1:8001 # 打开新的终端
➜ ~ kubectl get pod
NAME READY STATUS RESTARTS AGE
helloworld-2080166056-4q88d 1/1 Running 0 1h
➜ ~ curl http://localhost:8001/api/v1/proxy/namespaces/default/pods/helloworld-2080166056-4q88d/
Hello world !

OK,我们的第一个应用已经部署成功了。如果你的应用有问题(比如kubectl get deployment执行后看到AVAILABL是0),可以通过kubectl describe pod pod名字来查看信息(最后面的Events部分是该Pod的信息),看哪里出错了。

好吧,这里我们已经提到了Pod,它是Kubernetes中一个非常重要的概念,也是区别于其他编排系统的一个设计,这里我们简单介绍一下。

Pods和Nodes

其实我们创建了Deployment之后,它并不是直接创建了容器实例,而是先在Node上面创建了Pod,然后再在Pod里面创建容器。那Pod到底是什么?Pod是Kubernetes里面抽象出来的一个概念,它是能够被创建、调度和管理的最小单元;每个Pod都有一个独立的IP;一个Pod由若干个容器构成。一个Pod之内的容器共享Pod的所有资源,这些资源主要包括:共享存储(以Volumes的形式)、共享网络、共享端口等。Kubernetes虽然也是一个容器编排系统,但不同于其他系统,它的最小操作单元不是单个容器,而是Pod。这个特性给Kubernetes带来了很多优势,比如最显而易见的是同一个Pod内的容器可以非常方便的互相访问(通过localhost就可以访问)和共享数据。

A Pod is a group of one or more application containers (such as Docker or rkt) and includes shared storage (volumes), IP address and information about how to run them.

Containers should only be scheduled together in a single Pod if they are tightly coupled and need to share resources such as disk.

Services和Labels

上一步我们已经创建了一个应用,并且通过proxy实现了集群外部可以访问,但这种Proxy的方式是不太适用于实际生产环境的。本节我们再介绍一个Kubernetes里面另外一个非常重要的概念———Service。Service是Kubernetes里面抽象出来的一层,它定义了由多个Pods组成的逻辑组(logical set),可以对组内的Pod做一些事情:

  • 对外暴露流量

  • 做负载均衡(load balancing)

  • 服务发现(service-discovery)。

而且每个Service都有一个集群内唯一的私有IP和对外的端口,用于接收流量。如果我们想将一个Service暴露到集群外,有两种方法:

  • LoadBalancer - 提供一个公网的IP

  • NodePort - 使用NAT将Service的端口暴露出去。Minikube只支持这种方式。

A Kubernetes Service is an abstraction layer which defines a logical set of Pods and enables external traffic exposure, load balancing and service discovery for those Pods.

我们再来介绍一下Kubernetes里面的第三个比较重要的概念——Label。Service就是靠Label选择器(Label Selectors)来匹配组内的Pod的,而且很多命令都可以操作Label。Label是绑定在对象上(比如Pod)的键值对,主要用来把一些相关的对象组织在一起,并且对于用户来说label是有含义的,比如:

  • Production environment (production, test, dev)

  • Application version (beta, v1.3)

  • Type of service/server (frontend, backend, database)

当然,Label是随时可以更改的。

Labels are key/value pairs that are attached to objects

接着上的例子,我们使用Service的方式将我们之前部署的helloworld应用暴露到集群外部。因为Minikube只支持NodePort方式,所以这里我们使用NodePort方式。使用kubectl get service可以查看目前已有的service,Minikube默认创建了一个kubernetes Service。我们使用expose命令再创建一个Service:

# 查看已有Service
➜ ~ kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-nginx 10.0.0.163 <pending> 80:31943/TCP 1d
helloworld 10.0.0.114 <nodes> 8090:30350/TCP 1h
kubernetes 10.0.0.1 <none> 443/TCP 1d # 创建新的Service
➜ ~ kubectl expose deployment/helloworld --type="NodePort" --port 8090
service "helloworld" exposed # 查看某个Service的详细信息
➜ ~ kubectl describe service/helloworld
Name: helloworld
Namespace: default
Labels: run=helloworld
Selector: run=helloworld
Type: NodePort
IP: 10.0.0.114
Port: <unset> 8090/TCP
NodePort: <unset> 30350/TCP
Endpoints: 172.17.0.3:8090
Session Affinity: None
No events.

这样内部应用helloworld的8090端口映射到了外部的30350端口。此时我们就可以通过外部访问里面的应用了:

➜  ~ curl 192.168.99.100:30350
Hello world !

这里的IP是minikube的Docker host的IP,可以通过minikube docker-env命令查看。再看Label的例子,创建Pod的时候默认会生产一个Label和Label Selector,我们可以使用kubectl label命令创建新的Label。

➜  ~ kubectl describe pod helloworld-2080166056-4q88d
Name: helloworld-2080166056-4q88d
Namespace: default
Node: minikube/192.168.99.100
Start Time: Tue, 10 Jan 2017 16:36:22 +0800
Labels: pod-template-hash=2080166056 # 默认的Label
run=helloworld
Status: Running
IP: 172.17.0.3
Controllers: ReplicaSet/helloworld-2080166056
Containers:
helloworld:
Container ID: docker://a45e88e7cb9fdb193a2ed62539918e293aa381d5c8fedb57ed78e54df9ea502a
Image: registry.hnaresearch.com/public/hello-world:v1.0
Image ID: docker://sha256:b3737bd8b3af68017bdf932671212be7211f4cdc47cd63b2300fbd71057ecf83
Port: 8090/TCP
State: Running
Started: Tue, 10 Jan 2017 16:36:32 +0800
Ready: True
Restart Count: 0
Volume Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-zfl0m (ro)
Environment Variables: <none>
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-zfl0m:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-zfl0m
QoS Class: BestEffort
Tolerations: <none>
No events. # 新增一个Label
➜ ~ kubectl label pod helloworld-2080166056-4q88d app=v1
pod "helloworld-2080166056-4q88d" labeled ➜ ~ kubectl describe pod helloworld-2080166056-4q88d
Name: helloworld-2080166056-4q88d
Namespace: default
Node: minikube/192.168.99.100
Start Time: Tue, 10 Jan 2017 16:36:22 +0800
Labels: app=v1 # 新增的Label
pod-template-hash=2080166056
run=helloworld
Status: Running
IP: 172.17.0.3
Controllers: ReplicaSet/helloworld-2080166056
Containers:
helloworld:
Container ID: docker://a45e88e7cb9fdb193a2ed62539918e293aa381d5c8fedb57ed78e54df9ea502a
Image: registry.hnaresearch.com/public/hello-world:v1.0
Image ID: docker://sha256:b3737bd8b3af68017bdf932671212be7211f4cdc47cd63b2300fbd71057ecf83
Port: 8090/TCP
State: Running
Started: Tue, 10 Jan 2017 16:36:32 +0800
Ready: True
Restart Count: 0
Volume Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-zfl0m (ro)
Environment Variables: <none>
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-zfl0m:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-zfl0m
QoS Class: BestEffort
Tolerations: <none>
No events. # 使用Label的例子
➜ ~ kubectl get service -l run=helloworld
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloworld 10.0.0.114 <nodes> 8090:30350/TCP 5m
➜ ~ kubectl get pod -l app=v1
NAME READY STATUS RESTARTS AGE
helloworld-2080166056-4q88d 1/1 Running 0 1d

删掉一个Service使用kubectl delete service命令:

➜  ~ kubectl delete service helloworld

删除Service后,我们就没法通过外部访问到内部应用了,但是Pod内的应用依旧是在正常运行的。

Scale an App

PS:这个Scale不知道咋翻译才好,就用scale吧。

Scaling is accomplished by changing the number of replicas in a Deployment.

刚才我们部署了一个应用,并且增加了Service。但是这个应用只运行在一个Pod上面。随着流量的增加,我们可能需要增加我们应用的规模来满足用户的需求。Kubernetes的Scale功能就可以实现这个需求。

You can create from the start a Deployment with multiple instances using the --replicas parameter for the kubectl run command

扩大应用的规模时,Kubernetes将会在Nodes上面使用可用的资源来创建新的Pod,并运行新增加的应用,缩小规模时做相反的操作。Kubernetes也支持自动规模化Pod。当然我们也可以将应用的数量变为0,这样就会终止所有部署该应用的Pods。应用数量增加后,Service内的负载均衡就会变得非常有用了,为了表现出这个特性,我修改了一下程序,除了打印“Hello world”以外,还会打印主机名。我们先看一下现有的一些输出字段的含义:

➜  ~ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
helloworld 1 1 1 1 2m

可以看到,现在我们只有一个Pod,

  • DESIRED字段表示我们配置的replicas的个数,即实例的个数。

  • CURRENT字段表示目前处于running状态的replicas的个数。

  • UP-TO-DATE字段表示表示和预先配置的期望状态相符的replicas的个数。

  • AVAILABLE字段表示目前实际对用户可用的replicas的个数。

下面我们使用kubectl scale命令将启动4个复制品,语法规则是kubectl scale deployment-type name replicas-number:‘

➜  ~ kubectl scale deployment/helloworld --replicas=4
deployment "helloworld" scaled # 查看应用实例个数
➜ ~ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
helloworld 4 4 4 4 9m # 查看Pod个数
➜ ~ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
helloworld-2080166056-fn03c 1/1 Running 0 9m 172.17.0.2 minikube
helloworld-2080166056-jlwz1 1/1 Running 0 32s 172.17.0.4 minikube
helloworld-2080166056-mmpn4 1/1 Running 0 32s 172.17.0.3 minikube
helloworld-2080166056-wh696 1/1 Running 0 32s 172.17.0.5 minikube

可以看到,我们已经有4个应用实例了,而且Pod个数也变成4个了,每个都有自己的IP。当然,日志里面也有相关信息:

➜  ~ kubectl describe deployment/helloworld
Name: helloworld
Namespace: default
CreationTimestamp: Thu, 12 Jan 2017 13:37:47 +0800
Labels: run=helloworld
Selector: run=helloworld
Replicas: 4 updated | 4 total | 4 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: helloworld-2080166056 (4/4 replicas created)
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
11m 11m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set helloworld-2080166056 to 1
2m 2m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set helloworld-2080166056 to 4

然后我们再看下之前我们创建的Service信息:

➜  ~ kubectl describe service/helloworld
Name: helloworld
Namespace: default
Labels: run=helloworld
Selector: run=helloworld
Type: NodePort
IP: 10.0.0.170
Port: <unset> 8090/TCP
NodePort: <unset> 31030/TCP
Endpoints: 172.17.0.2:8090,172.17.0.3:8090,172.17.0.4:8090 + 1 more...
Session Affinity: None
No events.

可以看到Service的信息也已经更新了。让我们验证一下这个Service是有负载均衡的:

➜  ~ curl 192.168.99.100:31030
Hello world !
hostname:helloworld-2080166056-jlwz1
➜ ~ curl 192.168.99.100:31030
Hello world !
hostname:helloworld-2080166056-mmpn4
➜ ~ curl 192.168.99.100:31030
Hello world !
hostname:helloworld-2080166056-wh696
➜ ~ curl 192.168.99.100:31030
Hello world !
hostname:helloworld-2080166056-mmpn4
➜ ~ curl 192.168.99.100:31030
Hello world !
hostname:helloworld-2080166056-wh696

接着我们将实例缩减为2个:

➜  ~ kubectl scale deployment/helloworld --replicas=2
deployment "helloworld" scaled
➜ ~ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
helloworld 2 2 2 2 18m
➜ ~ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
helloworld-2080166056-fn03c 1/1 Running 0 18m 172.17.0.2 minikube
helloworld-2080166056-wh696 1/1 Running 0 9m 172.17.0.5 minikube

Update an App

Kubernetes还提供了一个非常有用的特性——滚动更新(Rolling update),这个特性的好处就是我们不用停止服务就可以实现应用更新。默认更新的时候是一个Pod一个Pod更新的,所以整个过程服务不会中断。当然你也可以设置一次更新的Pod的百分比。而且更新过程中,Service只会将流量转发到可用的节点上面。更加重要的是,我们可以随时回退到旧版本。

Rolling updates allow Deployments' update to take place with zero downtime by incrementally updating Pods instances with new ones.
If a Deployment is exposed publicly, the Service will load-balance the traffic only to available Pods during the update.

OK,我们来实践一下。我们在原来程序的基础上,多输出一个v2作为新版本,使用set image命令指定新版本镜像。

# 使用set image命令执行新版本镜像
➜ ~ kubectl set image deployments/helloworld helloworld=registry.hnaresearch.com/public/hello-world:v2.0
deployment "helloworld" image updated
➜ ~ kubectl get pod
NAME READY STATUS RESTARTS AGE
helloworld-2080166056-fn03c 1/1 Running 0 28m
helloworld-2161692841-8psgp 0/1 ContainerCreating 0 5s
helloworld-2161692841-cmzg0 0/1 ContainerCreating 0 5s # 更新中
➜ ~ kubectl get pods
NAME READY STATUS RESTARTS AGE
helloworld-2080166056-fn03c 1/1 Running 0 28m
helloworld-2161692841-8psgp 0/1 ContainerCreating 0 20s
helloworld-2161692841-cmzg0 0/1 ContainerCreating 0 20s # 已经更新成功
➜ ~ kubectl get pods
NAME READY STATUS RESTARTS AGE
helloworld-2161692841-8psgp 1/1 Running 0 2m
helloworld-2161692841-cmzg0 1/1 Running 0 2m
➜ ~ curl 192.168.99.100:31030
Hello world v2! # 输出以变为v2
hostname:helloworld-2161692841-cmzg0

然后我们继续更新到不存在的v3版本:

➜  ~ kubectl set image deployments/helloworld helloworld=registry.hnaresearch.com/public/hello-world:v3.0
deployment "helloworld" image updated # 更新中
➜ ~ kubectl get pods
NAME READY STATUS RESTARTS AGE
helloworld-2161692841-cmzg0 1/1 Running 0 16m
helloworld-2243219626-7qhzh 0/1 ContainerCreating 0 4s
helloworld-2243219626-rfw64 0/1 ContainerCreating 0 4s # 更新时,Service只会讲请求转发到可用节点
➜ ~ curl 192.168.99.100:31030
Hello world v2!
hostname:helloworld-2161692841-cmzg0
➜ ~ curl 192.168.99.100:31030
Hello world v2!
hostname:helloworld-2161692841-cmzg0 # 因为镜像不存在,所以更新失败了。但仍然有一个Pod是可用的
➜ ~ kubectl get pod
NAME READY STATUS RESTARTS AGE
helloworld-2161692841-cmzg0 1/1 Running 0 16m
helloworld-2243219626-7qhzh 0/1 ErrImagePull 0 21s
helloworld-2243219626-rfw64 0/1 ErrImagePull 0 21s

因为我们指定了一个不存在的镜像,所以更新失败了。现在我们使用kubectl rollout undo命令回滚到之前v2的版本:

➜  ~ kubectl rollout undo deployment/helloworld
deployment "helloworld" rolled back
➜ ~ kubectl get pod
NAME READY STATUS RESTARTS AGE
helloworld-2161692841-cmzg0 1/1 Running 0 19m
helloworld-2161692841-mw9g2 1/1 Running 0 5s
➜ ~ curl 192.168.99.100:31030
Hello world v2!
hostname:helloworld-2161692841-cmzg0
➜ ~ curl 192.168.99.100:31030
Hello world v2!
hostname:helloworld-2161692841-mw9g2

结束语

Kubernetes是Google根据他们多年的生产经验以及已有系统Brog等开发的一套全新系统,虽然目前我还只是个初学者,但是能够感觉到Kubernetes在一些结构设计方面相比于其他容器编排系统有着独特的见解。至于Kubernetes是什么,官方也有比较详细的说明:https://kubernetes.io/docs/whatisk8s。后面我抽空会将这篇文章翻译一下,以加深理解。

哦,对,Kubernetes一词源于希腊语,是舵手(helmsman)、船员(pilot)的意思。因为首字母和最后一个字母中间有8个字母,所以又简称K8s。

K8S Kubernetes 简单介绍 转自 http://time-track.cn/kubernetes-trial.html Kubernetes初体验的更多相关文章

  1. Kubernetes --- 详细介绍和架构详解

    Kubernetes是一个跨主机集群的开源的容器调度平台,它可以自动化应用容器的部署,扩展和操作,提供以容器为中心的基础架构 目录 一. Kubernetes用途 二. Kubernetes特点 三. ...

  2. k8s 挂载卷介绍(四)

    kubernetes关于pod挂载卷的知识 首先要知道卷是pod资源的属性,pv,pvc是单独的资源.pod 资源的volumes属性有多种type,其中就包含有挂载pvc的类型.这也帮我理清了之间的 ...

  3. Kubernetes组件介绍

    一.api-server   基本概念 该端口默认值为6443,可通过启动参数"--secure-port"的值来修改默认值. 默认IP地址为非本地(Non-Localhost)网 ...

  4. 三十一、kubernetes网络介绍

    Kubernetes 网络介绍 Service是Kubernetes的核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上 ...

  5. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  6. 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍

    一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...

  7. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  8. yii2的权限管理系统RBAC简单介绍

    这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...

  9. angular1.x的简单介绍(二)

    首先还是要强调一下DI,DI(Denpendency Injection)伸手获得,主要解决模块间的耦合关系.那么模块是又什么组成的呢?在我看来,模块的最小单位是类,多个类的组合就是模块.关于在根模块 ...

随机推荐

  1. mybatis动态参数查询

    参考:https://blog.csdn.net/zbw18297786698/article/details/53727594

  2. SQL注入个人理解及思路(包括payload和绕过的一些方式)

    首先本文主要是把我对SQL注入的一些坑和最早学习SQL注入的时候的一些不理解的地方做一个梳理. (本文仅为个人的一点皮毛理解,如有错误还望指出,转载请说明出处,大佬勿喷=.=) 什么是SQL注入呢? ...

  3. json序列化(重要)

    (1)同(2)public JsonResult JsonUserGet() { DataSet ds = Web_User.P_LG_User_Get(nUserId); return Json(J ...

  4. js保留两位小数的数字格式化方法

    // 格式化数字(保留两位小数) numberFormat (num) { let percent = Number(num.toString().match(/^\d+(?:\.\d{0,2})?/ ...

  5. 《跟老齐学Python:从入门到精通》齐伟(编著)epub+mobi+azw3

    内容简介 <跟老齐学Python:从入门到精通>是面向编程零基础读者的Python入门教程,内容涵盖了Python的基础知识和初步应用.以比较轻快的风格,向零基础的学习者介绍一门时下比较流 ...

  6. 如果不想在django 的settings中保存mysql数据库的密码

    如题,你可以编写一个配置文件,用'OPTIONS' 将该配置文件导入进来,这样你发布到git上的源码上就没有你的数据库密码了. 这是django推荐的方法. # settings.py DATABAS ...

  7. Gradient descend 梯度下降法和归一化、python中的实现(未完善)

    梯度下降法是优化函数参数最常用.简单的算法 通常就是将一组输入样本的特征$x^i$传入目标函数中,如$f(x) = wx + b$,再计算每个样本通过函数预测的值$f(x^i)$与其真实值(标签)$y ...

  8. 二十四 Redis消息订阅&事务&持久化

    Redis数据类型: Redis控制5种数据类型:String,list,hash,set,sorted-set 添加数据,删除数据,获取数据,查看有多少个元素,判断元素是否存在 key通用操作 JR ...

  9. 【QSBOJ】字符串编辑

    题目链接:https://bbs.csdn.net/topics/390289884?page=1 AC代码: #include<bits/stdc++.h> using namespac ...

  10. vue - 动态绑定 class

    <template>   <div class="todo-item" :class="{'is-complete':todo.completed}&q ...