Istio 中的授权策略详解

本文节选自 ServiceMesher 社区出品的开源电子书《Istio Handbook——Istio 服务网格进阶实践》,阅读地址:https://www.servicemesher.com/istio-handbook/

授权功能是 Istio 中安全体系的一个重要组成部分,它用来实现访问控制的功能,即判断一个请求是否允许通过,这个请求可以是从外部进入 Istio 内部的请求,也可以是在 Istio 内部从服务 A 到服务 B 的请求。可以把授权功能近似地认为是一种四层到七层的“防火墙”,它会像传统防火墙一样,对数据流进行分析和匹配,然后执行相应的动作。

本节所有概念和操作都基于 Istio 1.6 版本。

授权功能是通过授权策略 (AuthorizationPolicy) 来进行配置和使用的,下面是一个完整的授权策略示例:

                apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-policynamespace: foo
spec:selector:matchLabels:app: httpbinaction: ALLOWrules:- from:- source:principals: ["cluster.local/ns/default/sa/sleep"]to:- operation:methods: ["GET"]paths: ["/info*"]when:- key: request.auth.claims[iss]values: ["https://foo.com"]

这个授权策略的含义是:筛选出 foo 这个 namespace 中含有 app: httpbin label 的 pod,对发送到这些 pod 的请求进行匹配,如果匹配成功,则放行当前请求,匹配规则如下:发起请求的 pod 的 Service Account 需要是 cluster.local/ns/default/sa/sleep ,请求使用 HTTP 协议,请求的具体方法类型是 GET ,请求的 URL 为 /info* ,并且请求中需要包含由 https://foo.com 签发的有效的 JWT Token。

从这个例子中可以看出一个授权策略主要包含以下几个部分:

name:授权策略的名称,仅用于标识授权策略本身,不会影响规则的匹配和执行。•namespace:当前授权策略对象所在的 namespace ,可以使用这个字段配置不同作用范围的授权策略,详见授权策略的作用范围[1]。•selector:使用 label 来选择当前授权策略作用于哪些 pod 上。注意,这里设置的是服务端的 pod ,因为最终这些规则会转换成 Envoy 规则由服务端的 Envoy Proxy 来具体执行。例如有 client 和 server 两个 service ,它们的 pod 对应的 label 分别为 app: client 和 app: server ,为了针对从 client 到 server 的请求进行配置授权策略,这里的 selector 应该设置为 app: server。•action:可以为 ALLOW(默认值)或者 DENY。•rules:匹配规则,如果匹配成功,就会执行对应的 action ,详见授权策略的规则详解[2]

授权策略的作用范围

授权策略可以按照作用域的大小分成三个不同的类型:全局策略、某个 namespace 内的局部策略和具有明确 match label 的授权策略。下面分别进行说明。

全局策略

授权策略位于 istio 的 root namespace 中(例如 istio-system),且匹配所有的 pod。这种规则会作用于整个集群中的所有 pod。

下面的例子中有3个全局策略,第一个是全局 ALLOW ,第二个和第三个是全局 DENY ,后面这两个作用类似,但又有重要的区别,详见授权策略的匹配算法。

                kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: global-allownamespace: istio-system
spec:action: ALLOWrules:- {}
EOFkubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: global-denynamespace: istio-system
spec:action: DENYrules:- {}
EOFkubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: global-denynamespace: istio-system
spec:{}
EOF

某个 namespace 内的局部策略

授权策略位于除了 root namespace 之外的任何一个 namespace 中,且匹配所有的 pod ,这种情况下,这个策略会作用于当前 namespace 中的所有 pod。

下面的例子中是3个 namespace 级别的策略,第一个是 ALLOW ,第二个和第三个是 DENY ,像全局策略一样,后面这两个作用类似,但又有重要的区别,详见授权策略的匹配算法。

                kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: foo-namespace-allownamespace: foo
spec:action: ALLOWrules:- {}
EOFkubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: foo-namespace-denynamespace: foo
spec:action: DENYrules:- {}
EOFkubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: foo-namespace-denynamespace: foo
spec:{}
EOF

具有明确 match label 的授权策略

这种授权策略仅作用于当前 namespace 下使用 selector 字段匹配到的 pod。

                kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-allownamespace: foo
spec:selector:matchLabels:app: httpbinaction: ALLOWrules:- {}
EOF

授权策略的匹配算法

针对某一个请求,会按照一定的匹配算法来执行相应的授权策略:

1.如果有任何一条 DENY 授权策略匹配当前请求,则拒绝当前请求。2.针对当前 pod,如果没有任何 ALLOW 授权策略,则放行当前请求。3.如果有任何一条 ALLOW 授权策略匹配当前请求,则放行当前请求。4.拒绝当前请求。

也就意味着,如果同时有 ALLOW 和 DENY 策略作用于同一个 pod 上,则 DENY 策略会优先执行,其它的 ALLOW 规则就会被忽略。

注意这个顺序非常重要,有时又会比较隐晦,因此在配置比较复杂策略的时候需要多加小心。

在上文授权策略的作用范围中提到授权策略在配置时,有一些细节上的差异,现结合授权策略的匹配算法进行一些分析。

                spec:{}

这是一个 DENY 策略,作用于全局策略或者 namespace 级别(取决于策略所在 namespace 是否为 root namespace)。但是它并没有对当前请求进行匹配,也就意味着按照授权策略的匹配算法在匹配的时候并不会优先匹配到这条规则,因此可以将其作为一个“后备”策略,即全局或者 namespace 级别的一个默认策略。

                spec:action: DENYrules:- {}

这条规则会真正地匹配当前的请求,又由于它是 DENY 规则,按照授权策略的匹配算法,它会首先得到执行,也就意味着如果配置了一条这种全局或者 namespace 级别的规则,那么所有的其它 ALLOW 规则都不会得到执行。因此这条规则在实际中并没有什么价值。

                spec:action: ALLOWrules:- {}

这条规则和上一条规则类似,但是它是 ALLOW 规则,因此按照授权策略的匹配算法,它的优先级会低一些,因此也可以像第一条规则一样作为一个全局或者 namespace 级别的默认策略。

授权策略的规则详解

授权策略中最重要的是其中的 rule 字段,它指定了如何针对当前的请求进行匹配。如果一个授权策略中指定了多条 rule 规则,则它们之间是的关系,即只要其中任意一条规则匹配成功,那么整个授权策略匹配成功,就会执行相应的 action ,下面是概述中提到的一个授权策略的例子:

                apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-policynamespace: foo
spec:selector:matchLabels:app: httpbinaction: ALLOWrules:- from:- source:principals: ["cluster.local/ns/default/sa/sleep"]to:- operation:methods: ["GET"]paths: ["/info*"]when:- key: request.auth.claims[iss]values: ["https://foo.com"]

这里的 rules 是一个 rule 的列表。每一条 rule 规则包括三部分:from 、 to 和 when 。类似于防火墙规则,from 和 to 匹配当前请求从哪里来、到哪里去,when 会增加一些额外的检测,当这些条件都满足时,就会认为当前规则匹配成功。如果其中某一部分未进行配置,则认为其可以匹配成功。

在 rule 中进行配置时,所有的字符串类型都支持类似于通配符的匹配模式,例如 abc* 匹配 "abc" 和 "abcd" 等,*xyz 匹配 "xyz" 和 "axyz" 等,单独的 * 匹配非空的字符串。

下面针对具体的字段详细进行说明。

from。针对请求的发送方进行匹配,主要包括 principals 、 requestPrincipals 、 namespaces 和 ipBlocks 四个部分。•principals。匹配发送方的身份,在 Kubernetes 中可以认为是 pod 的 Service Account。使用这个字段时,首先需要开启 mTLS 功能,关于这部分内容可参见对等认证。例如,当前请求是从 default namespace 中的 pod 中发出,且 pod 使用的 Service Account 名为 sleep,针对这个请求进行匹配,可将 principals 配置为[cluster.local/ns/default/sa/sleep]。•requestPrincipals。匹配请求中的 JWT Token 的 <issuer>/<subject> 字段组合。•namespaces。匹配发送方 pod 所在的 namespace。•ipBlocks。匹配请求的源 IP 地址段。•to。针对请求的接收方进行匹配。除了请求接收方,还会对请求本身进行匹配。包括以下字段:•hosts。目的 host。•ports。目的 port。•methods。是指当前请求执行的 HTTP Method。针对 gRPC 服务,这个字段需要设置为 POST。注意这个字段必须在 HTTP 协议时才进行匹配,如果请求不是 HTTP 协议,则认为匹配失败。•paths。当前请求执行的 HTTP URL Path。针对 gRPC 服务,需要配置为 /package.service/method 格式。•when。这是一个 key/value 格式的 list 。这个字段会针对请求进行一些额外的检测,当这些检测全部匹配时才会认证当前规则匹配成功。例如 key: request.headers[User-Agent] 可以匹配 HTTP Header 中的 User-Agent 字段。所有可配置项可参见 Istio 官网上的 Authorization Policy Conditions[3] 说明。

针对以上字段,还有对应的反向匹配操作,即“取反”匹配,包括 notPrincipals、notNamespaces 等。例如 notNamespaces: ["bar"] 表示当发送请求的 pod 不位于 "bar" 这个 namespace 中的时候匹配成功。

另外,在 rule 中会有非常多针对 JWT Token 进行匹配的字段,关于这部分可以查看 JWT 授权里的详细分析。

下面针对上文列出来的授权策略给出一些实际的例子,一方面可以在实际环境中是如何使用这些策略的,另一方面也可以验证前文所述的各种匹配字段、授权策略的匹配算法和授权策略的作用域。

操作示例

创建应用

首先,创建客户端和服务器端的 service 和对应的 pod,使用的例子位于 istio 源代码的 samples[4] 目录中:

                $ kubectl create ns foo
$ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo

确认 pod 已正常运行:

                $ kubectl get pod -n foo --show-labels
NAME                       READY   STATUS    RESTARTS   AGE   LABELS
httpbin-5d5df46d48-jndgh   2/2     Running   0          57s   app=httpbin,istio.io/rev=,pod-template-hash=5d5df46d48,security.istio.io/tlsMode=isti
o,version=v1
sleep-545684d78b-29x74     2/2     Running   0          56s   app=sleep,istio.io/rev=,pod-template-hash=545684d78b,security.istio.io/tlsMode=istio
$

确认可以正常访问,且启用了 mTLS 功能,关于 mTLS 功能的开启和验证请参见对等认证:

                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 200
$
$ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl http://httpbin.foo:8000/headers -s | grep X-Forwarded-Client-Cert"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=e0f2132eb6ae920cec4b2ea16b9baa33ca388b719a2648636f7a75542852ff0e;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"

全局策略测试

接下来创建一个全局默认的拒绝策略:

                $ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: global-denynamespace: istio-system
spec:{}
EOF

这时再进行验证连通性:

                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 403

服务拒绝,表明全局拒绝策略生效。

接下来创建一个 httpbin pod 的 ALLOW 策略:

                kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-allow-policynamespace: foo
spec:selector:matchLabels:app: httpbinaction: ALLOWrules:- to:- operation:methods: ["GET"]
EOF

按照授权策略的匹配算法,应该可以匹配到第3条规则,因此会执行 ALLOW 动作,运行下面的命令进行验证:

                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 200

测试 Rule 中的字段

下面我们以 Service Account 为例来进行说明。首先来检查 sleep pod 所使用的的 Service Account:

                $ kubectl get pod -l app=sleep -n foo -o jsonpath={.items...serviceAccountName}
sleep

根据 namespace 和 Service Account 构造出 principals 字段,更新授权策略:

                $ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-allow-policynamespace: foo
spec:selector:matchLabels:app: httpbinaction: ALLOWrules:- from:- source:principals: ["cluster.local/ns/foo/sa/sleep"]to:- operation:methods: ["GET"]
EOF

进行验证:

                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 200

访问仍然是放行状态,说明刚才的授权策略是生效的。

将授权策略中的 Service Account 改为一个其它值:

                $ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-allow-policynamespace: foo
spec:selector:matchLabels:app: httpbinaction: ALLOWrules:- from:- source:principals: ["cluster.local/ns/foo/sa/other-sa"]to:- operation:methods: ["GET"]
EOF
                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 403

访问失败,因为授权策略中配置 Service Account 字段与实际的 Service Account 不匹配。

同样地,可以配置 From、To 和 When 中的其它字段进行测试。

授权策略的匹配算法测试

首先,删除之前创建的名为 httpbin-allow-policy 的授权策略,目前系统中仅存在一个全局的默认 DENY 策略。

                kubectl delete authorizationpolicies httpbin-allow-policy -n foo

接下来创建一个匹配 "GET" 方法的 ALLOW 策略,名为 httpbin-allow-get:

                $ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-allow-getnamespace: foo
spec:selector:matchLabels:app: httpbinaction: ALLOWrules:- to:- operation:methods: ["GET"]
EOF

这时使用 "GET /ip" 请求进行测试,由于可以和 httpbin-allow-get 策略匹配,因此按照授权策略的匹配算法,可以匹配到第3条规则,因此可以正常访问:

                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 200

使用 "POST /ip" 请求进行测试,与 httpbin-allow-get 策略不能匹配,因此会执默认的全局 DENY 策略:

                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl -X POST "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 403

再创建一个 "/ip" 的 DENY 策略,名为 httpbin-deny-ip-url:

                $ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-deny-ip-urlnamespace: foo
spec:selector:matchLabels:app: httpbinaction: DENYrules:- to:- operation:paths: ["/ip"]
EOF

这时使用 "GET /ip" 请求进行测试:

                $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"
sleep.foo to httpbin.foo: 403

可以看出执行失败。失败的原因是 "GET /ip" 请求与我们刚才创建的 httpbin-allow-get 和 httpbin-deny-ip-url 两个授权策略都会匹配,但是授权策略的匹配算法执行到第1条规则时,会发现匹配 httpbin-deny-ip-url 授权策略,然后就会直接拒绝当前的请求。另一条授权策略 httpbin-allow-get 便无法得到执行。

清理

执行以下操作来清理我们创建过的各种资源:

                $ kubectl delete authorizationpolicies httpbin-deny-ip-url -n foo
$ kubectl delete authorizationpolicies httpbin-allow-get -n foo
$ kubectl delete authorizationpolicies httpbin-allow-policy -n foo
$ kubectl delete authorizationpolicies global-deny -n istio-system
$ kubectl delete -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
$ kubectl delete -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo
$ kubectl delete ns foo

总结

本节我们详细分析了授权策略的概念和用法,也可以看出利用这些规则可以组合出非常复杂的场景,因此在使用复杂的授权策略时需要非常小心。另外,在授权策略中会涉及到很多针对请求中的 JWT Token 进行匹配的规则,相关的概念和用法会在下一节进行详细阐述。

参考

•Authorization Policy[5]•Authorization Policy Conditions[6]•Authorization[7]

引用链接

[1] 授权策略的作用范围: #授权策略的作用范围
[2] 授权策略的规则详解: #授权策略的规则详解
[3] Authorization Policy Conditions: https://istio.io/latest/docs/reference/config/security/conditions/
[4] samples: https://github.com/istio/istio/tree/master/samples
[5] Authorization Policy: https://istio.io/latest/docs/reference/config/security/authorization-policy/
[6] Authorization Policy Conditions: https://istio.io/latest/docs/reference/config/security/conditions/
[7] Authorization: https://istio.io/latest/docs/tasks/security/authorization/

活动预告

Service Mesh Webinar #2

7 月 22 日(周三)晚 8 点,B 站直播《基于 MOSN 和 Istio Service Mesh 的服务治理实践》,直播间 https://live.bilibili.com/21954520,点击阅读原文查看详细信息。

Go 夜读

Go 夜读第 97 期我们可以从 MOSN 和相关的项目中学习到什么

点击 阅读原文 查看更多

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

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

相关文章

[RabbitMQ]创建Java开发环境_消费者_生产者

我们将用 Java 编写两个程序。发送单个消息的生产者和接收消息并打印出来的消费者。我们将介绍 Java API 中的一些细节。 在下图中&#xff0c;“ P”是我们的生产者&#xff0c;“ C”是我们的消费者。中间的框是一个队列-RabbitMQ 代表使用者保留的消息缓冲区 引入依赖 <…

如何利用Gitlab-CI持续部署到远程机器?

长话短说&#xff0c;今天聊一聊使用Gitlab-CI 自动部署到远程服务器。如果看过《基于docker-compose的Gitlab CI/CD实践&排坑指南》这篇文章的朋友&#xff0c;会注意到我是在 Gitlab-Runner服务器上自动部署的站点&#xff0c;本次我们结合ssh部署到远程机器(将CI服务器和…

[RabbitMQ]工作队列原理_代码实现

Work Queues 工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务&#xff0c;而不得不等待它完成。 相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。当有多个工作线程时&#xff0c;这些工作…

使用ImpromptuInterface反射方便的创建自定义DfaGraphWriter

在本文中&#xff0c;我为创建的自定义的DfaGraphWriter实现奠定了基础。DfaGraphWriter是公开的&#xff0c;因此您可以如上一篇文章《将终结点图添加到你的ASP.NET Core应用程序中》中所示在应用程序中使用它&#xff0c;但它使用的所有类均已标记为internal。这使得创建自己…

[RabbitMQ]消息应答概念_消息手动应答代码

消息应答 概念 消费者完成一个任务可能需要一段时间&#xff0c;如果其中一个消费者处理一个长的任务并仅只完成了部分突然它挂掉了&#xff0c;会发生什么情况。RabbitMQ 一旦向消费者传递了一条消息&#xff0c;便立即将该消 息标记为删除。在这种情况下&#xff0c;突然有…

rust火箭基地主楼开启方法_Rust 为什么能成为 Stack Overflow 最受欢迎的语言?

每年&#xff0c;开发者问答网站 Stack Overflow 都会对程序员社区展开年度调查&#xff0c;包括他们最喜爱的技术到工作偏好的所有内容。 在2017 年和2018 年Stack Overflow 年度开发者调查中&#xff0c;Rust语言已经连续两年成为最受欢迎语言Top 1。2018 年 Stack Overflow …

[RabbitMQ]队列持久化

RabbitMQ持久化 概念 如何保障当 RabbitMQ 服务停掉以后消息生产者发送过来的消息不丢失。默认情况下 RabbitMQ 退出或由于某种原因崩溃时&#xff0c;它忽视队列和消息&#xff0c;除非告知它不要这样做。确保消息不会丢失需要做两件事&#xff1a;我们需要将队列和消息都标…

微服务认证架构如何演进来的?

【答疑解惑】| 作者 / Edison Zhou这是恰童鞋骚年的第267篇原创内容之前有同事问为何要用基于JWT令牌的认证架构&#xff0c;然后近期又有童鞋在后台留言问微服务安全认证架构的实践&#xff0c;因此我决定花两篇推文来解答一下。为了答好这个话题&#xff0c;我们先来看看微服…

maskrcnn还可以加网络吗_绿茶加蜂蜜的功效,绿茶可以加蜂蜜吗?

绿茶是我国的主要茶类之一&#xff0c;是一种天然健康的饮料&#xff0c;蜂蜜也是一种营养丰富的滋补食品&#xff0c;有些人不喜欢绿茶的苦味&#xff0c;想放点蜂蜜中和一下&#xff0c;但是不知道能不能这样做。那么绿茶能不能加蜂蜜呢?蜂蜜的主要成分是葡萄糖、果糖&#…

三分钟Docker-镜像、容器实战篇

本文主要内容&#xff1a;Docker 镜像、容器 常用命令整理使用Docker常见命令&#xff0c;搭建Consul集群通过创建自定义镜像&#xff0c;把.NetCore Api运行在Docker中1.镜像、容器命令镜像序号命令描述1docker image build基于Dockerfile创建镜像2docker image history显示镜…

手机键鼠映射软件_吃鸡,我最专业!---盖世小鸡键鼠吃鸡套装评测

Hello大家好&#xff0c;欢迎浏览这篇评测贴。首先很荣幸能够参与本期的评测&#xff0c;毕竟如此炫酷富有科技感的装备是可遇而不可求的&#xff0c;所以不论是得知入选还是收到快递开箱的时候&#xff0c;心情都是无比激动。话不多说&#xff0c;接下来就让我带你走进这个不一…

[Redis6]Redis启动_前台启动和后台启动

前台启动(不推荐) 前台启动&#xff0c;命令行窗口不能关闭&#xff0c;否则服务器停止 redis-server 关闭redis ctrlC : 关闭 后台启动&#xff08;推荐&#xff09; 备份redis.conf cd redis-6.2.6/cp redis.conf /etc/redis.confcd /etc后台启动设置daemonize no改成y…

深入剖析.NETCORE中CORS(跨站资源共享)

前言由于现代互联网的飞速发展&#xff0c;我们在开发现代 Web 应用程序中&#xff0c;经常需要考虑多种类型的客户端访问服务的情况&#xff1b;而这种情况放在15年前几乎是不可想象的&#xff0c;在那个时代&#xff0c;我们更多的是考虑怎么把网页快速友好的嵌套到服务代码中…

ai进入轮廓模式怎么退出_详解AI中扩展、扩展外观、轮廓化描边、创建轮廓

详解AI中扩展、扩展外观、轮廓化描边、创建轮廓在学习AI软件中&#xff0c;有不少同学分不清扩展、扩展外观、轮廓化描边、创建轮廓这四个概念具体的功能区别&#xff0c;今天我们具体聊一下。先说“扩展”&#xff0c;扩展是把复杂物体拆分成最基本的路径。矢量物体在组合&…

[Redis6]Redis相关知识介绍

Redis介绍相关知识 端口6379 6379 是 "MERZ " 九宫格输入法对应的数字。Alessia Merz 是一位意大利舞女、女演员。 Redis 作者 Antirez 早年看电视节目&#xff0c;觉得 Merz 在节目中的一些话愚蠢可笑&#xff0c;Antirez 喜欢造“梗”用于平时和朋友们交流&#x…

【Power Automate】如何自动生成Word与PDF文件[上]

上半年已经悄悄溜走&#xff0c;因为疫情&#xff0c;大家似乎也很习惯于在家办公。作为业务人员&#xff0c;如何汇报自己的工作&#xff0c;让自己更多地学习和掌握数字化办公技巧至关重要。那么今天我们就来看一下在不使用代码的情况下&#xff0c;如何通过Power Automate自…

easyui datagrid 中怎么选中所有页面的数据_学会这5个Excel中常用技巧,可以准时下班去摆摊了...

Excel是大家常用的办公工具之一&#xff0c;虽说上手简单&#xff0c;但是想要精通还是要下一些功夫的。最近有些小伙伴在留言吐槽说Excel数据处理时很方便&#xff0c;但是操作起来还是挺费时间的&#xff0c;其实工作是离不开技巧的&#xff0c;今天要跟大家分享的5个Excel技…

五年了,别再把务虚会开 “虚” 了

这是头哥侃码的第210篇原创上个月&#xff0c;为了配合公司的半年度战略讨论会&#xff0c;我特意留出一个周六的时间&#xff0c;与几位Leader在公司的会议室里开了一次部门半年度务虚会。让我没想到的是&#xff0c;几位小伙伴在这次讨论过程中都表现得非常亢奋&#xff0c;所…

人工智能正在如何改变传统行业

做了这么多年的技术工作&#xff0c;也正好赶上了这一波的人工智能浪潮&#xff0c;有时候我总是不免在想&#xff0c;人工智能如何真正地融入到我们的日常工作和生活中&#xff0c;实现它应有的价值。大家可能不知道&#xff0c;人工智能其实最早在上个世纪五十年代就提出来了…

[Redis6]key键操作

我们先连接redis cd /usr/local/bin/ redis-cliRedis键(key) keys *查看当前库所有key (匹配&#xff1a;keys *1) exists key判断某个key是否存在 type key 查看你的key是什么类型 del key 删除指定的key数据 unlink key 根据value选择非阻塞删除 仅将keys从keyspace元数据…