0%

简介

服务网格(Service mesh)是服务间通信的基础设施层。它对全局流量和通信进行监控和管理,提供包括可观察性、流量转移(用于灰度发布)、弹性能力(例如断路和重试/超时)等一系列功能,并为服务之间的通信提供双向 TLS 认证能力,让网格能够对请求和响应进行自动加密和解密。
Service Mesh

特点

  • 治理能力独立(Sidecar)
  • 应用程序无感知
  • 服务通信的基础设施层

关注的方面

  • 可观察性
  • 安全性
  • 可运维性
  • 可拓展性

为什么需要?

Service Mesh
Kubernetes 提供平台基础设施层强大的容器编排与调度能力

  • 服务部署与弹性伸缩:Deployment
  • 服务拆分与服务发现:Service

Kubernetes 提供简单的负载均衡

  • 负载均衡:基于IPVSIptables的简单均衡机制

但是Kubernetes在服务治理方面并不完备,缺少了动态路由、熔断、灰度发布等等功能,需要由服务网格互补。

什么时候用Service Mesh?

Service Mesh

随着我们的微服务越来越细分,我们所要管理的服务正在成倍的增长着,Kubernetes 提供了丰富的功能,使得我们可以快速的部署和调度这些服务,同时也提供了我们熟悉的方式来实现那些复杂的功能,但是随着部署的应该越来越多,复杂度越来越高,当临界点到来时,可能就是我们真正要去考虑使用 Service Mesh 的时候了。

Istio问世

Service Mesh
Istio是一个开放服务网格,是Service Mesh标准实现,也是当下最流行的,提供了一种连接,管理和保护微服务的统一方法。它支持管理服务之间的流量,执行访问策略以及汇总遥测数据,所有这些都无需更改微服务代码。

LogQL github

LogQL简介

LogQL: Log Query Language
Loki comes with its very own language for querying logs called LogQL. LogQL can be considered a distributed grep with labels for filtering.

A basic LogQL query consists of two parts: the log stream selector and a filter expression. Due to Loki’s design, all LogQL queries are required to contain a log stream selector.

The log stream selector will reduce the number of log streams to a manageable volume. Depending how many labels you use to filter down the log streams will affect the relative performance of the query’s execution. The filter expression is then used to do a distributed grep over the retrieved log streams.

Loki选择器

对于查询表达式的标签部分,将其包装在花括号中{},然后使用键值对的语法来选择标签,多个标签表达式用逗号分隔,比如:

{app="mysql",name="mysql-backup"}

目前支持以下标签匹配运算符:

  • =等于
  • !=不相等
  • =~正则表达式匹配
  • !~不匹配正则表达式
  • 比如:
{name=~"mysql.+"}
{name!~"mysql.+"}

日志过滤器

编写日志流选择器后,您可以通过编写搜索表达式来进一步过滤结果。搜索表达式可以只是文本或正则表达式。
查询示例:

{job="mysql"} |= "error"
{name="kafka"} |~ "tsdb-ops.*io:2003"
{instance=~"kafka-[23]",name="kafka"} != kafka.server:type=ReplicaManager

过滤器运算符可以被链接,并将顺序过滤表达式-结果日志行将满足每个过滤器。例如:

{job="mysql"} |= "error" != "timeout"

已实现以下过滤器类型:

  • |= 行包含字符串。
  • != 行不包含字符串。
  • |~ 行匹配正则表达式。
  • !~ 行与正则表达式不匹配。
    regex表达式接受RE2语法。默认情况下,匹配项区分大小写,并且可以将regex切换为不区分大小写的前缀(?i)

日志统计

  • rate: calculate the number of entries per second
rate( ( {job="mysql"} |= "error" != "timeout)[10s] ) )
  • count_over_time: counts the entries for each log stream within the given range.
count_over_time({job="mysql"}[5m])

聚合运算

  • sum: Calculate sum over labels
  • min: Select minimum over labels
  • max: Select maximum over labels
  • avg: Calculate the average over labels
  • stddev: Calculate the population standard deviation over labels
  • stdvar: Calculate the population standard variance over labels
  • count: Count number of elements in the vector
  • bottomk: Select smallest k elements by sample value
  • topk: Select largest k elements by sample value

示例:
Get the top 10 applications by the highest log throughput:

topk(10,sum(rate({region="us-east1"}[5m])) by (name))

Get the count of logs during the last five minutes, grouping by level:

sum(count_over_time({job="mysql"}[5m])) by (level)

Get the rate of HTTP GET requests from NGINX logs:

avg(rate(({job="nginx"} |= "GET")[10s])) by (region)

df命令

Linux df命令用于显示目前在Linux系统上的文件系统的磁盘使用情况统计。

df -h
df -h /home
df --total

du命令

Linux du命令用于显示目录或文件的大小。
du会显示指定的目录或文件所占用的磁盘空间。

  • 查看当前目录下文件夹所占磁盘大小
du
  • 查看当前目录下文件夹所占磁盘大小,并格式单位
du -h
  • 查看当前目录下文件夹所占磁盘大小,并显示时间
du --time
  • 查看文件占用空间
du test.log
  • 查看文件占用空间
du test
  • 以M为单位
du -m
  • 以K为单位
du -k
  • 只显示总计,不显示子目录
du -s
  • 设置目录层数
du --max-depth=1

查看tag为none的镜像

docker images -f "dangling=true"

删除tag为none的镜像

docker rmi $(docker images -f "dangling=true" -q)

查看docker占用的磁盘空间

[root@node1 ~]# docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              35                  3                   5.039GB             4.603GB (91%)
Containers          3                   2                   19.69kB             19.5kB (99%)
Local Volumes       28                  0                   3.782MB             3.782MB (100%)
Build Cache         0                   0                   0B                  0B

查找所有无用的volume

docker volume ls -qf dangling=true

删除所有无用的volume

docker volume rm $(docker volume ls -qf dangling=true)

查看所有docker文件夹

find / -name docker

可以使用df或者du命令查看文件夹具体使用情况,参考Linux系统磁盘使用情况相关命令.
如:

du -hs /var/lib/docker/

查找所有未运行的容器

docker ps -a|grep Exited
docker ps -qf status=exited

删除所有未运行的容器

docker rm $(docker ps -a|grep Exited |awk '{print $1}')

prune命令

  • 删除所有无用的容器
docker container prune
  • 删除所有无用的镜像
docker image prune
  • 删除所有无用的volume
docker volume prune
  • 删除所有无用的network
docker network prune
  • 删除docker系统中所有无用的,包括容器、镜像、volume、网络等
docker system prune

注意docker system prunedocker system prune -a两者的区别:


[root@node1 ~]# docker system prune
WARNING! This will remove:

  • all stopped containers
  • all networks not used by at least one container
  • all dangling images
  • all dangling build cache
    Are you sure you want to continue? [y/N]

[root@node1 ~]# docker system prune -a
WARNING! This will remove:

  • all stopped containers
  • all networks not used by at least one container
  • all images without at least one container associated to them
  • all build cache
    Are you sure you want to continue? [y/N]

Cert-manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt, HashiCorp Vault 这些免费证书的签发。在Kubernetes集群中,我们可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。
本文 Cert manager使用版本:v0.12.0
cert-manager
强烈建议参考官方文档:https://cert-manager.io/docs

添加helm源

注意stable/cert-manager已经过时不再维护了,转到jetstack/cert-manager

helm repo add jetstack https://charts.jetstack.io

更新源

helm repo update

创建CRDs

kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml
或
kubectl create -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml

安装

这里设置了两个默认值
–set ingressShim.defaultIssuerName=letsencrypt-prod
–set ingressShim.defaultIssuerKind=ClusterIssuer
–set ingressShim.defaultIssuerGroup=cert-manager.io
用于在后续创建Ingress时,配合annotations
kubernetes.io/tls-acme: “true”
kubernetes.io/ingress.class: “nginx”
实现自动创建证书。

helm install --name cert-manager --namespace cert-manager --version v0.12.0 --set ingressShim.defaultIssuerName=letsencrypt-prod --set ingressShim.defaultIssuerKind=ClusterIssuer --set ingressShim.defaultIssuerGroup=cert-manager.io jetstack/cert-manager

查看安装是否完成

注意事项:下面的pod需要部署在可以访问外网的机器上.

[root@k8s-master cert]# kubectl get pod -n cert-manager
NAME                                      READY   STATUS    RESTARTS   AGE
cert-manager-5cd477f7bb-fxpvf             1/1     Running   0          22m
cert-manager-cainjector-df4dc78cd-l527b   1/1     Running   0          22m
cert-manager-webhook-5f78ff89bc-ggvqt     1/1     Running   0          22m
[root@k8s-master cert]# kubectl get crd | grep cert-manager
certificaterequests.cert-manager.io         2020-01-07T01:38:32Z
certificates.cert-manager.io                2020-01-07T01:38:32Z
challenges.acme.cert-manager.io             2020-01-07T01:38:32Z
clusterissuers.cert-manager.io              2020-01-07T01:38:32Z
issuers.cert-manager.io                     2020-01-07T01:38:32Z
orders.acme.cert-manager.io                 2020-01-07T01:38:32Z

创建默认签发机构

刚刚安装时已经指定了默认签发类型是ClusterIssuer ,签发机构名称是letsencrypt-prod ,但是我们还没有创建,现在需要创建cluster-issuer.yaml

cert-manager 给我们提供了 IssuerClusterIssuer 这两种用于创建签发机构的自定义资源对象,Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书.

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: 1154365135@qq.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:    
    - http01:
        ingress:
          class: nginx

上述配置,更多配置参考ClusterIssuer

  • metadata.name 是我们创建的签发机构的名称,后面我们创建证书的时候会引用它
  • spec.acme.email 是你自己的邮箱,证书快过期的时候会有邮件提醒,不过 cert-manager 会利用 acme 协议自动给我们重新颁发证书来续期
  • spec.acme.server 是 acme 协议的服务端,我们这里用 Let’s Encrypt,这个地址就写死成这样就行
  • spec.acme.privateKeySecretRef 指示此签发机构的私钥将要存储到哪个 Secret 对象中,名称不重要
  • spec.acme.solvers.http01 这里指示签发机构使用 HTTP-01 的方式进行 acme 协议 (还可以用 DNS 方式,acme 协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)
kubectl create -f cluster-issuer.yaml
kubectl get clusterissuer

配置ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app: kubernetes-dashboard
    chart: kubernetes-dashboard-1.10.0
    heritage: Tiller
    release: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  rules:
  - host: k8s.deri.com
    http:
      paths:
      - backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
        path: /
  tls:
  - hosts:
    - k8s.deri.com
    secretName: deri-com-tls-secret-cc

由于添加了annotations kubernetes.io/tls-acme: "true",tls这个secret会自动创建。

创建完成后隔一会儿我们可以看到会多出现一个随机名称的 Ingress 对象cm-acme-http-solver-hl5sx,这个 Ingress 对象就是用来专门验证证书的:

$ kubectl get ingress -n gateway
NAME                        HOSTS                   ADDRESS   PORTS     AGE
cm-acme-http-solver-hl5sx   cs.deri.com             80        37s
kube-ui                     cs.deri.com             80, 443   41s

验证成功后,这个 Ingress 对象会自动删除.

卸载

helm delete --purge cert-manager
kubectl delete -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml

Check

检查服务是否正常

[root@master ~]# kubectl get certificate -n gateway 
NAME              READY   SECRET            AGE
consul-tls-test   True    consul-tls-test   19m
 
[root@master ~]# kubectl get clusterissuer
NAME               READY   AGE
letsencrypt-prod   True    157m
 
[root@master ~]# kubectl get certificate -n gateway 
NAME              READY   SECRET            AGE
consul-tls-test   True    consul-tls-test   19m
 
[root@master ~]# kubectl get Order -n gateway
NAME                                    STATE   AGE
consul-tls-test-3546184973-1845474898   valid   20m
 
[root@master ~]# kubectl get  CertificateRequest -n gateway
NAME                         READY   AGE
consul-tls-test-3546184973   True    27m
 
[root@master ~]# kubectl get secret -ngateway
NAME                      TYPE                                  DATA   AGE
consul-tls-test           kubernetes.io/tls                     3      29m

用到的镜像

quay.io/jetstack/cert-manager-cainjector:v0.12.0
quay.io/jetstack/cert-manager-webhook:v0.12.0
quay.io/jetstack/cert-manager-controller:v0.12.0
#这里由于上面配置solve是acme所以用到这个镜像,如果你配置别的,可能不一致
quay.io/jetstack/cert-manager-acmesolver:v0.12.0

使用国内镜像源。

quay.io

例如下面拉取比较慢

docker pull quay.io/jetstack/cert-manager-cainjector:v0.12.0

可以换成

docker pull quay-mirror.qiniu.com/jetstack/cert-manager-cainjector:v0.12.0

gcr.io

例如下面拉取比较慢

docker pull gcr.io/google_containers/kube-proxy

可以换成阿里云的

docker pull registry.aliyuncs.com/google_containers/kube-proxy

下载完成

可以使用tag命令改回去

docker tag