三、应用编排与管理:核心原理

1、资源元信息

Kubernetes的资源对象组成:主要包括了Spec、Status两部分。其中Spec部分用来描述期望的状态,Status部分用来描述观测到的状态

Kubernetes的元数据部分。该部分主要包括了用来识别资源的标签:Labels;用来描述资源的注解:Annotations;用来描述多个资源之间相互关系的OwnerReference

1)、labels

Labels是一种具有标识型的Key:Value元数据。标签主要用来筛选资源和组合资源,可以使用类似于SQL查询select,来根据Label查询相关的资源

2)、Selector

最常见的Selector就是相等型Selector

假设系统中有四个Pod,每个Pod都有标识系统层级和环境的标签,通过Tie:front这个标签,可以匹配左边栏的Pod,相等型Selector还可以包括多个相等条件,多个相等条件之间是逻辑与的关系

通过Tie=front,Env=dev的Selector,可以筛选出所有Tie=front,而且Env=dev的Pod,也就是上图中左上角的Pod。另外一种Selector是集合型Selector,在例子中,Selector筛选所有环境是test或者gray的Pod

除了in的集合操作外,还有notin集合操作,比如tie notin(front,back),将会筛选所有tie不是front且不是back的Pod。另外,也可以根据是否存在某lable的筛选,如:Selector release,筛选所有带release标签的Pod。集合型和相等型的Selector,也可以用,来连接,同样的标识逻辑与的关系

3)、Annotations

Annotations一般是系统或者工具用来存储资源的非标示性信息,可以用来扩展资源的spec/status的描述

4)、Ownereference

Ownereference一般就是指集合类的资源,比如说Pod集合,就有replicaset、statefulset

集合类资源的控制器会创建对应的归属资源。比如:replicaset控制器在操作中会创建Pod,被创建Pod的Ownereference就指向了创建Pod的replicaset,Ownereference使得用户可以方便地查找一个创建资源的对象,另外,还可以用来实现级联删除的效果

2、kubectl查看和修改Kubernetes元数据

pod1.yaml

apiVersion: v1
kind: Pod
metadata:name: nginx1namespace: defaultlabels:env: devtie: front
spec:containers:- name : nginximage: nginx:1.8ports:- containerPort: 80

pod2.yaml

apiVersion: v1
kind: Pod
metadata:name: nginx2namespace: defaultlabels:env: devtie: front
spec:containers:- name : nginximage: nginx:1.8ports:- containerPort: 80

创建两个pod

hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods
No resources found in default namespace.
hanxiantaodeMBP:yamls hanxiantao$ kubectl apply -f pod1.yaml
pod/nginx1 created
hanxiantaodeMBP:yamls hanxiantao$ kubectl apply -f pod2.yaml
pod/nginx2 created

查看所有pod的标签

hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods --show-labels
NAME     READY   STATUS    RESTARTS   AGE   LABELS
nginx1   1/1     Running   0          62s   env=dev,tie=front
nginx2   1/1     Running   0          58s   env=dev,tie=front

查看nginx1这个pod的详细信息

hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods nginx1 -o yaml | less

修改pod的label,改为env=test

hanxiantaodeMBP:yamls hanxiantao$ kubectl label pods nginx1 env=test
error: 'env' already has a value (dev), and --overwrite is false
hanxiantaodeMBP:yamls hanxiantao$ kubectl label pods nginx1 env=test --overwrite
pod/nginx1 labeled
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods --show-labels
NAME     READY   STATUS    RESTARTS   AGE     LABELS
nginx1   1/1     Running   0          5m39s   env=test,tie=front
nginx2   1/1     Running   0          5m35s   env=dev,tie=front

去掉pod的tie这个标签

hanxiantaodeMBP:yamls hanxiantao$ kubectl label pods nginx1 tie-
pod/nginx1 labeled
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods --show-labels
NAME     READY   STATUS    RESTARTS   AGE     LABELS
nginx1   1/1     Running   0          6m58s   env=test
nginx2   1/1     Running   0          6m54s   env=dev,tie=front

通过label来筛选pod

hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods --show-labels -l env=test
NAME     READY   STATUS    RESTARTS   AGE     LABELS
nginx1   1/1     Running   0          7m33s   env=test
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods --show-labels -l env=test,env=dev
No resources found in default namespace.
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods --show-labels -l env=dev,tie=front
NAME     READY   STATUS    RESTARTS   AGE    LABELS
nginx2   1/1     Running   0          8m4s   env=dev,tie=front
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods --show-labels -l 'env in (test,dev)'
NAME     READY   STATUS    RESTARTS   AGE     LABELS
nginx1   1/1     Running   0          8m36s   env=test
nginx2   1/1     Running   0          8m32s   env=dev,tie=front

添加annotate

hanxiantaodeMBP:yamls hanxiantao$ kubectl annotate pods nginx1 my-annotate='my comment, ok'
pod/nginx1 annotated
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods -o yaml | less
apiVersion: v1
kind: Pod
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"env":"dev","tie":"front"},"name":"nginx1","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.8","name":"nginx","ports":[{"containerPort":80}]}]}}my-annotate: my comment, okcreationTimestamp: "2020-12-24T00:18:18Z"labels:env: test

rs.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:name: nginx-replicasetsnamespace: defaultlabels:env: prod
spec:replicas: 2selector:matchLabels:env: prodtemplate:metadata:labels:env: prodspec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80

通过创建replicaset对象来创建pod,pod中会包含ownerReference信息

hanxiantaodeMBP:yamls hanxiantao$ kubectl apply -f rs.yaml
replicaset.apps/nginx-replicasets created
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
nginx-replicasets-ld4n6   1/1     Running   0          2m3s
nginx-replicasets-xvr6k   1/1     Running   0          2m3s
nginx1                    1/1     Running   0          27m
nginx2                    1/1     Running   0          27m
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pods nginx-replicasets-ld4n6 -o yaml | less
  name: nginx-replicasets-ld4n6namespace: defaultownerReferences:- apiVersion: apps/v1blockOwnerDeletion: truecontroller: truekind: ReplicaSetname: nginx-replicasetsuid: 5beab4c4-3aae-4c6c-a3f2-3822a2e3ba3aresourceVersion: "567337"selfLink: /api/v1/namespaces/default/pods/nginx-replicasets-ld4n6uid: 9dbcafce-72ec-4088-a0ab-3eccaba95c2d
spec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: default-token-6c86preadOnly: true

3、控制器模式

1)、控制循环

控制型模式最核心的就是控制循环的概念。在控制循环中包括了控制器,被控制的系统,以及能够观测系统的传感器,三个逻辑组件

外界通过修改资源spec来控制资源,控制器比较资源spec和status,从而计算一个diff,diff最后会用来决定执行对系统进行什么样的控制操作,控制操作会使得系统产生新的输出,并被传感器以资源status形式上报,控制器的各个组件将都会是独立自主地运行,不断使系统向spec表示终态趋近

2)、Sensor

控制循环中逻辑的传感器主要由Reflector、Informer、Indexer三个组件构成

Reflector通过List和Watch K8s server来获取资源的数据。List用来在Controller重启以及Watch中断的情况下,进行系统资源的全量更新;而Watch则在多次List之间进行增量的资源更新;Reflector在获取新的资源数据后,会在Delta队列中塞入一个包括资源对象信息本身以及资源对象事件类型的Delta记录,Delta队列中可以保证同一个对象在队列中仅有一条记录,从而避免Reflector重新List和Watch的时候产生重复的记录

Informer组件不断地从Delta队列中弹出delta记录,然后把资源对象交给indexer,让indexer把资源记录在一个缓存中,缓存在默认设置下是用资源的命名空间来做索引的,并且可以被Controller Manager或多个Controller所共享。之后,再把这个事件交给事件的回调函数

控制循环中的控制器组件主要由事件处理函数以及worker组成,事件处理函数之间会相互关注资源的新增、更新、删除的事件,并根据控制器的逻辑去决定是否需要处理。对需要处理的事件,会把事件关联资源的命名空间以及名字塞入一个工作队列中,并且由后续的worker池中的一个Worker来处理,工作队列会对存储的对象进行去重,从而避免多个Woker处理同一个资源的情况

Worker在处理资源对象时,一般需要用资源的名字来重新获得最新的资源数据,用来创建或者更新资源对象,或者调用其他的外部服务,Worker如果处理失败的时候,一般情况下会把资源的名字重新加入到工作队列中,从而方便之后进行重试

3)、控制循环例子——扩容

ReplicaSet是一个用来描述无状态应用的扩缩容行为的资源,ReplicaSet controler通过监听ReplicaSet资源来维持应用希望的状态数量,ReplicaSet中通过selector来匹配所关联的Pod,在这里考虑ReplicaSet rsA的,replicas从2被改到3的场景

首先,Reflector会watch到ReplicaSet和Pod两种资源的变化。发现ReplicaSet发生变化后,在delta队列中塞入了对象是rsA,而且类型是更新的记录

Informer一方面把新的ReplicaSet更新到缓存中,并与Namespace nsA作为索引。另外一方面,调用Update的回调函数,ReplicaSet控制器发现ReplicaSet发生变化后会把字符串的nsA/rsA字符串塞入到工作队列中,工作队列后的一个Worker从工作队列中取到了nsA/rsA这个字符串的key,并且从缓存中取到了最新的ReplicaSet数据

Worker通过比较ReplicaSet中spec和status里的数值,发现需要对这个ReplicaSet进行扩容,因此ReplicaSet的Worker创建了一个Pod,这个pod中的Ownereference取向了ReplicaSet rsA

然后Reflector Watch到的Pod新增事件,在delta队列中额外加入了Add类型的deta记录,一方面把新的Pod记录通过Indexer存储到了缓存中,另一方面调用了ReplicaSet控制器的Add回调函数,Add回调函数通过检查pod ownerReferences找到了对应的ReplicaSet,并把包括ReplicaSet命名空间和字符串塞入到了工作队列中

ReplicaSet的Woker在得到新的工作项之后,从缓存中取到了新的ReplicaSet记录,并得到了其所有创建的Pod,因为ReplicaSet的状态不是最新的,也就是所有创建Pod的数量不是最新的。因此在此时ReplicaSet更新status使得spec和status达成一致

4、控制器模式总结

Kubernetes所采用的控制器模式,是由声明式API驱动的。确切来说,是基于对Kubernetes资源对象的修改来驱动的

Kubernetes资源之后,是关注该资源的控制器。这些控制器将异步的控制系统向设置的终态驱近

这些控制器是自主运行的,使得系统的自动化和无人值守成为可能

因为Kubernete的控制器和资源都是可以自定义的,因此可以方便的扩展控制器模式。特别是对于有状态应用,我们往往通过自定义资源和控制器的方式,来自动化运维操作。这个也就是operator的场景

四、应用编排与管理:Deployment

1、需求来源

如果直接管理集群中所有的Pod,应用A、B、C的Pod,其实是散乱地分布在集群中

现在有以下的问题:

  • 首先,如何保证集群内可用Pod的数量?也就是说我们应用A四个Pod如果出现了一些宿主机故障,或者一些网络问题,如何能保证它可用的数量?
  • 如何为所有Pod更新镜像版本?我们是否要某一个Pod去重建新版本的Pod?
  • 然后在更新过程中,如何保证服务的可用性?
  • 以及更新过程中,如果发现了问题,如何快速回滚到上一个版本?

通过Deployment将应用A、B、C分别规划到不同的Deployment中,每个Deployment其实是管理的一组相同的应用Pod,这组Pod我们认为它是相同的一个副本,那么Deployment能帮我们做什么事情呢?

1)首先,Deployment定义了一种Pod期望数量,比如说应用A,我们期望Pod数量是四个,那么这样的话,controller就会持续维持Pod数量为期望的数量。当我们与Pod出现了网络问题或者宿主机问题的话,controller能帮我们恢复,也就是新扩出来对应的Pod,来保证可用的Pod数量与期望数量一致

2)配置Pod发布方式,也就是说controller会按照用户给定的策略来更新Pod,而且更新过程中,也可以设定不可用Pod数量在多少范围内

3)如果更新过程中发生问题的话,即所谓一键回滚,也就是说你通过一条命令或者一行修改能够将Deployment下面所有Pod更新为某一个旧版本

2、用例解读

1)、Deployment语法

apiVersion:apps/v1,也就是说Deployment当前所属的组是apps,版本是v1

Deployment作为一个K8s资源,它有自己的metadata元信息,这里定义的Deployment.name是nginx-deployment

Deployment.spec中首先要有一个核心的字段,即replicas,这里定义期望的Pod数量为三个;selector其实是Pod选择器,那么所有扩容出来的Pod,它的Labels必须匹配selector层上的image.labels,也就是app:nginx

2)、查看Deployment状态

可以通过kubectl get deployment,看到Deployment总体的一个状态

  • DESIRED:期望的Pod数量是3个
  • CURRENT:当前实际Pod数量是3个
  • UP-TO-DATE:其实是到达最新的期望版本的Pod数量
  • AVAILABLE:这个其实是运行过程中可用的Pod数量。这里AVAILABLE并不简单是可用的,也就是Ready状态的,它其实包含了一些可用超过一定时间长度的Pod
  • AGE:deployment创建的时长,如上图Deployment就是已经创建了80分钟

3)、查看Pod

Pod名字格式最前面一段:nginx-deployment,其实是Pod所属 Deployment.name;中间一段:template-hash,这里三个Pod是一样的,因为这三个Pod其实都是同一个template中创建出来的;最后一段,是一个random的字符串

通过get.pod可以看到,Pod的ownerReferences即Pod所属的controller资源,并不是Deployment,而是一个ReplicaSet。这个ReplicaSet的name,其实是nginx-deployment加上pod.template-hash。所有的Pod都是ReplicaSet创建出来的,而ReplicaSet它对应的某一个具体的Deployment.template版本

4)、更新镜像

首先kubectl后面有一个set image固定写法,这里指的是设定镜像;其次是一个deployment.v1.apps,这里也是一个固定写法,写的是我们要操作的资源类型,deployment是资源名、v1是资源版本、apps是资源组,这里也可以简写为deployment或者deployment.apps,比如说写为deployment的时候,默认将使用apps组v1版本

第三部分是要更新的deployment的name,也就是我们的nginx-deployment;再往后的nginx其实指的是template,也就是Pod中的container.name;这里可以注意到:一个Pod中,其实可能存在多个container,而我们指定想要更新的镜像的container.name,就是nginx

最后,指定我们这个容器期望更新的镜像版本,这里指的是nginx: 1.9.1。如上图所示:当执行完这条命令之后,可以看到deployment中的template.spec已经更新为nginx: 1.9.1

5)、快速回滚

通过kubectl执行的话,其实是kubectl rollout undo这个命令,可以回滚到Deployment上一版本;通过rollout undo加上to-revision来指定可以回滚到某一个具体的版本

6)、DeploymeStatus

deploymentStatus中描述的三个其实是它的conversion状态,也就是Processing、Complete以及Failed

以Processing为例:Processing指的是Deployment正在处于扩容和发布中。比如说Processing状态的deployment,它所有的replicas及Pod副本全部达到最新版本,而且是available,这样的话,就可以进入complete状态。而complete状态如果发生了一些扩缩容的话,也会进入processing这个处理工作状态

如果在处理过程中遇到一些问题:比如说拉镜像失败了,或者说readiness probe检查失败了,就会进入failed状态;如果在运行过程中即complete状态,中间运行时发生了一些pod readiness probe检查失败,这个时候deployment也会进入failed状态。进入failed状态之后,除非所有点replicas均变成available,而且是updated最新版本,deployment才会重新进入complete状态

3、操作演示

deployment-case.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentlabels:app: nginx
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80
hanxiantaodeMBP:yamls hanxiantao$ kubectl create -f deployment-case.yaml
deployment.apps/nginx-deployment created
hanxiantaodeMBP:yamls hanxiantao$ kubectl get deployment nginx-deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           15s
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5d59d67564-528s8   1/1     Running   0          30s
nginx-deployment-5d59d67564-6znl8   1/1     Running   0          30s
nginx-deployment-5d59d67564-q47cp   1/1     Running   0          30s
hanxiantaodeMBP:yamls hanxiantao$ kubectl get replicaset
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5d59d67564   3         3         3       99s

升级nginx为nginx:1.9.1

hanxiantaodeMBP:yamls hanxiantao$ kubectl set image deployment nginx-deployment nginx=nginx:1.9.1
deployment.apps/nginx-deployment image updated
hanxiantaodeMBP:yamls hanxiantao$ kubectl edit deployment nginx-deployment
  template:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:1.9.1imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30
hanxiantaodeMBP:yamls hanxiantao$ kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-69c44dfb78-6v2gv   1/1     Running   0          2m2s
nginx-deployment-69c44dfb78-gzbnf   1/1     Running   0          83s
nginx-deployment-69c44dfb78-j7wwl   1/1     Running   0          85s
hanxiantaodeMBP:yamls hanxiantao$ kubectl get replicaset
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5d59d67564   0         0         0       8m33s
nginx-deployment-69c44dfb78   3         3         3       5m47s

回滚到上一版本

hanxiantaodeMBP:yamls hanxiantao$ kubectl rollout undo deployment nginx-deployment
deployment.apps/nginx-deployment rolled back
hanxiantaodeMBP:yamls hanxiantao$ kubectl get replicaset
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5d59d67564   3         3         3       12m
nginx-deployment-69c44dfb78   0         0         0       9m15s

4、架构设计

1)、管理模式

Deployment只负责管理不同版本的ReplicaSet,由ReplicaSet来管理具体的Pod副本数,每个ReplicaSet对应Deployment template的一个版本

如上图所示:Deployment创建ReplicaSet,而ReplicaSet创建Pod。他们的OwnerRef其实都对应了其控制器的资源

2)、Deployment控制器

所有的控制器都是通过Informer中的Event 做一些Handler和Watch。这个地方Deployment控制器,其实是关注Deployment和ReplicaSet中的event,收到事件后会加入到队列中。而Deployment controller从队列中取出来之后,它的逻辑会判断Check Paused,这个Paused其实是Deployment是否需要新的发布,如果Paused设置为true的话,就表示这个Deployment只会做一个数量上的维持,不会做新的发布

如果Check paused为Yes也就是true的话,那么只会做Sync replicas。也就是说把replicas sync同步到对应的ReplicaSet 中,最后再Update Deployment status,那么controller这一次的ReplicaSet就结束了

如果paused为false的话,它就会做Rollout,也就是通过Create或者是Rolling的方式来做更新,更新的方式其实也是通过Create/Update/Delete这种ReplicaSet来做实现的

3)、ReplicaSet控制器

当Deployment分配ReplicaSet之后,ReplicaSet控制器本身也是从Informer中watch一些事件,这些事件包含了ReplicaSet和Pod的事件。从队列中取出之后,ReplicaSet controller的逻辑很简单,就只管理副本数。也就是说如果controller发现replicas比Pod数量大的话,就会扩容,而如果发现实际数量超过期望数量的话,就会删除Pod

上面Deployment控制器的图中可以看到,Deployment控制器其实做了更复杂的事情,包含了版本管理,而它把每一个版本下的数量维持工作交给ReplicaSet来做

4)、扩容模拟

有一个Deployment,它的副本数是2,对应的ReplicaSet有Pod1和Pod2。这时如果我们修改Deployment replicas, controller就会把replicas同步到当前版本的ReplicaSet中,这个ReplicaSet发现当前有2个Pod,不满足当前期望3个,就会创建一个新的Pod3

5)、发布模拟

Deployment当前初始的template,比如说template1这个版本。template1这个ReplicaSet对应的版本下有三个Pod:Pod1,Pod2,Pod3

这时修改template中一个容器的image, Deployment controller就会新建一个对应template2的ReplicaSet。创建出来之后ReplicaSet会逐渐修改两个ReplicaSet的数量,比如它会逐渐增加ReplicaSet2中replicas的期望数量,而逐渐减少ReplicaSet1中的Pod数量

那么最终达到的效果是:新版本的Pod为Pod4、Pod5和Pod6,旧版本的Pod已经被删除了,这里就完成了一次发布

6)、回滚模拟

回滚模拟,根据上面的发布模拟可以知道Pod4、Pod5、Pod6已经发布完成。这时发现当前的业务版本是有问题的,如果做回滚的话,不管是通过rollout命令还是通过回滚修改template,它其实都是把template回滚为旧版本的template1

这个时候Deployment会重新修改ReplicaSet1中Pod的期望数量,把期望数量修改为3个,且会逐渐减少新版本也就是ReplicaSet2中的replica数量,最终的效果就是把Pod从旧版本重新创建出来

发布模拟的图中可以看到,其实初始版本中Pod1、Pod2、Pod3是旧版本,而回滚之后其实是Pod7、Pod8、Pod9。就是说它的回滚并不是把之前的Pod重新找出来,而是说重新创建出符合旧版本template的Pod

7)、spec字段解析

8)、升级策略字段解析

课程地址:https://edu.aliyun.com/roadmap/cloudnative?spm=5176.11399608.aliyun-edu-index-014.4.dc2c4679O3eIId#suit

云原生技术公开课学习笔记:应用编排与管理:核心原理、Deployment相关推荐

  1. “云原生”技术公开课第1章:第一堂“云原生”课

    摘要:欢迎大家来到阿里云与 CNCF 共同推出的"云原生"技术公开课.本文整理自"云原生"技术公开课的开篇:第一堂"云原生"课.在本文中,阿 ...

  2. 阿里巴巴云原生技术公开课文案:课时 1:第一堂“云原生”课(转载只为自学)

    课时 1:第一堂"云原生"课 本节课程要点 云原生技术发展历程(为什么要学习这门课) 课程简介与预备知识(这门课到底教什么) 云原生的定义与技术要点(本节正式内容) 为什么要开设云 ...

  3. CNCF X 阿里巴巴云原生技术公开课

    课程内容 课程介绍 为什么要开设云原生技术公开课? 在 2019 年,阿里巴巴宣布要全面上云,而且"上云就要上云原生".我们还可以看到,以"云"为核心的软件研发 ...

  4. cncf java_《CNCF × Alibaba 云原生技术公开课》正式首播

    课时1:第一堂"云原生"课 了解云原生的概念.本质.主流技术等 课时2:容器基本概念 掌握容器.容器镜像.容器数据卷等基本概念 课时3:Kubernetes 核心概念与 API 原 ...

  5. 传智播客c/c++公开课学习笔记--Linux网络流媒体服务器的核心代码揭秘

    Xinetd 从守护进程的概念可以看出,对于系统所要通过的每一种服务,都必须运行一个监听某个端口连接所发生的守护进程, 这通常意味着资源浪费. 为了解决这个问题,Linux引进了"网络守护进 ...

  6. 【华为云专家技术公开课】7月4日直播,报名观看赢取好礼

    [导语]新手大咖齐相聚,畅谈云端新科技.2019年7月4日,华为云专家技术公开课直播将在云视界进行线上直播,本期华为云MVP.敏捷创新教练王立杰将就<敏捷项目管理的关键点>进行深入讲解,让 ...

  7. 英宝通Unity4.0公开课学习笔记Vol.0

    英宝通Unity4.0公开课学习笔记 公开课地址 学习笔记目录 公开课地址 公开课地址:游戏蛮牛网. 源码素材:游戏蛮牛网. 公开课在官网上刷新不出来,只能去B站上找资源了.视频链接:哔哩哔哩. Un ...

  8. 云原生技术赋能联邦学习

    题图:望京升明月,中秋节摄于北京奥林匹克观光塔 (本文作者系 VMware 中国研发云原生实验室架构师,联邦学习 KubeFATE / FATE 开源项目维护者和贡献者.) 相关信息: 招聘云原生开发 ...

  9. KubeFATE: 用云原生技术赋能联邦学习(一)

    题图摄于北海公园 联邦学习是AI领域一个新兴的方向,被认为是 AI 领域最重要的研究和应用趋势之一.联邦学习可在用户之间进行联合建模,构造精确的人工智能模型,同时数据不用离开机构,可以保证双方数据的隐 ...

最新文章

  1. Meteor:发布与订阅
  2. 人月神话阅读笔记03
  3. php 怎么获取meta标签,php – 通过jQuery获取META描述
  4. c语言 char转int_图文并茂,一文讲透C语言结构体内存对齐
  5. scala中给集合创建懒加载view视图
  6. linux高亮查找关键字
  7. 移动最小二乘_最小移动以形成弦
  8. openstack社区_OpenStack社区中发生了什么?
  9. 单片机语音识别源码与资料(ASR M08-B模块arduino与51驱动)
  10. mysql 省市县三级联动查询_三级联动查询全国省市区(xml与数据库)
  11. win10下使用mklink命令给C盘软件搬家
  12. ISP模块之RAW DATA去噪(一)
  13. Deeping_Learning 02
  14. CSDN、博文视点名家讲坛之夏昕、林信良谈Spring框架
  15. Jlink 接口定义
  16. 随机森林回归树官方例子小结
  17. 比原链CEO朗豫:DeFi让用户真正理解区块链,意义重大
  18. RabbitMQ可视化界面登录不了,报错:Login failed
  19. 基于Vue的图片裁剪 vue-cropper
  20. 【C语言程序】某班级学习委员整理获得奖学金排名,总成绩=智育成绩*60%+德育成绩*30%+体育成绩*10%,使用冒泡排序法将班级前12名同学的成绩进行排名。

热门文章

  1. 刘强东发飙:不要跟我空谈毛利率 京东不会死!
  2. Linux网络学习与总结(1)
  3. 科技公司薪酬排行榜:思科人均超12万美元居首
  4. AI企划-《大明镇抚司到此一游》商业计划书
  5. Java项目精选|Java毕业设计项目源码
  6. 2018 Multi-University Training Contest 4__全部题解+标程
  7. 2023年5月青少年软件编程(Python) 等级考试试卷(一级)
  8. Spider-Man IG-impostors: cityscapes and beyond翻译
  9. 如何用tableau画桑基图(决策树)
  10. vm虚拟机安装ubuntu12.04配置安卓虚拟机