安装

# 先卸载
/usr/local/bin/k3s-uninstall.sh
rm -rf /etc/rancher/k3s
rm -rf /var/lib/rancher/k3s
rm -rf /var/lib/cni/networks/k8s

# x.x.x.x是你的服务器外网IP
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --tls-san x.x.x.x" sh -

准备dns01验证

现在不用https都不好意思出门,这里假设我们的cf的token已经申请,token为cf_token_for_dns01,邮箱为[email protected],需要操作的域名为web.your_doamin.comgrafana.your_domain.com

# 创建token的secret
kubectl create secret generic cloudflare-api-token \
  --namespace kube-system \
  --from-literal=api-token=cf_token_for_dns01

# 创建邮箱的secret
kubectl create secret generic acme-credentials \
  --namespace=kube-system \
  [email protected]
# 编辑文件
# vi /var/lib/rancher/k3s/server/manifests/traefik.yaml
valuesContent: |-
  deployment:
    podAnnotations:
      prometheus.io/port: "8082"
      prometheus.io/scrape: "true"
  providers:
    kubernetesIngress:
      publishedService:
        enabled: true
  priorityClassName: "system-cluster-critical"
  image:
    repository: "rancher/mirrored-library-traefik"
    tag: "3.3.6"
  tolerations:
  - key: "CriticalAddonsOnly"
    operator: "Exists"
  - key: "node-role.kubernetes.io/control-plane"
    operator: "Exists"
    effect: "NoSchedule"
  - key: "node-role.kubernetes.io/master"
    operator: "Exists"
    effect: "NoSchedule"
  service:
    ipFamilyPolicy: "PreferDualStack"
  env:
    - name: CF_DNS_API_TOKEN
      valueFrom:
        secretKeyRef:
          name: cloudflare-api-token
          key: api-token
    - name: ACME_EMAIL
      valueFrom:
        secretKeyRef:
          name: acme-credentials
          key: email
  additionalArguments:
    - "--log.level=DEBUG"
    - "--certificatesresolvers.cloudflare.acme.email=$(ACME_EMAIL)"
    - "--certificatesresolvers.cloudflare.acme.storage=/data/acme.json"
    - "--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare"
    - "--certificatesresolvers.cloudflare.acme.dnschallenge.delaybeforecheck=30"
    - "--certificatesresolvers.cloudflare.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
  persistence:
    enabled: true

如果感觉修改的有问题,可以查看系统里的helmcharts.helm.cattle.io

kubectl get helmcharts.helm.cattle.io -n kube-system traefik -o yaml

修改后k3s会更新traefik,现在系统已经有了自动申请证书的能力!下一步我们部署一个简单nginx,然后为他绑定上域名。

https证书支持

先在web命名空间下创建一个nginx pod

apiVersion: v1
kind: Namespace
metadata:
  name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: web
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

ok,我们现在有了一个nginx的workload,现在我们在当前命名空间声明IngressRoute,准备申请证书

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: redirect-to-https
  namespace: web
spec:
  redirectScheme:
    scheme: https
    permanent: true
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: nginx-http
  namespace: web
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`web.your_doamin.com`)
      kind: Rule
      middlewares:
        - name: redirect-to-https
      services:
        - name: nginx-service
          port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: nginx-https
  namespace: web
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`web.your_doamin.com`)
      kind: Rule
      services:
        - name: nginx-service
          port: 80
  tls:
    certResolver: cloudflare

现在可以使用https://web.your_domain.com访问你的nginx了!

趁热打铁,我们部署一个Prometheus和Grafana,同时支持https证书,首先,我们安装prometheus-stack-grafana

# vi /var/lib/rancher/k3s/server/manifests/prometheus-grafana-stack.yml
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: prometheus
  namespace: kube-system
spec:
  chart: prometheus
  repo: https://prometheus-community.github.io/helm-charts
  createNamespace: true
  targetNamespace: monitoring
  version: 27.16.0
  valuesContent: |-
    alertmanager:
      enabled: true
    server:
      persistentVolume:
        enabled: true
        size: 10Gi
      resources:
        limits:
          cpu: 1
          memory: 2Gi
        requests:
          cpu: 500m
          memory: 1Gi
    kubeStateMetrics:
      enabled: true
    nodeExporter:
      enabled: true
    pushgateway:
      enabled: false
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: grafana
  namespace: kube-system
spec:
  chart: grafana
  repo: https://grafana.github.io/helm-charts
  targetNamespace: monitoring
  createNamespace: true
  version: 9.2.1
  valuesContent: |-
    persistence:
      enabled: true
      size: 5Gi
    resources:
      limits:
        cpu: 500m
        memory: 1Gi
      requests:
        cpu: 200m
        memory: 512Mi
    datasources:
      datasources.yaml:
        apiVersion: 1
        datasources:
        - name: Prometheus
          type: prometheus
          url: http://prometheus-server.monitoring.svc.cluster.local
          access: proxy
          isDefault: true
    adminPassword: admin_pass
    initChownData:
      enabled: false

安装完成后我们在monitoring下创建IngressRoute和Middleware。

---
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: redirect-to-https
  namespace: web
spec:
  redirectScheme:
    scheme: https
    permanent: true
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: grafana-http
  namespace: monitoring
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`grafana.your_domain.com`)
      kind: Rule
      middlewares:
        - name: redirect-to-https
      services:
        - name: prometheus-stack-grafana
          port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: grafana-https
  namespace: monitoring
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`grafana.your_domain.com`)
      kind: Rule
      services:
        - name: prometheus-stack-grafana
          port: 80
  tls:
    certResolver: cloudflare
---

现在可以使用https://grafana.your_domain.com访问你的grafana了!

查询每个用户的实时连接数

要查询每个用户的实时连接数,可以使用以下SQL查询语句:

SELECT
  USER,
  COUNT(*) AS ConnectionCount
FROM
  information_schema.processlist
GROUP BY
  USER
ORDER BY
  ConnectionCount DESC;

这个查询会返回当前数据库中每个用户的连接数。information_schema.processlist 表包含了当前所有活动线程的信息,通过按 USER 分组并计数,可以得到每个用户的连接数。

查询每个IP的实时连接数

要查询每个IP的实时连接数,可以使用以下SQL查询语句:

SELECT
  SUBSTRING_INDEX(HOST, ':', 1) AS ip,
  COUNT(*) AS ConnectionCount
FROM
  information_schema.processlist
GROUP BY
  ip
ORDER BY
  ConnectionCount DESC;

这个查询会返回当前数据库中每个IP的连接数。information_schema.processlist 表包含了当前所有活动线程的信息,通过使用SUBSTRING_INDEX函数截取HOST字段中的IP地址部分,并按IP地址分组计数,可以得到每个IP的连接数。

查询每个IP的实时连接数

要查询每个用户的每个IP的实时连接数,可以使用以下SQL查询语句:

SELECT
  user,
  SUBSTRING_INDEX(HOST, ':', 1) AS IP,
  COUNT(*) AS Total
FROM
  information_schema.processlist
GROUP BY
  user,
  IP
ORDER BY
  Total DESC;

这个查询语句会返回当前数据库中每个用户在每个IP的连接数。通过SUBSTRING_INDEX函数截取HOST字段中的IP地址部分,并按用户和IP地址分组计数,可以得到每个用户的每个IP的连接数。

什么是Kubebuilder

Kubebuilder 是一个基于 CRD(Custom Resource Definitions,自定义资源定义)构建 Kubernetes API 的框架。它允许开发者使用 CRD 来构建 Kubernetes API、Controller 和 Admission Webhook。Kubebuilder 的主要目的是简化 Kubernetes API 和工具的构建过程,减少样板代码的编写,使得开发者可以更专注于业务逻辑的实现。

Kubebuilder 的工作流程大致如下:

创建一个新的工程目录。 创建一个或多个资源 API CRD 并将字段添加到资源中。 在控制器中实现协调循环(reconcile loop),watch 额外的资源。 在集群中运行测试(自动安装 CRD 并自动启动控制器)。 更新引导集成测试测试新字段和业务逻辑。 使用用户提供的 Dockerfile 构建和发布容器。

什么是code-generator

Kubernetes code-generator 是一个代码生成工具集合,它位于 Kubernetes 代码库中的 staging/src/k8s.io/code-generator 包中,这个工具的主要目的是自动化生成与 Kubernetes 相关的客户端库、API 服务器(API server)和其他与 Kubernetes 相关的代码,以提高代码的可维护性和一致性,减少重复代码的开发工作。

code-generator 的主要功能包括:

自动生成客户端库 clientset:通过定义自定义资源的 API 规范,code-generator 可以自动生成用于访问和操作这些自定义资源的客户端库。 自动生成 API 服务器代码:可以根据自定义资源的 API 规范,自动生成与之对应的 API 服务器代码,使得开发者可以快速构建自己的自定义资源的 API 服务器,并将其部署到 Kubernetes 集群中。 自动生成 DeepCopy 方法:对于 Kubernetes 对象,深拷贝是一种常见的操作,用于创建对象的副本。 自动生成其他辅助代码:除了上述功能外,code-generator 还可以生成其他与 Kubernetes 相关的辅助代码,如列表(List)、转换器(Converter)等。 code-generator 包含多个生成工具(gen tools),例如:

deepcopy-gen:为每个类型生成 DeepCopy 方法。 client-gen:生成类型化客户端集合(typed client sets)。 informer-gen:生成基于 Kubernetes API 资源的 Informer。 lister-gen:生成 Kubernetes API 资源的 Lister。 register-gen:自动生成 API 资源类型的注册表代码。 conversion-gen:用于生成 Kubernetes 对象之间的转换器(Converter)。 openapi-gen:用于生成 Kubernetes API 的 OpenAPI 规范。

综上,这两个工具都可以提升我们管理CRD的效率。首先我们使用Kubebuilder生成我们想要的crd对应的type和对应的crd文件。code-generator可以帮助我们生成与api交互需要的资源,比如lister。

接下来老高会讲解如何使用kubebuilder和code-generator构建你的crd套件。

阅读剩余部分

老高最近由于工作变动,需要开展K8S的学习和研究,如何快速搭建一个K8S集群成为了第一个要解决的问题。

刚好老高手头有一台配置还行的服务器,赶紧安装记录一下,省的服务器迁移后数据全丢,然后又要重头来。

阅读剩余部分