标签 k8s 下的文章

在这篇文章中,我们将向你展示如何在 Kubernetes(k8s)集群中设置动态 NFS 配置。

Kubernetes 中的动态 NFS 存储配置允许你按需自动为 Kubernetes 应用配置和管理 NFS(网络文件系统)卷。它允许创建持久卷(PV)和持久卷声明(PVC),而无需手动干预或预配置存储。

NFS 配置程序负责动态创建 PV 并将其绑定到 PVC。它与 NFS 服务器交互,为每个 PVC 创建目录或卷。

先决条件

  • 预装 Kubernetes 集群
  • 具有 Kubernetes 集群管理员权限的普通用户
  • 互联网连接

事不宜迟,让我们深入探讨步骤:

步骤 1、准备 NFS 服务器

就我而言,我将在 Kubernetes 主节点(Ubuntu 22.04)上安装 NFS 服务器。登录主节点并运行以下命令:

$ sudo apt update
$ sudo apt install nfs-kernel-server -y

创建以下文件夹并使用 NFS 共享它:

$ sudo mkdir /opt/dynamic-storage
$ sudo chown -R nobody:nogroup /opt/dynamic-storage
$ sudo chmod 777 /opt/dynamic-storage

/etc/exports 文件中添加以下条目:

$ sudo vi /etc/exports
/opt/dynamic-storage 192.168.1.0/24(rw,sync,no_subtree_check)

保存并关闭文件。

注意:不要忘记更改导出文件中适合你的部署的网络。

要使上述更改生效,请运行:

$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server
$ sudo systemctl status nfs-kernel-server

NFS-Service-Status-Kubernetes-Master-Ubuntu

在工作节点上,使用以下 apt 命令安装 nfs-common 包。

$ sudo apt install nfs-common -y

步骤 2、安装和配置 NFS 客户端配置程序

NFS 子目录外部配置程序在 Kubernetes 集群中部署 NFS 客户端配置程序。配置程序负责动态创建和管理由 NFS 存储支持的持久卷(PV)和持久卷声明(PVC)。

因此,要安装 NFS 子目录外部配置程序,首先使用以下命令集安装 helm

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh

运行以下命令来启用 helm 仓库:

$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner

使用以下 helm 命令部署配置程序:

$ helm install -n nfs-provisioning --create-namespace nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --set nfs.server=192.168.1.139 --set nfs.path=/opt/dynamic-storage

helm-install-nfs-provisioning-kubernetes-cluster

上面的 helm 命令将自动创建 nfs-provisioning 命名空间,并安装 NFS 配置程序的容器荚/部署、名称为 nfs-client 的存储类,并将创建所需的 rbac。

$ kubectl get all -n nfs-provisioning
$ kubectl get sc -n nfs-provisioning

kubectl-get-all-nfs-provisioning-kubernetes-cluster

完美,上面的输出确认了配置程序容器荚和存储类已成功创建。

步骤 3、创建持久卷声明(PVC)

让我们创建 PVC 来为你的容器荚或部署请求存储。PVC 将从存储类 nfs-client 请求特定数量的存储:

$ vi demo-pvc.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: demo-claim
  namespace: nfs-provisioning
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Mi

保存并关闭文件。

PVC-Yaml-Dynamic-NFS-Kubernetes

运行以下 kubectl 命令以使用上面创建的 YML 文件创建 PVC:

$ kubectl create -f demo-pvc.yml

验证 PVC 和 PV 是否创建:

$ kubectl get pv,pvc -n nfs-provisioning

Verify-pv-pvc-dynamic-nfs-kubernetes-cluster

太好了,上面的输出表明 PV 和 PVC 创建成功。

步骤 4、测试并验证动态 NFS 配置

为了测试和验证动态 NFS 配置,请使用以下 YML 文件启动测试容器荚:

$ vi test-pod.yml
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
  namespace: nfs-provisioning
spec:
  containers:
  - name: test-pod
    image: busybox:latest
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS && sleep 600"
    volumeMounts:
      - name: nfs-pvc
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: demo-claim

Pod-Yml-Dynamic-NFS-kubernetes

使用以下 kubectl 命令部署容器荚:

$ kubectl create -f test-pod.yml

验证 test-pod 的状态:

$ kubectl get pods -n nfs-provisioning

Verify-Test-Pod-Using-NFS-Volume-Kubernetes

登录到容器荚并验证 NFS 卷是否已安装。

$ kubectl exec -it test-pod -n nfs-provisioning /bin/sh

Access-Dynamic-NFS-Inside-Pod-Kubernetes

太棒了,上面容器荚的输出确认了动态 NFS 卷已安装且可访问。

最后删除容器荚和 PVC,查看 PV 是否自动删除。

$ kubectl delete -f test-pod.yml
$ kubectl delete -f demo-pvc.yml
$ kubectl get pv,pvc -n  nfs-provisioning

Delete-Pod-PVC-Dynamic-NFS

这就是这篇文章的全部内容,希望对你有所帮助。请随时在下面的评论部分发表你的疑问和反馈。

(题图:MJ/75dae36f-ff68-4c63-81e8-281e2c239356)


via: https://www.linuxtechi.com/dynamic-nfs-provisioning-kubernetes/

作者:Pradeep Kumar 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

你是否在寻找一份在 Debian 11(Bullseye)上安装 Kubernetes 集群的简易指南?

这份分步指南将向你展示如何使用 Kubeadm 工具在 Debian 11 上安装 Kubernetes 集群。

Kubernetes(k8s)集群包含主控节点和工作节点,用于运行容器化的应用程序。主控节点作为控制平面,工作节点为实际工作负载提供环境。

前置条件:

  • 已安装 Debian 11
  • 2 CPU / vCPU
  • 2 GB RAM
  • 20 GB 空闲硬盘空间
  • 有管理员权限的 sudo 用户
  • 稳定的网络连接

实验环境配置:

在本文中,我使用了 3 个 Debian 11 系统的节点,配置如下

  • 主控节点(k8s-master) – 192.168.1.236
  • 工作节点 1(k8s-worker1) – 192.168.1.237
  • 工作节点 2(k8s-worker2) – 192.168.1.238

事不宜迟,我们直接进入安装步骤。

1、设置主机名和更新 /etc/hosts 文件

在主控节点和工作节点上使用 hostnamectl 命令来设置主机名:

$ sudo hostnamectl set-hostname "k8s-master"       // 在主控节点运行
$ sudo hostnamectl set-hostname "k8s-worker1"      // 在工作节点 1 运行
$ sudo hostnamectl set-hostname "k8s-worker2"      // 在工作节点 2 运行

在所有节点的 /etc/hosts 文件末尾添加下面几行内容:

192.168.1.236       k8s-master
192.168.1.237       k8s-worker1
192.168.1.238       k8s-worker2

2、在所有节点上关闭交换分区

我推荐关闭交换分区,以便更丝滑地使用 kubelet。在所有节点上执行以下命令来关闭交换分区:

$ sudo swapoff -a
$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

3、配置 Kubernetes 集群相关的防火墙规则

如果你的操作系统防火墙是打开的,请分别在主控节点和工作节点允许以下的端口。

在主控节点,执行:

$ sudo ufw allow 6443/tcp
$ sudo ufw allow 2379/tcp
$ sudo ufw allow 2380/tcp
$ sudo ufw allow 10250/tcp
$ sudo ufw allow 10251/tcp
$ sudo ufw allow 10252/tcp
$ sudo ufw allow 10255/tcp
$ sudo ufw reload

在工作节点,执行:

$ sudo ufw allow 10250/tcp
$ sudo ufw allow 30000:32767/tcp
$ sudo ufw reload

注意:如果你的 Debian 11 系统防火墙是关闭的,可以跳过此步骤。

4、在所有节点安装 Containerd 运行时

Containerd 是容器运行时的行业标准,所有节点必须安装 Containerd。

先在所有节点上配置如下的核心参数,再安装 Containerd。

$ cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

$ sudo modprobe overlay
$ sudo modprobe br_netfilter

$ cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

运行如下命令,以使上面的更改生效:

$ sudo sysctl --system

现在,在所有节点上运行如下 apt 命令来安装 Conatinerd。

$ sudo apt  update
$ sudo apt -y install containerd

在所有节点上运行如下命令来配置 Containerd:

$ containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1

在所有节点上设置 cgroupdriversystemd,编辑 /etc/containerd/config.toml 文件,找到 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] 部分,添加一行内容:SystemdCgroup = true

$ sudo vi /etc/containerd/config.toml

systemdCgroup-true-containerd-config-toml

保存并退出文件。

在所有节点上重启并启用 containerd 服务:

$ sudo systemctl restart containerd
$ sudo systemctl enable containerd

5、添加 Kubernetes Apt 库

执行以下命令,添加 Kubernetes Apt 库:

$ sudo apt install gnupg gnupg2 curl software-properties-common -y
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/cgoogle.gpg
$ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"

6、在所有节点上安装 kubelet、kubectl 和 kubeadm

在所有节点上执行以下 apt 命令,安装 Kubernetes 集群组件,如 kubeletkubectl 以及 kubeadm

$ sudo apt update
$ sudo apt install kubelet kubeadm kubectl -y
$ sudo apt-mark hold kubelet kubeadm kubectl

7、使用 Kubeadm 创建 Kubernetes 集群

现在我们可以创建 Kubernetes 集群了,在主控节点上执行以下命令:

$ sudo kubeadm init --control-plane-endpoint=k8s-master

命令输出:

Kubernetes-Control-Plane-Initialization-Debian11

出现以上内容,说明控制平面初始化成功。在输出中,有普通用户与集群交互的命令,也有把任何工作节点加入到集群的命令。

要开始与集群进行交互,请在主控节点上运行以下命令:

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

执行以下 kubectl 命令来获取节点和集群的信息:

$ kubectl get nodes
$ kubectl cluster-info

以上命令的输出:

Nodes-Cluster-Info-Kubectl

通过执行 kubeadm join 命令来把两个工作节点加入到集群。

注意:请从 kubeadm init 命令的输出中复制完整的命令。在我的例子中,命令如下:

$ sudo kubeadm join k8s-master:6443 --token ta622t.enl212euq7z87mgj \
   --discovery-token-ca-cert-hash sha256:2be58f54458d0e788c96b8841f811069019161f9a3dd8502a38c773e5c6ead17

在工作节点 1 上的输出如下:

Worker-Node1-Join-Kunernetes-Cluster

在工作节点 2 上的输出如下:

Worker-Node2-Join-Kubernetes-Cluster

在主控节点上执行以下命令,检查节点的状态:

$ kubectl get nodes
NAME          STATUS     ROLES           AGE     VERSION
k8s-master    NotReady   control-plane   23m     v1.25.0
k8s-worker1   NotReady   <none>          9m27s   v1.25.0
k8s-worker2   NotReady   <none>          2m19s   v1.25.0
$

为了使节点状态变为 ready,我们需要安装 容器荚 Pod 网络插件,如 Calico 或 flannel。

8、安装 Calico Pod 网络插件

在主控节点上执行以下命令安装 Calico:

$ kubectl apply -f https://projectcalico.docs.tigera.io/manifests/calico.yaml

输出:

Install-calico-pod-network-addon-debian11

在所有节点上执行以下命令,配置防火墙允许 Calico 的端口:

$ sudo ufw allow 179/tcp
$ sudo ufw allow 4789/udp
$ sudo ufw allow 51820/udp
$ sudo ufw allow 51821/udp
$ sudo ufw allow 4789/udp
$ sudo ufw reload

执行以下命令检查下 Calico 的状态:

$ kubectl get pods -n kube-system

Calico-Pods-Status-Kuberenetes-Debian11

完美!现在再检查下节点状态:

Nodes-status-after-calico-Installation

非常棒!上面的输出说明主控节点和工作节点的状态都是 ready。现在这个集群可以正常工作了。

9、检查 Kubernetes 集群安装是否正确

我们尝试通过 deployment 命令来部署基于 Nginx 的应用程序,来验证 Kubernetes 集群的安装是否正确。执行以下命令:

$ kubectl create deployment nginx-app --image=nginx --replicas 2
$ kubectl expose deployment nginx-app --name=nginx-web-svc --type NodePort --port 80 --target-port 80
$ kubectl describe svc nginx-web-svc

以上命令的输出:

Nginx-Based-App-Kubernetes-Cluster-Debian11

使用以下的 curl 命令通过节点端口 30036 来访问基于 nginx 的应用程序。

注意:在 curl 命令中,可以使用两个工作节点任一的主机名。

$ curl http://k8s-worker1:30036

Access-Nginx-Based-App-via-NodePort-Kubernetes-Debian11

以上的输出说明我们可以正常访问基于 nginx 的应用程序了。

以上为全部内容。希望本文对你有用,参照本文可以在 Debian 11 上正常安装 Kubernetes 集群。如有任何问题,请在下面评论区告诉我。


via: https://www.linuxtechi.com/install-kubernetes-cluster-on-debian/

作者:Pradeep Kumar 选题:lkxed 译者:lxbwolf 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

看看这个很酷的 Kubernetes 管理的终端 UI。

通常情况下,我写的关于 Kubernetes 管理的文章中用的都是做集群管理的 kubectl 命令。然而最近,有人给我介绍了 k9s 项目,可以让我快速查看并解决 Kubernetes 中的日常问题。这极大地改善了我的工作流程,我会在这篇教程中告诉你如何上手它。

它可以安装在 Mac、Windows 和 Linux 中,每种操作系统的说明可以在这里找到。请先完成安装,以便能够跟上本教程。

我会使用 Linux 和 Minikube,这是一种在个人电脑上运行 Kubernetes 的轻量级方式。按照此教程或使用该文档来安装它。

设置 k9s 配置文件

安装好 k9s 应用后,从帮助命令开始总是很好的起点。

$ k9s help

正如你在帮助信息所看到的,我们可以用 k9s 来配置很多功能。我们唯一需要进行的步骤就是编写配置文件。而 info 命令会告诉我们该应用程序要在哪里找它的配置文件。

$ k9s info
 ____  __.________
|    |/ _/   __   \______
|      < \____    /  ___/
|    |  \   /    /\___ \
|____|__ \ /____//____  >
        \/            \/

Configuration:   /Users/jess/.k9s/config.yml
Logs:            /var/folders/5l/c1y1gcw97szdywgf9rk1100m0000gn/T/k9s-jess.log
Screen Dumps:    /var/folders/5l/c1y1gcw97szdywgf9rk1100m0000gn/T/k9s-screens-jess

如果要添加配置文件,该配置目录不存在的话就创建它,然后添加一个配置文件。

$ mkdir -p ~/.k9s/
$ touch ~/.k9s/config.yml

在这篇介绍中,我们将使用 k9s 版本库中推荐的默认 config.yml。维护者请注意,这种格式可能会有变化,可以在这里查看最新版本。

k9s:
  refreshRate: 2
  headless: false
  readOnly: false
  noIcons: false
  logger:
    tail: 200
    buffer: 500
    sinceSeconds: 300
    fullScreenLogs: false
    textWrap: false
    showTime: false
  currentContext: minikube
  currentCluster: minikube
  clusters:
    minikube:
      namespace:
        active: ""
        favorites:
        - all
        - kube-system
        - default
      view:
        active: dp
  thresholds:
    cpu:
      critical: 90
      warn: 70
    memory:
      critical: 90
      warn: 70

我们设置了 k9s 寻找本地的 minikube 配置,所以我要确认 minikube 已经上线可以使用了。

$ minikube status
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

运行 k9s 来探索一个 Kubernetes 集群

有了配置文件,并指向我们的本地集群,我们现在可以运行 k9s 命令了。

$ k9s

启动后,会弹出 k9s 的基于文本的用户界面。在没有指定命名空间标志的情况下,它会向你显示默认命名空间中的 Pod。

 title=

如果你运行在一个有很多 Pod 的环境中,默认视图可能会让人不知所措。或者,我们可以将注意力集中在给定的命名空间上。退出该应用程序,运行 k9s -n <namespace>,其中 <namespace> 是已存在的命名空间。在下图中,我运行了 k9s -n minecraft,它显示了我损坏的 Pod:

 title=

所以,一旦你有了 k9s 后,有很多事情你可以更快地完成。

通过快捷键来导航 k9s,我们可以随时使用方向键和回车键来选择列出的项目。还有不少其他的通用快捷键可以导航到不同的视图。

  • 0:显示在所有命名空间中的所有 Pod  title=
  • d:描述所选的 Pod  title=
  • l:显示所选的 Pod 的日志  title=

你可能会注意到 k9s 设置为使用 Vim 命令键,包括使用 JK 键上下移动等。Emacs 用户们,败退吧 :)

快速查看不同的 Kubernetes 资源

需要去找一个不在 Pod 里的东西吗?是的,我也需要。当我们输入冒号(:)键时,可以使用很多快捷方式。从那里,你可以使用下面的命令来导航。

  • :svc:跳转到服务视图  title=
  • :deploy:跳转到部署视图  title=
  • :rb:跳转到角色绑定视图,用于 基于角色的访问控制(RBAC)管理  title=
  • :namespace:跳转到命名空间视图  title=
  • :cj:跳转到 cronjob 视图,查看集群中计划了哪些作业。  title=

这个应用最常用的工具是键盘;要在任何页面往上或下翻页,请使用方向键。如果你需要退出,记得使用 Vim 绑定键,键入 :q,然后按回车键离开。

用 k9s 排除 Kubernetes 的故障示例

当出现故障的时候,k9s 怎么帮忙?举个例子,我让几个 Pod 由于配置错误而死亡。下面你可以看到我那个可怜的 “hello” 部署死了。当我们将其高亮显示出来,可以按 d 运行 describe 命令,看看是什么原因导致了故障。

 title=

 title=

草草掠过那些事件并不能告诉我们故障原因。接下来,我按了 esc 键,然后通过高亮显示 Pod 并输入shift-l 来检查日志。

 title=

不幸的是,日志也没有提供任何有用的信息(可能是因为部署从未正确配置过),而且 Pod 也没有出现。

然后我使用 esc 退了出来,我看看删除 Pod 是否能解决这个问题。要做到这一点,我高亮显示该 Pod,然后使用 ctrl-d。幸好 k9s 在删除前会提示用户。

 title=

虽然我确实删除了这个 Pod,但部署资源仍然存在,所以新的 Pod 会重新出现。无论什么原因(我们还不知道),它还会继续重启并死掉。

在这里,我会重复查看日志,描述资源,甚至使用 e 快捷方式来编辑运行中的 Pod 以排除故障行为。在这个特殊情况下,失败的 Pod 是因为没有配置在这个环境下运行。因此,让我们删除部署来停止崩溃接着重启的循环。

我们可以通过键入 :deploy 并点击回车进入部署。从那里我们高亮显示并按 ctrl-d 来删除。

 title=

 title=

这个有问题的部署被干掉了! 只用了几个按键就把这个失败的部署给清理掉了。

k9s 是极其可定制的

这个应用有很多自定义选项、乃至于 UI 的配色方案。这里有几个可编辑的选项,你可能会感兴趣。

  • 调整你放置 config.yml 文件的位置(这样你就可以把它存储在版本控制中)。
  • alias.yml 文件中添加自定义别名
  • hotkey.yml 文件中创建自定义热键
  • 探索现有的插件或编写自己的插件。

整个应用是在 YAML 文件中配置的,所以定制化对于任何 Kubernetes 管理员来说都会觉得很熟悉。

用 k9s 简化你的生活

我倾向于以一种非常手动的方式来管理我团队的系统,更多的是为了锻炼脑力,而不是别的。当我第一次听说 k9s 的时候,我想,“这只是懒惰的 Kubernetes 而已。”于是我否定了它,然后回到了到处进行人工干预的状态。实际上,当我在处理积压工作时就开始每天使用它,而让我震惊的是它比单独使用 kubectl 快得多。现在,我已经皈依了。

了解你的工具并掌握做事情的“硬道理”很重要。还有一点很重要的是要记住,就管理而言,重要的是要更聪明地工作,而不是更努力。使用 k9s,就是我践行这个目标的方法。我想,我们可以把它叫做懒惰的 Kubernetes 管理,也没关系。


via: https://opensource.com/article/20/5/kubernetes-administration

作者:Jessica Cherry 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Kubernetes 解决了一些开发和运维团队每天关注的的常见问题。

Kubernetes(K8S)是面向企业的开源容器编排工具的事实标准。它提供了应用部署、扩展、容器管理和其他功能,使企业能够通过容错能力快速优化硬件资源利用率并延长生产环境运行时间。该项目最初由谷歌开发,并将该项目捐赠给云原生计算基金会(CNCF)。2018 年,它成为第一个从 CNCF 毕业的项目。

这一切都很好,但它并不能解释为什么开发者和运维人员应该在 Kubernetes 上投入宝贵的时间和精力。Kubernetes 之所以如此有用,是因为它有助于开发者和运维人员迅速解决他们每天都在努力解决的问题。

以下是 Kubernetes 帮助开发者和运维人员解决他们最常见问题的五种能力。

1、厂商无关

许多公有云提供商不仅提供托管 Kubernetes 服务,还提供许多基于这些服务构建的云产品,来用于本地应用容器编排。由于与供应商无关,使运营商能够轻松、安全地设计、构建和管理多云和混合云平台,而不会有供应商锁定的风险。Kubernetes 还消除了运维团队对复杂的多云/混合云战略的担忧。

2、服务发现

为了开发微服务应用,Java 开发人员必须控制服务可用性(就应用是否可以提供服务而言),并确保服务持续存在,以响应客户端的请求,而没有任何例外。Kubernetes 的服务发现功能意味着开发人员不再需要自己管理这些东西。

3、触发

你的 DevOps 会如何在上千台虚拟机上部署多语言、云原生应用?理想情况下,开发和运维会在 bug 修复、功能增强、新功能、安全更新时触发部署。Kubernetes 的部署功能会自动化这个日常工作。更重要的时,它支持高级部署策略,例如蓝绿部署和金丝雀部署

4、可伸缩性

自动扩展是处理云环境中大量工作负载所需的关键功能。通过构建容器平台,你可以为终端用户提高系统可靠性。Kubernetes Horizo​​ntal Pod Autoscaler(HPA)允许一个集群增加或减少应用程序(或 Pod)的数量,以应对峰值流量或性能峰值,从而减少对意外系统中断的担忧。

5、容错性

在现代应用体系结构中,应考虑故障处理代码来控制意外错误并快速从中恢复。但是开发人员需要花费大量的时间和精力来模拟偶然的错误。Kubernetes 的 ReplicaSet 通过确保指定数量的 Pod 持续保持活动来帮助开发人员解决此问题。

结论

Kubernetes 使企业能够轻松、快速、安全地解决常见的开发和运维问题。它还提供其他好处,例如构建无缝的多云/混合云战略,节省基础架构成本以及加快产品上市时间。


via: https://opensource.com/article/19/6/reasons-kubernetes

作者:Daniel Oh 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Fedora IoT 是一个即将发布的、面向物联网的 Fedora 版本。去年 Fedora Magazine 的《如何使用 Fedora IoT 点亮 LED 灯》一文第一次介绍了它。从那以后,它与 Fedora Silverblue 一起不断改进,以提供针对面向容器的工作流的不可变基础操作系统。

Kubernetes 是一个颇受欢迎的容器编排系统。它可能最常用在那些能够处理巨大负载的强劲硬件上。不过,它也能在像树莓派 3 这样轻量级的设备上运行。让我们继续阅读,来了解如何运行它。

为什么用 Kubernetes?

虽然 Kubernetes 在云计算领域风靡一时,但让它在小型单板机上运行可能并不是常见的。不过,我们有非常明确的理由来做这件事。首先,这是一个不需要昂贵硬件就可以学习并熟悉 Kubernetes 的好方法;其次,由于它的流行性,市面上有大量应用进行了预先打包,以用于在 Kubernetes 集群中运行。更不用说,当你遇到问题时,会有大规模的社区用户为你提供帮助。

最后但同样重要的是,即使是在家庭实验室这样的小规模环境中,容器编排也确实能够使事情变得更加简单。虽然在学习曲线方面,这一点并不明显,但这些技能在你将来与任何集群打交道的时候都会有帮助。不管你面对的是一个单节点树莓派集群,还是一个大规模的机器学习场,它们的操作方式都是类似的。

K3s - 轻量级的 Kubernetes

一个“正常”安装的 Kubernetes(如果有这么一说的话)对于物联网来说有点沉重。K8s 的推荐内存配置,是每台机器 2GB!不过,我们也有一些替代品,其中一个新人是 k3s —— 一个轻量级的 Kubernetes 发行版。

K3s 非常特殊,因为它将 etcd 替换成了 SQLite 以满足键值存储需求。还有一点,在于整个 k3s 将使用一个二进制文件分发,而不是每个组件一个。这减少了内存占用并简化了安装过程。基于上述原因,我们只需要 512MB 内存即可运行 k3s,极度适合小型单板电脑!

你需要的东西

  1. Fedora IoT 运行在虚拟机或实体设备中运行的。在这里可以看到优秀的入门指南。一台机器就足够了,不过两台可以用来测试向集群添加更多节点。
  2. 配置防火墙,允许 6443 和 8372 端口的通信。或者,你也可以简单地运行 systemctl stop firewalld 来为这次实验关闭防火墙。

安装 k3s

安装 k3s 非常简单。直接运行安装脚本:

curl -sfL https://get.k3s.io | sh -

它会下载、安装并启动 k3s。安装完成后,运行以下命令来从服务器获取节点列表:

kubectl get nodes

需要注意的是,有几个选项可以通过环境变量传递给安装脚本。这些选项可以在文档中找到。当然,你也完全可以直接下载二进制文件来手动安装 k3s。

对于实验和学习来说,这样已经很棒了,不过单节点的集群也不能算一个集群。幸运的是,添加另一个节点并不比设置第一个节点要难。只需要向安装脚本传递两个环境变量,它就可以找到第一个节点,而不用运行 k3s 的服务器部分。

curl -sfL https://get.k3s.io | K3S_URL=https://example-url:6443 \
  K3S_TOKEN=XXX sh -

上面的 example-url 应被替换为第一个节点的 IP 地址,或一个完全限定域名。在该节点中,(用 XXX 表示的)令牌可以在 /var/lib/rancher/k3s/server/node-token 文件中找到。

部署一些容器

现在我们有了一个 Kubernetes 集群,我们可以真正做些什么呢?让我们从部署一个简单的 Web 服务器开始吧。

kubectl create deployment my-server --image nginx

这会从名为 nginx 的容器镜像中创建出一个名叫 my-server部署(默认使用 docker hub 注册中心,以及 latest 标签)。

kubectl get pods

为了访问到 pod 中运行的 nginx 服务器,首先通过一个 服务 来暴露该部署。以下命令将创建一个与该部署同名的服务。

kubectl expose deployment my-server --port 80

服务将作为一种负载均衡器和 Pod 的 DNS 记录来工作。比如,当运行第二个 Pod 时,我们只需指定 my-server(服务名称)就可以通过 curl 访问 nginx 服务器。有关如何操作,可以看下面的实例。

# 启动一个 pod,在里面以交互方式运行 bash
kubectl run debug --generator=run-pod/v1 --image=fedora -it -- bash
# 等待 bash 提示符出现
curl my-server
# 你可以看到“Welcome to nginx!”的输出页面

Ingress 控制器及外部 IP

默认状态下,一个服务只能获得一个 ClusterIP(只能从集群内部访问),但你也可以通过把它的类型设置为 LoadBalancer 为该服务申请一个外部 IP。不过,并非所有应用都需要自己的 IP 地址。相反,通常可以通过基于 Host 请求头部或请求路径进行路由,从而使多个服务共享一个 IP 地址。你可以在 Kubernetes 使用 Ingress 完成此操作,而这也是我们要做的。Ingress 也提供了额外的功能,比如无需配置应用即可对流量进行 TLS 加密。

Kubernetes 需要 Ingress 控制器来使 Ingress 资源工作,k3s 包含 Traefik 正是出于此目的。它还包含了一个简单的服务负载均衡器,可以为集群中的服务提供外部 IP。这篇文档描述了这种服务:

k3s 包含一个使用可用主机端口的基础服务负载均衡器。比如,如果你尝试创建一个监听 80 端口的负载均衡器,它会尝试在集群中寻找一个 80 端口空闲的节点。如果没有可用端口,那么负载均衡器将保持在 Pending 状态。

k3s README

Ingress 控制器已经通过这个负载均衡器暴露在外。你可以使用以下命令找到它正在使用的 IP 地址。

$ kubectl get svc --all-namespaces
NAMESPACE     NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
 default       kubernetes   ClusterIP      10.43.0.1               443/TCP                      33d
 default       my-server    ClusterIP      10.43.174.38            80/TCP                       30m
 kube-system   kube-dns     ClusterIP      10.43.0.10              53/UDP,53/TCP,9153/TCP       33d
 kube-system   traefik      LoadBalancer   10.43.145.104   10.0.0.8      80:31596/TCP,443:31539/TCP   33d

找到名为 traefik 的服务。在上面的例子中,我们感兴趣的 IP 是 10.0.0.8。

路由传入的请求

让我们创建一个 Ingress,使它通过基于 Host 头部的路由规则将请求路由至我们的服务器。这个例子中我们使用 xip.io 来避免必要的 DNS 记录配置工作。它的工作原理是将 IP 地址作为子域包含,以使用 10.0.0.8.xip.io 的任何子域来达到 IP 10.0.0.8。换句话说,my-server.10.0.0.8.xip.io 被用于访问集群中的 Ingress 控制器。你现在就可以尝试(使用你自己的 IP,而不是 10.0.0.8)。如果没有 Ingress,你应该会访问到“默认后端”,只是一个写着“404 page not found”的页面。

我们可以使用以下 Ingress 让 Ingress 控制器将请求路由到我们的 Web 服务器的服务。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-server
spec:
  rules:
    - host: my-server.10.0.0.8.xip.io
      http:
        paths:
          - path: /
            backend:
              serviceName: my-server
              servicePort: 80

将以上片段保存到 my-ingress.yaml 文件中,然后运行以下命令将其加入集群:

kubectl apply -f my-ingress.yaml

你现在应该能够在你选择的完全限定域名中访问到 nginx 的默认欢迎页面了。在我的例子中,它是 my-server.10.0.0.8.xip.io。Ingress 控制器会通过 Ingress 中包含的信息来路由请求。对 my-server.10.0.0.8.xip.io 的请求将被路由到 Ingress 中定义为 backend 的服务和端口(在本例中为 my-server80)。

那么,物联网呢?

想象如下场景:你的家或农场周围有很多的设备。它是一个具有各种硬件功能、传感器和执行器的物联网设备的异构集合。也许某些设备拥有摄像头、天气或光线传感器。其它设备可能会被连接起来,用来控制通风、灯光、百叶窗或闪烁的 LED。

这种情况下,你想从所有传感器中收集数据,在最终使用它来制定决策和控制执行器之前,也可能会对其进行处理和分析。除此之外,你可能还想配置一个仪表盘来可视化那些正在发生的事情。那么 Kubernetes 如何帮助我们来管理这样的事情呢?我们怎么保证 Pod 在合适的设备上运行?

简单的答案就是“标签”。你可以根据功能来标记节点,如下所示:

kubectl label nodes <node-name> <label-key>=<label-value>
# 举例
kubectl label nodes node2 camera=available

一旦它们被打上标签,我们就可以轻松地使用 nodeSelector 为你的工作负载选择合适的节点。拼图的最后一块:如果你想在所有合适的节点上运行 Pod,那应该使用 DaemonSet 而不是部署。换句话说,应为每个使用唯一传感器的数据收集应用程序创建一个 DaemonSet,并使用 nodeSelector 确保它们仅在具有适当硬件的节点上运行。

服务发现功能允许 Pod 通过服务名称来寻找彼此,这项功能使得这类分布式系统的管理工作变得易如反掌。你不需要为应用配置 IP 地址或自定义端口,也不需要知道它们。相反,它们可以通过集群中的命名服务轻松找到彼此。

充分利用空闲资源

随着集群的启动并运行,收集数据并控制灯光和气候,可能使你觉得你已经把它完成了。不过,集群中还有大量的计算资源可以用于其它项目。这才是 Kubernetes 真正出彩的地方。

你不必担心这些资源的确切位置,或者去计算是否有足够的内存来容纳额外的应用程序。这正是编排系统所解决的问题!你可以轻松地在集群中部署更多的应用,让 Kubernetes 来找出适合运行它们的位置(或是否适合运行它们)。

为什么不运行一个你自己的 NextCloud 实例呢?或者运行 gitea?你还可以为你所有的物联网容器设置一套 CI/CD 流水线。毕竟,如果你可以在集群中进行本地构建,为什么还要在主计算机上构建并交叉编译它们呢?

这里的要点是,Kubernetes 可以更容易地利用那些你可能浪费掉的“隐藏”资源。Kubernetes 根据可用资源和容错处理规则来调度 Pod,因此你也无需手动完成这些工作。但是,为了帮助 Kubernetes 做出合理的决定,你绝对应该为你的工作负载添加资源请求配置。

总结

尽管 Kuberenetes 或一般的容器编排平台通常不会与物联网相关联,但在管理分布式系统时,使用一个编排系统肯定是有意义的。你不仅可以使用统一的方式来处理多样化和异构的设备,还可以简化它们的通信方式。此外,Kubernetes 还可以更好地对闲置资源加以利用。

容器技术使构建“随处运行”应用的想法成为可能。现在,Kubernetes 可以更轻松地来负责“随处”的部分。作为构建一切的不可变基础,我们使用 Fedora IoT。


via: https://fedoramagazine.org/kubernetes-on-fedora-iot-with-k3s/

作者:Lennart Jern 选题:lujun9972 译者:StdioA 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这也许是一个不太受欢迎的观点,但大多数主流公司最好不要再使用 k8s 了。

你知道那个古老的“以程序员技能写 Hello world ”笑话吗?—— 从一个新手程序员的 printf("hello, world\n") 语句开始,最后结束于高级软件架构工程师令人费解的 Java OOP 模式设计。使用 k8s 就有点像这样。

  • 新手系统管理员:

./binary

  • 有经验的系统管理员:

在 EC2 上的 ./binary

  • DevOp:

在 EC2 上自部署的 CI 管道运行 ./binary

  • 高级云编排工程师:

在 EC2 上通过 k8s 编排的自部署 CI 管道运行 ./binary

¯\\_(ツ)\_/¯

这不意味着 Kubernetes 或者任何这样的东西本身都是坏的,就像 Java 或者 OOP 设计本身并不是坏的一样,但是,在很多情况下,它们被严重地误用,就像在一个 hello world 的程序中可怕地误用 Java 面向对象设计模式一样。对大多数公司而言,系统运维从根本上来说并不十分复杂,此时在这上面应用 k8s 起效甚微。

复杂性本质上来说创造了工作,我十分怀疑使用 k8s 对大多数使用者来说是省时的这一说法。这就好像花一天时间来写一个脚本,用来自动完成一些你一个月进行一次,每次只花 10 分钟完成的工作。这不是一个好的时间投资(特别是你可能会在未来由于扩展或调试这个脚本而进一步投入的更多时间)。

你的部署大概应该需要自动化 – 以免你 最终像 Knightmare 那样 —— 但 k8s 通常可以被一个简单的 shell 脚本所替代。

在我们公司,系统运维团队用了很多时间来设置 k8s 。他们还不得不用了很大一部分时间来更新到新一点的版本(1.6 ➙ 1.8)。结果是如果没有真正深入理解 k8s ,有些东西就没人会真的明白,甚至连深入理解 k8s 这一点也很难(那些 YAML 文件,哦呦!)

在我能自己调试和修复部署问题之前 —— 现在这更难了,我理解基本概念,但在真正调试实际问题的时候,它们并不是那么有用。我不经常用 k8s 足以证明这点。


k8s 真的很难这点并不是什么新看法,这也是为什么现在会有这么多 “k8s 简单用”的解决方案。在 k8s 上再添一层来“让它更简单”的方法让我觉得,呃,不明智。复杂性并没有消失,你只是把它藏起来了。

以前我说过很多次:在确定一样东西是否“简单”时,我最关心的不是写东西的时候有多简单,而是当失败的时候调试起来有多容易。包装 k8s 并不会让调试更加简单,恰恰相反,它让事情更加困难了。


Blaise Pascal 有一句名言:

几乎所有的痛苦都来自于我们不善于在房间里独处。

k8s —— 略微拓展一下,Docker —— 似乎就是这样的例子。许多人似乎迷失在当下的兴奋中,觉得 “k8s 就是这么回事!”,就像有些人迷失在 Java OOP 刚出来时的兴奋中一样,所以一切都必须从“旧”方法转为“新”方法,即使“旧”方法依然可行。

有时候 IT 产业挺蠢的。

或者用 一条推特 来总结:

  • 2014 - 我们必须采用 #微服务 来解决独石应用的所有问题
  • 2016 - 我们必须采用 #docker 来解决微服务的所有问题
  • 2018 - 我们必须采用 #kubernetes 来解决 docker 的所有问题

你可以通过 [email protected] 给我发邮件或者 创建 GitHub issue 来给我反馈或提出问题等。


via: https://arp242.net/weblog/dont-need-k8s.html

作者:Martin Tournoij 选题:lujun9972 译者:beamrolling 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出