一文搞懂 K3D

技术

 Hello folks,作为一款由 Google 开发的开源平台,Kubernetes 主要用于自动部署、资源扩展、管理以及编排容器化应用程序。其不仅是

提供了一个简单的系统,用于管理跨多个服务器的容器,同时,具备出色的负载平衡和资源分配能力,以确保每个应用程序能够以最佳性能运行。

 尽管 Kubernetes 是为在云中运行而构建的,然而,在实际的业务场景中,开发人员出于各种原因需要在其本地计算机上部署及运行它。毕竟,在本地运行往往是一种使用容器编排平台的最为简单模式。基于本地开发环境,能够尽可能以减轻与生产环境的差异,并确保应用程序在生产中有效运行。




 但是,在本地设置 Kubernetes 往往需要一个工具来帮助我们在本地计算机上创建环境。

有许多 Kubernetes 开发环境可以帮助开发和测试为 Kubernetes 创建的应用程序,但它们中的每一个都存在一些问题。以笔者的浅薄经验总结:一个良好的开发环境,往往具备以下相关特性:

 1、快速启动




 2、资源轻量级




 3、重启时保持状态




 4、易于重置




 5、支持跨平台




 在本篇文章中,

我们将讨论 K3d 以及它如何让开发人员轻松配置 Kubernetes 开发环境。

 K3d,顾名思义,就其名称本身而言,可以表达为 “K3s-in-docker”,其是 K3s 的一个包装器——在 Docker 中运行它的轻量级 Kubernetes。K3d 能够以快速地创建及操作集群而闻名,得到了众多开发者、组织及相关社区的高度认可,广泛用于本地 Kubernetes 集群规模项目活动开发。




 通过前面的简要解析,我们知道,K3d 是一个旨在轻松在 Docker 中运行 K3s 的实用程序,基于其所提供的一个简单的 CLI 来创建、运行、删除具有 1 到 N 个节点的完全合规的 Kubernetes 集群,是本地容器编排不可或缺的一款平台。那么,K3d 都具备哪些功能呢?

picture.image

 如官网所述,K3s 附带了较多的内置功能和服务,由于 K3s 在容器中运行,其中一些可能只能在 K3d 中以“非正常”方式使用。故此,K3d 囊括了 K3s 所具备的相关功能组件,具体如下所示:

CoreDNS

 关于集群 DNS 服务,K3s 相关资源配置列表信息,如下文件所示:

          
apiVersion: v1
          
kind: ServiceAccount
          
metadata:
          
  name: coredns
          
  namespace: kube-system
          
---
          
apiVersion: rbac.authorization.k8s.io/v1
          
kind: ClusterRole
          
metadata:
          
  labels:
          
    kubernetes.io/bootstrapping: rbac-defaults
          
  name: system:coredns
          
rules:
          
- apiGroups:
          
  - ""
          
  resources:
          
  - endpoints
          
  - services
          
  - pods
          
  - namespaces
          
  verbs:
          
  - list
          
  - watch
          
- apiGroups:
          
  - discovery.k8s.io
          
  resources:
          
  - endpointslices
          
  verbs:
          
  - list
          
  - watch
          
---
          
apiVersion: rbac.authorization.k8s.io/v1
          
kind: ClusterRoleBinding
          
metadata:
          
  annotations:
          
    rbac.authorization.kubernetes.io/autoupdate: "true"
          
  labels:
          
    kubernetes.io/bootstrapping: rbac-defaults
          
  name: system:coredns
          
roleRef:
          
  apiGroup: rbac.authorization.k8s.io
          
  kind: ClusterRole
          
  name: system:coredns
          
subjects:
          
- kind: ServiceAccount
          
  name: coredns
          
  namespace: kube-system
          
---
          
apiVersion: v1
          
kind: ConfigMap
          
metadata:
          
  name: coredns
          
  namespace: kube-system
          
data:
          
  Corefile: |
          
    .:53 {
          
        errors
          
        health
          
        ready
          
        kubernetes %{CLUSTER_DOMAIN}% in-addr.arpa ip6.arpa {
          
          pods insecure
          
          fallthrough in-addr.arpa ip6.arpa
          
        }
          
        hosts /etc/coredns/NodeHosts {
          
          ttl 60
          
          reload 15s
          
          fallthrough
          
        }
          
        prometheus :9153
          
        forward . /etc/resolv.conf
          
        cache 30
          
        loop
          
        reload
          
        loadbalance
          
    }
          
    import /etc/coredns/custom/*.server
          
---
          
apiVersion: apps/v1
          
kind: Deployment
          
metadata:
          
  name: coredns
          
  namespace: kube-system
          
  labels:
          
    k8s-app: kube-dns
          
    kubernetes.io/name: "CoreDNS"
          
spec:
          
  #replicas: 1
          
  strategy:
          
    type: RollingUpdate
          
    rollingUpdate:
          
      maxUnavailable: 1
          
  selector:
          
    matchLabels:
          
      k8s-app: kube-dns
          
  template:
          
    metadata:
          
      labels:
          
        k8s-app: kube-dns
          
    spec:
          
      priorityClassName: "system-cluster-critical"
          
      serviceAccountName: coredns
          
      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"
          
      nodeSelector:
          
        beta.kubernetes.io/os: linux
          
      topologySpreadConstraints:
          
        - maxSkew: 1
          
          topologyKey: kubernetes.io/hostname
          
          whenUnsatisfiable: DoNotSchedule
          
          labelSelector:
          
            matchLabels:
          
              k8s-app: kube-dns
          
      containers:
          
      - name: coredns
          
        image: %{SYSTEM_DEFAULT_REGISTRY}%rancher/mirrored-coredns-coredns:1.8.6
          
        imagePullPolicy: IfNotPresent
          
        resources:
          
          limits:
          
            memory: 170Mi
          
          requests:
          
            cpu: 100m
          
            memory: 70Mi
          
        args: [ "-conf", "/etc/coredns/Corefile" ]
          
        volumeMounts:
          
        - name: config-volume
          
          mountPath: /etc/coredns
          
          readOnly: true
          
        - name: custom-config-volume
          
          mountPath: /etc/coredns/custom
          
          readOnly: true
          
        ports:
          
        - containerPort: 53
          
          name: dns
          
          protocol: UDP
          
        - containerPort: 53
          
          name: dns-tcp
          
          protocol: TCP
          
        - containerPort: 9153
          
          name: metrics
          
          protocol: TCP
          
        securityContext:
          
          allowPrivilegeEscalation: false
          
          capabilities:
          
            add:
          
            - NET_BIND_SERVICE
          
            drop:
          
            - all
          
          readOnlyRootFilesystem: true
          
        livenessProbe:
          
          httpGet:
          
            path: /health
          
            port: 8080
          
            scheme: HTTP
          
          initialDelaySeconds: 60
          
          periodSeconds: 10
          
          timeoutSeconds: 1
          
          successThreshold: 1
          
          failureThreshold: 3
          
        readinessProbe:
          
          httpGet:
          
            path: /ready
          
            port: 8181
          
            scheme: HTTP
          
          initialDelaySeconds: 0
          
          periodSeconds: 2
          
          timeoutSeconds: 1
          
          successThreshold: 1
          
          failureThreshold: 3
          
      dnsPolicy: Default
          
      volumes:
          
        - name: config-volume
          
          configMap:
          
            name: coredns
          
            items:
          
            - key: Corefile
          
              path: Corefile
          
            - key: NodeHosts
          
              path: NodeHosts
          
        - name: custom-config-volume
          
          configMap:
          
            name: coredns-custom
          
            optional: true
          
---
          
apiVersion: v1
          
kind: Service
          
metadata:
          
  name: kube-dns
          
  namespace: kube-system
          
  annotations:
          
    prometheus.io/port: "9153"
          
    prometheus.io/scrape: "true"
          
  labels:
          
    k8s-app: kube-dns
          
    kubernetes.io/cluster-service: "true"
          
    kubernetes.io/name: "CoreDNS"
          
spec:
          
  selector:
          
    k8s-app: kube-dns
          
  clusterIP: %{CLUSTER_DNS}%
          
  ports:
          
  - name: dns
          
    port: 53
          
    protocol: UDP
          
  - name: dns-tcp
          
    port: 53
          
    protocol: TCP
          
  - name: metrics
          
    port: 9153
          
    protocol: TCP
      
 备注:所涉及的模板变量(如 %{CLUSTER\_DOMAIN}%),在将文件写入文件系统之前将被 K3s 替换。对于 K3d 而言,CoreDNS 工作方式与在其他集群中的工作方式基本上是相同的。不过需要注意的是, Corefile 中配置的 /etc/resolv.conf 不能正常工作,因为 K3s 节点容器中的 /etc/resolv.conf 文件与本地机器上的不同。







 从 K3d v5.x 开始,K3d 将条目注入到 NodeHosts 以使集群中的 Pod 能够解析同一 Docker 中其他容器的名称网络(集群网络)和一个名为 host.k3d.internal 的特殊条目,它解析为网络网关的 IP(可用于例如使用本地解析器解析 DNS 查询)。

Local-Path-Provisione

 基于 Kubernetes 动态配置持久本地存储,K3s 相关资源配置列表信息,如下文件所示:

          
apiVersion: v1
          
kind: ServiceAccount
          
metadata:
          
  name: local-path-provisioner-service-account
          
  namespace: kube-system
          
---
          
apiVersion: rbac.authorization.k8s.io/v1
          
kind: ClusterRole
          
metadata:
          
  name: local-path-provisioner-role
          
rules:
          
- apiGroups: [""]
          
  resources: ["nodes", "persistentvolumeclaims", "configmaps"]
          
  verbs: ["get", "list", "watch"]
          
- apiGroups: [""]
          
  resources: ["endpoints", "persistentvolumes", "pods"]
          
  verbs: ["*"]
          
- apiGroups: [""]
          
  resources: ["events"]
          
  verbs: ["create", "patch"]
          
- apiGroups: ["storage.k8s.io"]
          
  resources: ["storageclasses"]
          
  verbs: ["get", "list", "watch"]
          
---
          
apiVersion: rbac.authorization.k8s.io/v1
          
kind: ClusterRoleBinding
          
metadata:
          
  name: local-path-provisioner-bind
          
roleRef:
          
  apiGroup: rbac.authorization.k8s.io
          
  kind: ClusterRole
          
  name: local-path-provisioner-role
          
subjects:
          
- kind: ServiceAccount
          
  name: local-path-provisioner-service-account
          
  namespace: kube-system
          
---
          
apiVersion: apps/v1
          
kind: Deployment
          
metadata:
          
  name: local-path-provisioner
          
  namespace: kube-system
          
spec:
          
  replicas: 1
          
  selector:
          
    matchLabels:
          
      app: local-path-provisioner
          
  template:
          
    metadata:
          
      labels:
          
        app: local-path-provisioner
          
    spec:
          
      priorityClassName: "system-node-critical"
          
      serviceAccountName: local-path-provisioner-service-account
          
      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"
          
      containers:
          
      - name: local-path-provisioner
          
        image: %{SYSTEM_DEFAULT_REGISTRY}%rancher/local-path-provisioner:v0.0.21
          
        imagePullPolicy: IfNotPresent
          
        command:
          
        - local-path-provisioner
          
        - start
          
        - --config
          
        - /etc/config/config.json
          
        volumeMounts:
          
        - name: config-volume
          
          mountPath: /etc/config/
          
        env:
          
        - name: POD_NAMESPACE
          
          valueFrom:
          
            fieldRef:
          
              fieldPath: metadata.namespace
          
      volumes:
          
        - name: config-volume
          
          configMap:
          
            name: local-path-config
          
---
          
apiVersion: storage.k8s.io/v1
          
kind: StorageClass
          
metadata:
          
  name: local-path
          
  annotations:
          
    storageclass.kubernetes.io/is-default-class: "true"
          
provisioner: rancher.io/local-path
          
volumeBindingMode: WaitForFirstConsumer
          
reclaimPolicy: Delete
          
---
          
kind: ConfigMap
          
apiVersion: v1
          
metadata:
          
  name: local-path-config
          
  namespace: kube-system
          
data:
          
  config.json: |-
          
    {
          
      "nodePathMap":[
          
      {
          
        "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
          
        "paths":["%{DEFAULT_LOCAL_STORAGE_PATH}%"]
          
      }
          
      ]
          
    }
          
  setup: |-
          
    #!/bin/sh
          
    while getopts "m:s:p:" opt
          
    do
          
        case $opt in
          
            p)
          
            absolutePath=$OPTARG
          
            ;;
          
            s)
          
            sizeInBytes=$OPTARG
          
            ;;
          
            m)
          
            volMode=$OPTARG
          
            ;;
          
        esac
          
    done
          
    mkdir -m 0777 -p ${absolutePath}
          
    chmod 701 ${absolutePath}/..
          
  teardown: |-
          
    #!/bin/sh
          
    while getopts "m:s:p:" opt
          
    do
          
        case $opt in
          
            p)
          
            absolutePath=$OPTARG
          
            ;;
          
            s)
          
            sizeInBytes=$OPTARG
          
            ;;
          
            m)
          
            volMode=$OPTARG
          
            ;;
          
        esac
          
    done
          
    rm -rf ${absolutePath}
          
  helperPod.yaml: |-
          
    apiVersion: v1
          
    kind: Pod
          
    metadata:
          
      name: helper-pod
          
    spec:
          
      containers:
          
      - name: helper-pod
          
        image: %{SYSTEM_DEFAULT_REGISTRY}%rancher/mirrored-library-busybox:1.34.1
      
 在 K3d 中,Local-Path-Provisioner 使用的是位于容器的文件系统中的本地路径(默认为 /var/lib/rancher/k3s/storage),这意味着默认情况下它不会映射到某个地方,例如,在我们的用户主目录中供使用。 






 在实际的业务场景中,我们可能需要将一些本地目录映射到该路径以轻松使用此路径中的文件,此时,可借助以下命令行参数:






 --volume $HOME/some/directory:/var/lib/rancher/k3s/storage@all 添加到我们的 K3d 集群以进行相关操作命令的创建。

Traefik

 在 K3

s 中,Kubernetes Ingress Controller 即入口控制器默认使用的是 Traefik 接入层代理,其版本为 1.x。K3d 在容器中运行 K3s,因此我们需要在主机上暴露 Http/Https 端口才能轻松访问集群中的 Ingress 资源。其相关资源配置列表信息,如下文件所示:


          
---
          
apiVersion: helm.cattle.io/v1
          
kind: HelmChart
          
metadata:
          
  name: traefik-crd
          
  namespace: kube-system
          
spec:
          
  chart: https://%{KUBERNETES_API}%/static/charts/traefik-crd-10.14.100.tgz
          
---
          
apiVersion: helm.cattle.io/v1
          
kind: HelmChart
          
metadata:
          
  name: traefik
          
  namespace: kube-system
          
spec:
          
  chart: https://%{KUBERNETES_API}%/static/charts/traefik-10.14.100.tgz
          
  set:
          
    global.systemDefaultRegistry: "%{SYSTEM_DEFAULT_REGISTRY_RAW}%"
          
  valuesContent: |-
          
    rbac:
          
      enabled: true
          
    ports:
          
      websecure:
          
        tls:
          
          enabled: true
          
    podAnnotations:
          
      prometheus.io/port: "8082"
          
      prometheus.io/scrape: "true"
          
    providers:
          
      kubernetesIngress:
          
        publishedService:
          
          enabled: true
          
    priorityClassName: "system-cluster-critical"
          
    image:
          
      name: "rancher/mirrored-library-traefik"
          
      tag: "2.6.1"
          
    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"
      
 通常而言,目前支持以下 2 种模式,具体:




 1、入口




此模式为默认推荐的方式。我们通过某种方式创建集群,使内部端口 80(Traefik 入口控制器监听)暴露在主机系统上。




 2、节点端口 基于集群节点进行特定端口映射。

Servicelb

 基于 K3d 中的 Servicelb,

klipper-lb 创建新的 Pod,将来自 hostPorts 的流量代理到以下类型的服务端口: LoadBalancer。 在这种情况下,hostPort 是 K3s 容器中的端口,而不是我们的本地主机,因此需要在创建集群时通过 --port 标志添加端口映射。

 除了上述功能外,K3d 也具备其他高级特性,诸如使用 Calico 网络策略替代早期的 Flannel、运行 CUDA 工作负载等等。





 备注:

如果想在 K3s 容器上运行 CUDA 工作负载,我们则需要自定义容器。 CUDA 工作负载需要 NVIDIA Container Runtime,因此需要将 containerd 配置为使用此运行时。 K3s 容器本身也需要与此运行时一起运行。 如果 使用的是 Docker,则可以安装 NVIDIA Container Toolkit。

 接下来,我们了解一下 K3d 的安装部署以及所映射的相关网络模型。为了尽可能地融入社区,K3d 使用 “Server” 和 “Agent” 两个词来设计 “Master” 和 “Worker” 节点。通常,基于 K3d 所构建的本地 Kubernetes 集群环境,主要涉及以下:





 1、所创建的每个集群现在将生成至少 2 个容器:1 个负载均衡器和 1 个“服务器”节点。






 负载均衡器将成为 Kubernetes API 的接入点,因此即使对于多服务器集群,我们也只需要公开一个 Api 端口,然后负载均衡器将负责将我们的请求代理到正确的服务器节点。(当然,若不使用此项,可以使用 --no-lb 标志进行禁用)






 2

采用“名词动词”句法。 这一重大更改使得添加新名词(即 K3d 托管对象)变得更加容易,并且与许多其他云原生 CLI(例如 Gcloud、AWScli、AZURE cli、...)类似,并且还提供了更清晰的 CLI 层次结构。

 3、当一个新的服务器节点被添加至集群时,支持多服务器集群(dqlite)和热重载配置。




 4、独立的集群处理节点。




 5、基本的插件支持系统及丰富的命令行操作。




 现在创建一个带有1个Loadbalancer 和1节点(具有服务器和代理的角色)的简单群集,名称为“Devops Cluster”,具体命令行操作如下所示:

          
[leonli@192 ~] % k3d version
          
k3d version v5.3.0
          
k3s version v1.22.6-k3s1 (default)
          
[leonli@192 ~] % docker version
          
Client:
          
 Cloud integration: v1.0.22
          
 Version:           20.10.12
          
 API version:       1.41
          
 Go version:        go1.16.12
          
 Git commit:        e91ed57
          
 Built:             Mon Dec 13 11:46:56 2021
          
 OS/Arch:           darwin/arm64
          
 Context:           default
          
 Experimental:      true
          

          
Server: Docker Desktop 4.5.0 (74594)
          
 Engine:
          
  Version:          20.10.12
          
  API version:      1.41 (minimum version 1.12)
          
  Go version:       go1.16.12
          
  Git commit:       459d0df
          
  Built:            Mon Dec 13 11:43:07 2021
          
  OS/Arch:          linux/arm64
          
  Experimental:     false
          
 containerd:
          
  Version:          1.4.12
          
  GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
          
 runc:
          
  Version:          1.0.2
          
  GitCommit:        v1.0.2-0-g52b36a2
          
 docker-init:
          
  Version:          0.19.0
          
  GitCommit:        de40ad0
      

          
[leonli@192 ~] % k3d cluster create devops-cluster --port 8080:80@loadbalancer --port 8443:443@loadbalancer --api-port 6443 --servers 1 --agents 1
          
INFO[0000] portmapping '8080:80' targets the loadbalancer: defaulting to [servers:*:proxy agents:*:proxy] 
          
INFO[0000] portmapping '8443:443' targets the loadbalancer: defaulting to [servers:*:proxy agents:*:proxy] 
          
INFO[0000] Prep: Network                                
          
INFO[0000] Created network 'k3d-devops-cluster'         
          
INFO[0000] Created image volume k3d-devops-cluster-images 
          
INFO[0000] Starting new tools node...                   
          
INFO[0004] Pulling image 'docker.io/rancher/k3d-tools:5.3.0' 
          
INFO[0006] Creating node 'k3d-devops-cluster-server-0'  
          
INFO[0010] Pulling image 'docker.io/rancher/k3s:v1.22.6-k3s1' 
          
INFO[0010] Starting Node 'k3d-devops-cluster-tools'     
          
INFO[0018] Creating node 'k3d-devops-cluster-agent-0'   
          
INFO[0018] Creating LoadBalancer 'k3d-devops-cluster-serverlb' 
          
INFO[0023] Pulling image 'docker.io/rancher/k3d-proxy:5.3.0' 
          
INFO[0033] Using the k3d-tools node to gather environment information 
          
INFO[0034] Starting cluster 'devops-cluster'            
          
INFO[0034] Starting servers...                          
          
INFO[0034] Starting Node 'k3d-devops-cluster-server-0'  
          
INFO[0038] Starting agents...                           
          
INFO[0038] Starting Node 'k3d-devops-cluster-agent-0'   
          
INFO[0045] Starting helpers...                          
          
INFO[0045] Starting Node 'k3d-devops-cluster-serverlb'  
          
INFO[0052] Injecting records for hostAliases (incl. host.k3d.internal) and for 3 network members into CoreDNS configmap... 
          
INFO[0054] Cluster 'devops-cluster' created successfully! 
          
INFO[0054] You can now use it like this:                
          
kubectl cluster-info
      
 此时,依据日志输出提示,运行 kubectl cluster-info 查看下当前集群的信息,如下所示:

          
[leonli@192 ~] % kubectl cluster-info
          
Kubernetes control plane is running at https://0.0.0.0:6443
          
CoreDNS is running at https://0.0.0.0:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
          
Metrics-server is running at https://0.0.0.0:6443/api/v1/namespaces/kube-system/services/https:metrics-server:https/proxy
      
 然后,我们借助 docker ps 命令来看一下创建的容器底层相关信息,具体如下所示:

          
[leonli@192 ~] % docker ps
          
CONTAINER ID   IMAGE                      COMMAND                  CREATED         STATUS         PORTS                                                                 NAMES
          
52ae7eedb2f6   rancher/k3d-proxy:5.3.0    "/bin/sh -c nginx-pr…"   6 minutes ago   Up 6 minutes   0.0.0.0:6443->6443/tcp, 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp   k3d-devops-cluster-serverlb
          
c147f033af88   rancher/k3s:v1.22.6-k3s1   "/bin/k3d-entrypoint…"   7 minutes ago   Up 6 minutes                                                                         k3d-devops-cluster-agent-0
          
3e1e97081296   rancher/k3s:v1.22.6-k3s1   "/bin/k3d-entrypoint…"   7 minutes ago   Up 6 minutes                                                                         k3d-devops-cluster-server-0
      
 接下来,我们基于所创建的集群信息,来梳理一下所配置的端口映射逻辑关系:




 --port 8080:80@loadbalancer 会将本地的 8080 端口映射到 Loadbalancer  80 端口,然后 Loadbalancer 接收到 80 端口的请求后,会代理到所有的 K8s 节点。




 --api-port 6443 默认提供的端口号,K3s  Api-Server 会监听 6443 端口,主要是用来操作 Kubernetes API 的,即使创建多个 Master 节点,也只需要暴露一个 6443 端口,Loadbalancer 会将请求代理分发给多个 Master 节点。




 如果我们期望通过 NodePort 的形式暴露服务,也可以基于实际的业务场景来自定义一些端口号映射到 Loadbalancer 来暴露 K8s 的服务,当然,前提是如果不想使用 Ingress Controller 的话。相关命令行可参考如下命令行:

        
            

          -p 20080-30080:20080-30080@loadbalancer
        
      
 此时,基于 K3d 所创建的名称为 Devops Cluster 的本地集群网络拓扑如下所示:  

picture.image

 现在,一个完整的本地 K8s 集群已部署 Ok,接下来,我们通过创建一个简单的 Nginx 实例进行验证,具体如下所示:

          
[leonli@192 ~] % kubectl create deployment nginx --image=nginx
          
deployment.apps/nginx created
          
[leonli@192 ~] % kubectl create service clusterip nginx --tcp=80:80
          
service/nginx created
          
[leonli@192 ~] % cat <<EOF | kubectl apply -f -
          
apiVersion: networking.k8s.io/v1beta1
          
kind: Ingress
          
metadata:
          
  name: nginx
          
  annotations:
          
    ingress.kubernetes.io/ssl-redirect: "false"
          
spec:
          
  rules:
          
  - http:
          
      paths:
          
      - path: /
          
        backend:
          
          serviceName: nginx
          
          servicePort: 80
          
EOF
      
 创建一个默认由 Traefik 1.x 作为 Ingress Controller 的 Ingress,我们可以直接访

http://localhost:8080/,即可看到 Nginx 相关信息。

 其实,从本质而言,K3d 是一款出色的工具,其不仅结合了简单、极轻、模块化和功能,同时也解决了更为复杂的需求。除此之外,Rancher 团队再次出色地重写了 K3d,使得在一台机器上运行具有不同拓扑的 K3s Kubernetes 集群的多个实例变得非常容易、模块化、简单和高效。
参考资料

picture.image

  • EOF -


● ●

如果您喜欢本文,欢迎 点赞 、 在看 、 留言 ,或者点击 右上角 ,把文章分享到朋友圈~~~

picture.image

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
DevOps 在字节移动研发中的探索和实践
在日益复杂的APP工程架构下,如何保证APP能高效开发,保障团队效能和工程质量?本次将结合字节内部应用的事件案例,介绍DevOps团队对移动研发效能建设的探索和思考。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论