写点什么

使用 Kubernetes 来管理 Docker 扩展

  • 2015-10-26
  • 本文字数:10274 字

    阅读完需:约 34 分钟

Kubernetes 是一款开源的项目,管理 Linux 容器集群,并可将集群作为一个单一的系统来对待。其可跨多主机来管理和运行 Docker 容器、提供容器的定位、服务发现以及复制控制。它由 Google 发起,现在得到了如微软、红帽、IBM 和Docker 等众多厂商的支持。

Google 使用容器技术有着超过十年的历史,每周要启动超过2 亿台容器。通过Kubernetes,Google 分享了他们关于容器的专业经验,即创建大规模运行容器的开放平台。

一旦用户开始使用Docker 容器,那么问题就来了,一、如何跨多个Docker 主机扩展和启动容器,且能够在主机间平衡这些容器。二、还需要高度抽象出API 来定义如何从逻辑上组织容器、定义容器池、负载均衡以及关联性。该项目就是为了解决这两个问题而生的。

Kubernetes 仍然处于早期阶段,这也就意味着会有很多新的变化进入到该项目,目前还仅有比较简单的实例,仍需要加入新的功能,但是它正在一步一步地平稳发展,也得到了很多大公司的支持,前途无量。

Kubernetes 概念

Kubernetes 的架构被定义为由一个 master 服务器和多个 minons 服务器组成。命令行工具连接到 master 服务器的 API 端点,其可以管理和编排所有的 minons 服务器,Docker 容器接收来自 master 服务器的指令并运行容器。

  • Master:Kubernetes API 服务所在,多 Master 的配置仍在开发中。
  • Minons:每个具有 Kubelet 服务的 Docker 主机,Kubelet 服务用于接收来自 Master 的指令,且管理运行容器的主机。
  • Pod :定义了一组绑在一起的容器,可以部署在同一 Minons 中,例如一个数据库或者是 web 服务器。
  • Replication controller :定义了需要运行多少个 Pod 或者容器。跨多个 minons 来调度容器。
  • Service:定义了由容器所发布的可被发现的服务/端口,以及外部代理通信。服务会映射端口到外部可访问的端口,而所映射的端口是跨多个 minons 的 Pod 内运行的容器的端口。
  • kubecfg:命令行客户端,连接到 master 来管理 Kubernetes。

(点击图片可放大显示)

Kubernetes 由状态所定义,而不是进程。当你定义了一个 pod 时,Kubernetes 会设法确保它会一直运行。如果其中的某个容器挂掉了,Kubernetes 会设法再启动一个新的容器。如果一个复制控制器定义了 3 份复制,Kubernetes 会设法一直运行这 3 份,根据需要来启动和停止容器。

本文中所用的例子应用是 Jenkins 持续集成服务,Jenkins 是典型的通过主从服务来建立分布式的工作任务的例子。Jenkins 由 jenkins swarm 插件来配置,运行一个 jenkins 主服务和多个 jenkins 从服务,所有的 Jenkins 服务都以 Docker 容器的方式跨多个主机运行。swarm 从服务在启动时连接到 Jenkins 主服务,然后就可以运行 Jenkins 任务了。例子中使用的配置文件可以从Github 上下载到,而该Docker 镜像可以从 casnchez/jenkins-swarm 获取,对于 Jenkins 主服务来说,可以通过 swarm 插件来扩展官方 Jenkins 镜像。对于 jenkins 从服务来说,可以从 csanchez/jenkins-swarm-slave 获取,它只是在 JVM 容器中运行了 jenkins 从服务而已。

创建 Kubernetes 集群

Kubernetes 提供了多个操作系统和云/虚拟化提供商下创建集群的脚本,有 Vagrant(用于本地测试)、Google Compute Engine、Azure、Rackspace 等。

本文所实践的例子就是运行在 Vagrant 之上的本地集群,使用 Fedora 作为操作系统,遵照的是官方入门指南,测试的 Kubernetes 版本是 0.5.4。取代了默认的 3 个 minion(Docker 主机),而是使用了 2 个 minion,两台主机就足以展示 Kubernetes 的能力了,三台有点浪费。

当你下载了 Kubernetes ,然后将至解压后,即可在本地的目录下运行这些示例了。初学者创建集群仅需要一个命令,即./cluster/kube-up.sh。

复制代码
$ export KUBERNETES_PROVIDER=vagrant
$ export KUBERNETES_NUM_MINIONS=2
$ ./cluster/kube-up.sh

获取示例配置文件:

复制代码
$ git clone https://github.com/carlossg/kubernetes-jenkins.git

集群创建的快慢取决于机器的性能和内部的带宽。但是其最终完成不能有任何的错误,而且它仅需要运行一次。

命令行工具

和 Kubernetes 交互的命令行工具叫做 kubecfg,此脚本位于 cluster/kubecfg.sh。

为了检验我们刚才创建的两个 minons 已经启动并运行了,只需运行 kubecfg list minions 命令即可,它的结果会显示 Vagrant 的两台虚拟机。

复制代码
$ ./cluster/kubecfg.sh list minions
Minion identifier
----------
10.245.2.2
10.245.2.3

Pod

在 Kubernetes 的术语中,Jenkins 主服务被定义为一个 pod 。在一个 pod 中可以指定多个容器,这些容器均部署在同一 Docker 主机中,在一个 pod 中的容器的优势在于可以共享资源,例如存储,而且使用相同的网络命名空间和IP 地址。默认的卷是空的目录,类型为emptyDir,它的生存时间就是pod 的生命周期,而并非是指定的容器,所以如果一个容器失效了,但是其持久性的存储仍然在。另外一个卷的类型是hostDir,它是将主机的一个目录挂载到容器中。

在这个具体的Jenkins 示例中,我们所创建的pod 是两个容器,分别是Jenkins 主服务和MySQL,前者作为实例,后者作为数据库。然而我们只需要关心jenkins 主服务容器即可。

为了创建一个Jenkins pod,我们运行定义了Jenkins 容器pod 的kubecfg,使用Docker 镜像csanchez/jenkins-swarm,为了能够访问Jenkins 的Web 界面和从服务的API,我们将主机的端口8080 和50000 映射到容器,以及将/var/jenkins_home 挂载为卷。读者可从 Github 下载到示例代码。

Jenkins Web 界面的 pod(pod.json)的定义如下:

复制代码
{
"id": "jenkins",
"kind": "Pod",
"apiVersion": "v1beta1",
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "jenkins",
"containers": [
{
"name": "jenkins",
"image": "csanchez/jenkins-swarm:1.565.3.3",
"ports": [
{
"containerPort": 8080,
"hostPort": 8080
},
{
"containerPort": 50000,
"hostPort": 50000
}
],
"volumeMounts": [
{
"name": "jenkins-data",
"mountPath": "/var/jenkins_home"
}
]
}
],
"volumes": [
{
"name": "jenkins-data",
"source": {
"emptyDir": {}
}
}
]
}
},
"labels": {
"name": "jenkins"
}
}

然后使用下面命令来创建:

复制代码
$ ./cluster/kubecfg.sh -c kubernetes-jenkins/pod.json create pods
Name Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
jenkins csanchez/jenkins-swarm:1.565.3.3 <unassigned> name=jenkins Pending</unassigned>

这需要等待一段时间,具体时间的长短要视你的网络而定,因为它会从 Docker Hub 上下载 Docker 镜像到 minion,我们可以查看它的状态,以及在那个 minion 中启动了。

复制代码
$ ./cluster/kubecfg.sh list pods
Name Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
jenkins csanchez/jenkins-swarm:1.565.3.3 10.0.29.247/10.0.29.247 name=jenkins Running

如果我们使用 SSH 登录到 minion 中,此 minion 即是 pod 被分配到的 minion-1 或 minion-2,我们就可以看到 Docker 按照所定义的那样启动起来了。其中还包括了用于 Kubernetes 内部管理的容器(kubernetes/pause 和 google/cadvisor)。

复制代码
$ vagrant ssh minion-2 -c "docker ps"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f6825a80c8a google/cadvisor:0.6.2 "/usr/bin/cadvisor" 3 minutes ago Up 3 minutes k8s_cadvisor.b0dae998_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0.default.file_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0_28df406a
5c02249c0b3c csanchez/jenkins-swarm:1.565.3.3 "/usr/local/bin/jenk 3 minutes ago Up 3 minutes k8s_jenkins.f87be3b0_jenkins.default.etcd_901e8027-759b-11e4-bfd0-0800279696e1_bf8db75a
ce51fda15f55 kubernetes/pause:go "/pause" 10 minutes ago Up 10 minutes k8s_net.dbcb7509_0d38f5b2-759c-11e4-bfd0-0800279696e1.default.etcd_0d38fa52-759c-11e4-bfd0-0800279696e1_e4e3a40f
e6f00165d7d3 kubernetes/pause:go "/pause" 13 minutes ago Up 13 minutes 0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp k8s_net.9eb4a781_jenkins.default.etcd_901e8027-759b-11e4-bfd0-0800279696e1_7bd4d24e
7129fa5dccab kubernetes/pause:go "/pause" 13 minutes ago Up 13 minutes 0.0.0.0:4194->8080/tcp k8s_net.a0f18f6e_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0.default.file_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0_659a7a52

还有,我们一旦拿到了容器的 ID,就可以通过如 vagrant ssh minion-1 -c "docker logs cec3eab3f4d3"这样的命令来查看容器的日志了。

我们也可以访问 Jenkins 的 Web 界面,至于要访问的 URL 是 http://10.245.2.2:8080/ 还是 http://10.0.29.247:8080/,要看用到了那个 minion。

服务发现

Kubernetes 支持定义服务,一种为容器使用发现和代理请求到合适的 pod 的方法。下面示例使用了 service-http.json 文件来创建一个服务,其将 id 为 jenkins 指向了贴有标签为 name=jenkins 的 pod。而标签是在如上面 pod 的定义中所声明的。且将端口 8888 重定向到容器的 8080 。

复制代码
{
"id": "jenkins",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 8888,
"containerPort": 8080,
"selector": {
"name": "jenkins"
}
}

使用 kubecfg 来创建服务:

复制代码
$ ./cluster/kubecfg.sh -c kubernetes-jenkins/service-http.json create services
Name Labels Selector IP Port
---------- ---------- ---------- ---------- ----------
jenkins name=jenkins 10.0.29.247 8888

每个服务都会被分配一个唯一的 IP 地址,且此 IP 地址会伴随服务的整个生命周期。如果我们有多个 pod 匹配服务的定义,服务就会在所有它们之上提供负载均衡。

服务的另外一个特性是可以为由 Kubernetes 来运行的容器设置一些环境变量,使其可以连接到该服务容器,这和运行已链接的 Docker 容器有些类似,它可以帮助我们从若干从服务中找到 Jenkins 主服务。

复制代码
JENKINS_PORT='tcp://10.0.29.247:8888'
JENKINS_PORT_8080_TCP='tcp://10.0.29.247:8888'
JENKINS_PORT_8080_TCP_ADDR='10.0.29.247'
JENKINS_PORT_8080_TCP_PORT='8888'
JENKINS_PORT_8080_TCP_PROTO='tcp'
JENKINS_SERVICE_PORT='8888'
SERVICE_HOST='10.0.29.247'

在此示例中,我们还需要打开端口 50000,Jenkins swarm 插件需要用这个端口。我们创建另外一个 service-slave.json 文件,这样 Kubernetes 就可以重定向端口到 Jenkins 服务容器了。

复制代码
{
"id": "jenkins-slave",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 50000,
"containerPort": 50000,
"selector": {
"name": "jenkins"
}
}

再次使用 kubecfg 来创建:

复制代码
$ ./cluster/kubecfg.sh -c kubernetes-jenkins/service-slave.json create services
Name Labels Selector IP Port
---------- ---------- ---------- ---------- ----------
jenkins-slave name=jenkins 10.0.86.28 50000

列出所有可用的已经定义的服务,包括一些 Kubernetes 内部的服务:

复制代码
$ ./cluster/kubecfg.sh list services
Name Labels Selector IP Port
---------- ---------- ---------- ---------- ----------
kubernetes-ro component=apiserver,provider=kubernetes 10.0.22.155 80
kubernetes component=apiserver,provider=kubernetes 10.0.72.49 443
jenkins name=jenkins 10.0.29.247 8888
jenkins-slave name=jenkins 10.0.86.28 50000

复制控制器

复制控制器允许在多个 minion 中运行多个 pod。Jenkins 的从服务以此方式来运行,可以确保一直有一个运行 Jenkins 任务的从服务池。

创建 replication.json,所定义的内容如下:

复制代码
{
"id": "jenkins-slave",
"apiVersion": "v1beta1",
"kind": "ReplicationController",
"desiredState": {
"replicas": 1,
"replicaSelector": {
"name": "jenkins-slave"
},
"podTemplate": {
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "jenkins-slave",
"containers": [
{
"name": "jenkins-slave",
"image": "csanchez/jenkins-swarm-slave:1.21",
"command": [
"sh", "-c", "/usr/local/bin/jenkins-slave.sh
-master http://$JENKINS_SERVICE_HOST:$JENKINS_SERVICE_PORT -tunnel
$JENKINS_SLAVE_SERVICE_HOST:$JENKINS_SLAVE_SERVICE_PORT -username
jenkins -password jenkins -executors 1"
]
}
]
}
},
"labels": {
"name": "jenkins-slave"
}
}
},
"labels": {
"name": "jenkins-slave"
}
}

podTemplate 一节允许和 pod 的定义进行一样的配置。在此示例中,我们打算让 Jenkins 从服务自动地连接到 Jenkins 主服务,而不是利用 Jenkins 主服务的多播发现。要实现此想法,我们需要执行 jenkins-slave.sh 命令,指定参数 -master,从而实现在 Kubernetes 中让从服务连接到主服务。注意,上述配置文件中,我们使用了 Kubernetes 所提供的为 Jenkins 服务定义的环境变量(JENKINS_SERVICE_HOST 和 JENKINS_SERVICE_PORT)。此方法中镜像的命令覆盖了容器的配置,为的是利用已经下载好的镜像。这也同样可以在 pod 的定义中去实现。

使用 kubecfg 来创建副本:

复制代码
$ ./cluster/kubecfg.sh -c kubernetes-jenkins/replication.json create replicationControllers
Name Image(s) Selector Replicas
---------- ---------- ---------- ----------
jenkins-slave csanchez/jenkins-swarm-slave:1.21 name=jenkins-slave 1

现在执行 pod 列表,可以看到新的 pod 已经创建,其数量是由我们刚刚所定义的复制控制器所决定的。

复制代码
$ ./cluster/kubecfg.sh list pods
Name Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
jenkins csanchez/jenkins-swarm:1.565.3.3 10.245.2.3/10.245.2.3 name=jenkins Running
07651754-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.2/10.245.2.2 name=jenkins-slave Pending

第一次运行的 jenkins-swarm-slave 镜像是 minion 从 Docker 仓库下载下来的,但是一段时间之后(这取决于你的互联网连接),Jenkins 从服务会自动连接到 Jenkins 主服务。登录到 Jenkins 从服务所在的服务器,docker ps 会显示出运行中的容器和 Docker 的日志,这能够帮助你来调试容器启动中出现的问题。

复制代码
$ vagrant ssh minion-1 -c "docker ps"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
870665d50f68 csanchez/jenkins-swarm-slave:1.21 "/usr/local/bin/jenk About a minute ago Up About a minute k8s_jenkins-slave.74f1dda1_07651754-4f88-11e4-b01e-0800279696e1.default.etcd_11cac207-759f-11e4-bfd0-0800279696e1_9495d10e
cc44aa8743f0 kubernetes/pause:go "/pause" About a minute ago Up About a minute k8s_net.dbcb7509_07651754-4f88-11e4-b01e-0800279696e1.default.etcd_11cac207-759f-11e4-bfd0-0800279696e1_4bf086ee
edff0e535a84 google/cadvisor:0.6.2 "/usr/bin/cadvisor" 27 minutes ago Up 27 minutes k8s_cadvisor.b0dae998_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0.default.file_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0_588941b0
b7e23a7b68d0 kubernetes/pause:go "/pause" 27 minutes ago Up 27 minutes 0.0.0.0:4194->8080/tcp k8s_net.a0f18f6e_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0.default.file_cadvisormanifes12uqn2ohido76855gdecd9roadm7l0_57a2b4de

复制控制器可以自动的调整任何想要的副本数量:

复制代码
$ ./cluster/kubecfg.sh resize jenkins-slave 2

再次列出 pod 的话,可以看到每个副本是在哪里运行的。

复制代码
$ ./cluster/kubecfg.sh list pods
Name Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
07651754-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.2/10.245.2.2 name=jenkins-slave Running
a22e0d59-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.3/10.245.2.3 name=jenkins-slave Pending
jenkins csanchez/jenkins-swarm:1.565.3.3 10.245.2.3/10.245.2.3 name=jenkins Running

调度

目前默认的调度是随机的,但是基于资源的调度很快就将实现了。在写作本文的时候,基于内存和 CPU 利用率的调度还有一些没有修复的问题。还有整合 Apache Mesos 的调度也在紧锣密鼓的进行中。Apache Mesos 是一款分布式系统的框架,提供了资源管理的 API,和跨整个数据中心或云环境的调度。

自愈

使用 Kubernetes 的一大好处就是其能够自动管理和修复容器。

如果运行 Jenkins 服务的容器由于某些原因宕机了,比如说进程崩溃了,那么 Kubernetes 就会得到通知,并会在几秒钟之后创建一个新的容器。

复制代码
$ vagrant ssh minion-2 -c 'docker kill `docker ps | grep csanchez/jenkins-swarm: | sed -e "s/ .*//"`'
51ba3687f4ee
$ ./cluster/kubecfg.sh list pods
Name Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
jenkins csanchez/jenkins-swarm:1.565.3.3 10.245.2.3/10.245.2.3 name=jenkins Failed
07651754-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.2/10.245.2.2 name=jenkins-slave Running
a22e0d59-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.3/10.245.2.3 name=jenkins-slave Running

稍后再执行 list pod 命令,一般不会超过 1 分钟,会看到如下内容:

复制代码
Name Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
jenkins csanchez/jenkins-swarm:1.565.3.3 10.245.2.3/10.245.2.3 name=jenkins Running
07651754-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.2/10.245.2.2 name=jenkins-slave Running
a22e0d59-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.3/10.245.2.3 name=jenkins-slave Running

将 Jeknkis 的数据目录以卷的形式运行,我们保证了在容器宕机之后仍然能够保留数据,所以不会丢失任何 Jenkins 的任务或者是已经创建好的数据。而且因为 Kubernetes 在每个 minion 都代理了服务,Jenkins 从服务会自动连接到 Jenkins 主服务,而根本无须关心它是在哪里运行的!而且 Jenkins 从服务容器宕掉,系统也会自动创建新的容器,服务发现会将之自动加入到 Jenkins 服务池中。

如果发生了更加严重的情况,比如 minion 挂掉了,Kubernetes 目前还没能提供将现有容器重新调度到其它仍在运行的 minion 中的能力,它仅仅会显示某个 pod 失效,如下所示:

复制代码
$ vagrant halt minion-2
==> minion-2: Attempting graceful shutdown of VM...
$ ./cluster/kubecfg.sh list pods
Name Image(s) Host Labels Status
---------- ---------- ---------- ---------- ----------
jenkins csanchez/jenkins-swarm:1.565.3.3 10.245.2.3/10.245.2.3 name=jenkins Failed
07651754-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.2/10.245.2.2 name=jenkins-slave Running
a22e0d59-4f88-11e4-b01e-0800279696e1 csanchez/jenkins-swarm-slave:1.21 10.245.2.3/10.245.2.3 name=jenkins-slave Failed

清理

kubecfg 还提供了一些命令来停止和删除复制控制器、pod、以及服务等。

要停止复制控制器,设置复制数为 0,所有 Jenkins 从服务的容器都会被终止:

复制代码
$ ./cluster/kubecfg.sh stop jenkins-slave

删除它:

复制代码
$ ./cluster/kubecfg.sh rm jenkins-slave

删除 Jenkins 服务 Pod,Jenkins 主服务的容器会被终止:

复制代码
$ ./cluster/kubecfg.sh delete pods/jenkins

删除服务:

复制代码
$ ./cluster/kubecfg.sh delete services/jenkins
$ ./cluster/kubecfg.sh delete services/jenkins-slave

总结

Kubernetes 还是一个尚处于早期的项目,但是极有希望来管理 Docker 的跨服务器部署以及简化执行长时间运行和分布式的 Docker 容器。通过抽象基础设施概念,定义状态而不是进程,它提供了集群的简单定义,包括脱离管理的自我修复能力。简而言之,Kubernetes 让 Docker 的管理更加的轻松。

关于作者

Carlos Sanchez在自动化、软件开发质量、QA 以及运维等方面有超过 10 年的经验,范围涉及从构建工具、持续集成到部署自动化,DevOps 最佳实践,再到持续交付。他曾经为财富 500 强的公司实施过解决方案,在多家美国的创业公司工作过,最近任职的公司叫做 MaestroDev,这也是他一手创建的公司。Carlos 曾经在世界各地的各种技术会议上作演讲,包括 JavaOne、EclipseCON、ApacheCON、JavaZone、Fosdem 和 PuppetConf。他非常积极的参与开源,是 Apache 软件基金会的成员,同时也是其它一些开源团体的成员,为很多个开源项目做过贡献,比如 Apache Maven、Fog 和 Puppet。

查看英文原文: Scaling Docker with Kubernetes


感谢夏雪对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-10-26 14:3212273
用户头像

发布了 33 篇内容, 共 12.5 次阅读, 收获喜欢 13 次。

关注

评论

发布
暂无评论
发现更多内容

阿里云手机正式公测,定义手机全新接入方式

阿里云弹性计算

阿里云 弹性云手机

Flink 实践教程-进阶(6):CEP 复杂事件处理

腾讯云大数据

流计算 Oceanus

VuePress 博客优化之开启 Gzip 压缩

冴羽

nginx 前端 后端 博客 vuepress

聊聊Netty那些事儿之Reactor在Netty中的实现(创建篇)

bin的技术小屋

网络编程 socket nio netty java 编程

Linux之df命令

入门小站

Linux

腾讯云 AI 视觉产品基于流计算 Oceanus(Flink)的计费数据去重尝试

腾讯云大数据

AI flink window

2021年12月券商App行情刷新及交易体验评测报告

博睿数据

Mycat 作为代理服务端的小知识点

CRMEB

模块9作业

Asha

知识库建设的5个步骤

爱吃小舅的鱼

转换匹配患者记录,看Amazon Lake Formation FindMatches显神通!

亚马逊云科技 (Amazon Web Services)

analytics

失去了SDK,云计算将会怎样?

亚马逊云科技 (Amazon Web Services)

计算

在线常用crontab表达式大全验证解析

入门小站

工具

低代码实现探索(十六)业务勾连复杂验证器

零道云-混合式低代码平台

圆桌对话:云时代下,企业运维面临的挑战与机遇

阿里云弹性计算

运维峰会 圆桌对话

呼叫医生云! Amazon HealthLake 现已正式上线

亚马逊云科技 (Amazon Web Services)

AI ML

专注于最有价值的事情!——亚马逊云科技首席科学家工作心得分享

亚马逊云科技 (Amazon Web Services)

Date

吐槽一下网站

你?

物联网场景中灵活实施对设备的控制管理

亚马逊云科技 (Amazon Web Services)

代码审计思路之PHP代码审计

网络安全学海

网络安全 信息安全 渗透测试 安全漏洞 代码审计

恒源云(GPUSHARE)_语音识别与语义处理领域之低资源机器翻译综述

恒源云

机器翻译 语音识别

透析阿里云视频云「低代码音视频工厂」之能量引擎——vPaaS视频原生应用开发平台

阿里云CloudImagine

云计算 阿里云 音视频 低代买

首届LoongArch生态创新大会成功召开,筑巢引凤共建信息产业命运共同体

OpenAnolis小助手

开源 芯片 白皮书

数云运维总监陈延宗:基于阿里云计算巢,数云CRM一键云上交付

阿里云弹性计算

弹性计算 年度峰会 计算巢

如何使团队的git log更优雅

阿呆

#GitLab

边缘网络 eBPF 超能力:eBPF map 原理与性能解析

火山引擎边缘云

工业生产中的“主动刹车”,是怎么实现的?

脑极体

【网络安全】手把手给大家演练红队渗透项目

H

网络安全 渗透测试·

只需5步!在轻量应用服务器部署Hexo博客

阿里云弹性计算

Hexo 轻量征文 用户投稿

腾讯云原生实时数仓建设实践

腾讯云大数据

flink window 流计算 Oceanus

百度APP浏览内核资源加载优化实践 -- ResourceScheduler 调优机制

百度开发者中心

百度app

使用Kubernetes来管理Docker扩展_DevOps & 平台工程_Carlos Sanchez_InfoQ精选文章