ubuntn 20.04 安装搭建k8s 集群

control_plane_ip: 主节点ip(例如172.19.33.41)

worker_1_ip: 从节点ip

worker_2_ip:从节点ip

第 1 步 — 设置工作区目录和 Ansible 库存文件

在本节中,您将在本地计算机上创建一个目录作为您的工作区。您将在本地配置 Ansible,以便它可以与远程服务器通信并在远程服务器上执行命令。完成后,您将创建一个hosts包含库存信息的文件,例如服务器的 IP 地址和每个服务器所属的组。

在您的三台服务器中,一台是控制平面,其 IP 显示为control_plane_ip. 另外两台服务器将是工作服务器,并将拥有 IPworker_1_ipworker_2_ip.

~/kube-cluster在本地计算机的主目录中创建一个名为的目录并将cd其放入:

 
 
  1. mkdir ~/kube-cluster
  2. cd ~/kube-cluster
复制

该目录将成为本教程其余部分的工作区,并将包含您的所有 Ansible 剧本。它也将是您将在其中运行所有本地命令的目录。

创建一个~/kube-cluster/hosts使用nano或您喜欢的文本编辑器命名的文件:

 
 
  1. nano ~/kube-cluster/hosts
复制

将以下文本添加到文件中,该文件将指定有关集群逻辑结构的信息:

~/kube-cluster/主机
[control_plane]
control1 ansible_host=control_plane_ip ansible_user=root 

[workers]
worker1 ansible_host=worker_1_ip ansible_user=root
worker2 ansible_host=worker_2_ip ansible_user=root

[all:vars]
ansible_python_interpreter=/usr/bin/python3
复制

您可能还记得Ansible 中的清单文件用于指定服务器信息,例如 IP 地址、远程用户和服务器组,以作为执行命令的单个单元。~/kube-cluster/hosts将是您的清单文件,并且您已向其中添加了两个 Ansible 组(控制平面工作人员),指定了集群的逻辑结构。

控制平面组中,有一个名为“control1”的服务器条目,它列出了控制平面的 IP ( control_plane_ip),并指定 Ansible 应以 root 用户身份运行远程命令。

同样,在工作组中,工作服务器有两个条目 (worker_1_ipworker_2_ip),它们也指定ansible_user为 root。

该文件的最后一行告诉 Ansible 使用远程服务器的 Python 3 解释器进行管理操作。

添加文本后保存并关闭文件。如果您正在使用nano,请按Ctrl+X,然后在出现提示时按 ,Y然后按Enter

使用组设置服务器清单后,让我们继续安装操作系统级别的依赖项并创建配置设置。

第 2 步 — 在所有远程服务器上创建非根用户

在本节中,您将在所有服务器上创建一个具有 sudo 权限的非 root 用户,以便您可以作为非特权用户手动 SSH 到它们。例如,如果您想使用命令查看系统信息top/htop、查看正在运行的容器列表或更改 root 拥有的配置文件,这将很有用。这些操作是在集群维护期间例行执行的,使用非 root 用户执行此类任务可以最大限度地降低修改或删除重要文件或无意执行其他危险操作的风险。

在工作区中创建一个名为的文件~/kube-cluster/initial.yml

 
 
  1. nano ~/kube-cluster/initial.yml
复制

接下来,将以下播放添加到文件中,以在所有服务器上创建一个具有 sudo 权限的非 root 用户。Ansible 中的 play 是针对特定服务器和组的要执行的步骤的集合。以下播放将创建一个非 root sudo 用户:

~/kube-cluster/initial.yml
---
- hosts: all
  become: yes
  tasks:
    - name: create the 'ubuntu' user
      user: name=ubuntu append=yes state=present createhome=yes shell=/bin/bash

    - name: allow 'ubuntu' to have passwordless sudo
      lineinfile:
        dest: /etc/sudoers
        line: 'ubuntu ALL=(ALL) NOPASSWD: ALL'
        validate: 'visudo -cf %s'

    - name: set up authorized keys for the ubuntu user
      authorized_key: user=ubuntu key="{{item}}"
      with_file:
        - ~/.ssh/id_rsa.pub
复制

以下是该剧本的功能细分:

  • 创建非 root 用户ubuntu

  • 配置sudoers文件以允许ubuntu用户在没有密码提示的情况下运行sudo命令。

  • 将本地计算机(通常~/.ssh/id_rsa.pub)中的公钥添加到远程ubuntu用户的授权密钥列表中。这将允许您以ubuntu用户身份通过​​ SSH 连接到每个服务器。

添加文本后保存并关闭文件。

接下来,在本地运行 playbook:

 
 
  1. ansible-playbook -i hosts ~/kube-cluster/initial.yml
复制

该命令将在两到五分钟内完成。完成后,您将看到类似于以下内容的输出:

 
Output

PLAY [all] **** TASK [Gathering Facts] **** ok: [control1] ok: [worker1] ok: [worker2] TASK [create the 'ubuntu' user] **** changed: [control1] changed: [worker1] changed: [worker2] TASK [allow 'ubuntu' user to have passwordless sudo] **** changed: [control1] changed: [worker1] changed: [worker2] TASK [set up authorized keys for the ubuntu user] **** changed: [worker1] => (item=ssh-rsa AAAAB3...) changed: [worker2] => (item=ssh-rsa AAAAB3...) changed: [control1] => (item=ssh-rsa AAAAB3...) PLAY RECAP **** control1 : ok=4 changed=3 unreachable=0 failed=0 worker1 : ok=4 changed=3 unreachable=0 failed=0 worker2 : ok=4 changed=3 unreachable=0 failed=0

现在初步设置已完成,您可以继续安装 Kubernetes 特定的依赖项。

第 3 步 — 安装 Kubernetes 的依赖项

在本节中,您将使用 Ubuntu 的包管理器安装 Kubernetes 所需的操作系统级包。这些软件包是:

  • Docker - 一个容器运行时。它是运行容器的组件。Kubernetes 支持其他运行时,但 Docker 仍然是一种流行且直接的选择。

  • kubeadm- 一个 CLI 工具,它将以标准方式安装和配置集群的各种组件。

  • kubelet- 在所有节点上运行并处理节点级操作的系统服务/程序。

  • kubectl- 一个 CLI 工具,用于通过其 API 服务器向集群发出命令。

在工作区中创建一个名为的文件~/kube-cluster/kube-dependencies.yml

 
 
  1. nano ~/kube-cluster/kube-dependencies.yml
复制

将以下播放添加到文件中以将这些软件包安装到您的服务器:

~/kube-cluster/kube-dependencies.yml
---
- hosts: all
  become: yes
  tasks:
   - name: create Docker config directory
     file: path=/etc/docker state=directory

   - name: changing Docker to systemd driver
     copy:
      dest: "/etc/docker/daemon.json"
      content: |
        {
        "exec-opts": ["native.cgroupdriver=systemd"]
        }

   - name: install Docker
     apt:
       name: docker.io
       state: present
       update_cache: true

   - name: install APT Transport HTTPS
     apt:
       name: apt-transport-https
       state: present

   - name: add Kubernetes apt-key
     apt_key:
       url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
       state: present

   - name: add Kubernetes' APT repository
     apt_repository:
      repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
      state: present
      filename: 'kubernetes'

   - name: install kubelet
     apt:
       name: kubelet=1.22.4-00
       state: present
       update_cache: true

   - name: install kubeadm
     apt:
       name: kubeadm=1.22.4-00
       state: present

- hosts: control_plane
  become: yes
  tasks:
   - name: install kubectl
     apt:
       name: kubectl=1.22.4-00
       state: present
       force: yes
复制

playbook 中的第一个 play 执行以下操作:

  • 安装 Docker、容器运行时并配置兼容性设置。

  • 安装apt-transport-https,允许您将外部 HTTPS 源添加到 APT 源列表。

  • 添加 Kubernetes APT 存储库的 apt-key 用于密钥验证。

  • 将 Kubernetes APT 存储库添加到远程服务器的 APT 源列表。

  • 安装kubeletkubeadm.

kubectl第二个游戏由安装在您的控制平面节点上的单个任务组成。

注意:虽然 Kubernetes 文档建议您为您的环境使用 Kubernetes 的最新稳定版本,但本教程使用特定版本。这将确保您可以成功执行这些步骤,因为 Kubernetes 变化很快,并且最新版本可能不适用于本教程。虽然“xenial”是 Ubuntu 16.04 的名称,而且本教程是针对 Ubuntu 20.04 的,但 Kubernetes 仍然默认指的是 Ubuntu 16.04 的包源,并且在这种情况下它们在 20.04 上是支持的。

完成后保存并关闭文件。

接下来,使用以下命令在本地运行 playbook:

 
 
  1. ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml
复制

完成后,您将收到类似于以下内容的输出:

 
Output

PLAY [all] **** TASK [Gathering Facts] **** ok: [worker1] ok: [worker2] ok: [control1] TASK [create Docker config directory] **** changed: [control1] changed: [worker1] changed: [worker2] TASK [changing Docker to systemd driver] **** changed: [control1] changed: [worker1] changed: [worker2] TASK [install Docker] **** changed: [control1] changed: [worker1] changed: [worker2] TASK [install APT Transport HTTPS] ***** ok: [control1] ok: [worker1] changed: [worker2] TASK [add Kubernetes apt-key] ***** changed: [control1] changed: [worker1] changed: [worker2] TASK [add Kubernetes' APT repository] ***** changed: [control1] changed: [worker1] changed: [worker2] TASK [install kubelet] ***** changed: [control1] changed: [worker1] changed: [worker2] TASK [install kubeadm] ***** changed: [control1] changed: [worker1] changed: [worker2] PLAY [control1] ***** TASK [Gathering Facts] ***** ok: [control1] TASK [install kubectl] ****** changed: [control1] PLAY RECAP **** control1 : ok=11 changed=9 unreachable=0 failed=0 worker1 : ok=9 changed=8 unreachable=0 failed=0 worker2 : ok=9 changed=8 unreachable=0 failed=0

运行此 playbook 后,Docker、kubeadmkubelet将安装在所有远程服务器上。kubectl不是必需的组件,仅用于执行集群命令。在这种情况下,仅将其安装在控制平面节点上是有意义的,因为您将kubectl仅从控制平面运行命令。但是请注意,kubectl命令可以从任何工作节点或任何可以安装和配置为指向集群的机器上运行。

现在已安装所有系统依赖项。让我们设置控制平面节点并初始化集群。

第 4 步 — 设置控制平面节点

在本节中,您将设置控制平面节点。然而,在创建任何剧本之前,有必要了解一些概念,例如PodsPod Network Plugins,因为您的集群将同时包含这两者。

Pod 是运行一个或多个容器的原子单元。这些容器共享资源,例如文件卷和网络接口。Pod 是 Kubernetes 中调度的基本单元:一个 pod 中的所有容器都保证在该 pod 被调度的同一节点上运行。

每个 pod 都有自己的 IP 地址,一个节点上的 pod 应该能够使用 pod 的 IP 访问另一个节点上的 pod。单个节点上的容器可以通过本地接口轻松通信。然而,pod 之间的通信更加复杂,并且需要一个单独的网络组件,该组件可以透明地将流量从一个节点上的 pod 路由到另一个节点上的 pod。

此功能由 pod 网络插件提供。对于此集群,您将使用Flannel,这是一个稳定且高性能的选项。

创建一个control-plane.yml在本地机器上命名的 Ansible playbook:

 
 
  1. nano ~/kube-cluster/control-plane.yml
复制

在文件中添加以下 play 来初始化集群并安装 Flannel:

~/kube-cluster/control-plane.yml
---
- hosts: control_plane
  become: yes
  tasks:
    - name: initialize the cluster
      shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
      args:
        chdir: $HOME
        creates: cluster_initialized.txt

    - name: create .kube directory
      become: yes
      become_user: ubuntu
      file:
        path: $HOME/.kube
        state: directory
        mode: 0755

    - name: copy admin.conf to user's kube config
      copy:
        src: /etc/kubernetes/admin.conf
        dest: /home/ubuntu/.kube/config
        remote_src: yes
        owner: ubuntu

    - name: install Pod network
      become: yes
      become_user: ubuntu
      shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml >> pod_network_setup.txt
      args:
        chdir: $HOME
        creates: pod_network_setup.txt
复制

以下是这部剧的详细介绍:

  • 第一个任务通过运行初始化集群kubeadm init。传递参数--pod-network-cidr=10.244.0.0/16指定将从中分配 pod IP 的私有子网。Flannel 默认使用上述子网;我们告诉kubeadm使用相同的子网。

  • 第二个任务.kube/home/ubuntu. 此目录将保存配置信息,例如连接到集群所需的管理密钥文件和集群的 API 地址。

  • 第三个任务将/etc/kubernetes/admin.conf生成的文件复制kubeadm init到非 root 用户的主目录。这将允许您使用kubectl来访问新创建的集群。

  • 最后一个任务运行kubectl apply安装Flannelkubectl apply -f descriptor.[yml|json]是告诉kubectl创建descriptor.[yml|json]文件中描述的对象的语法。该文件包含在集群kube-flannel.yml中设置所需的对象的描述。Flannel

完成后保存并关闭文件。

使用以下命令在本地运行 playbook:

 
 
  1. ansible-playbook -i hosts ~/kube-cluster/control-plane.yml
复制

完成后,您将看到类似于以下内容的输出:

 
Output

PLAY [control1] **** TASK [Gathering Facts] **** ok: [control1] TASK [initialize the cluster] **** changed: [control1] TASK [create .kube directory] **** changed: [control1] TASK [copy admin.conf to user's kube config] ***** changed: [control1] TASK [install Pod network] ***** changed: [control1] PLAY RECAP **** control1 : ok=5 changed=4 unreachable=0 failed=0

如果出现

error execution phase upload-config/kubelet: Error writing Crisocket information for the control-plane node: timed out waiting for the condition
To see the stack trace of this error execute with --v=5 or higher
 

说明iptables 有问题,执行如下操作

swapoff -a
kubeadm reset
systemctl daemon-reload
systemctl restart kubelet
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X  

然后从新执行

ansible-playbook -i hosts ~/kube-cluster/control-plane.yml

要检查控制平面节点的状态,请使用以下命令通过 SSH 连接到它:

 
 
  1. ssh ubuntu@control_plane_ip
复制

进入控制平面节点后,执行:

 
 
  1. kubectl get nodes
复制

您现在将看到以下输出:

 
Output

NAME STATUS ROLES AGE VERSION control1 Ready control-plane,master 51s v1.22.4

注意:从 Ubuntu 20.04 开始,kubernetes 正在更新他们的旧术语。control-plane我们在本教程中提到的节点过去称为master节点,有时您会看到 kubernetes 出于兼容性原因同时分配两个角色。

输出表明control-plane节点已完成所有初始化任务,并处于Ready可以开始接受工作节点并执行发送到 API Server 的任务的状态。您现在可以从本地计算机添加工作人员。

第 5 步 — 设置工作节点

将工作人员添加到集群涉及在每个工作人员上执行单个命令。该命令包括必要的集群信息,例如控制平面的 API 服务器的 IP 地址和端口,以及安全令牌。只有传入安全令牌的节点才能加入集群。

导航回您的工作区并创建一个名为的剧本workers.yml

 
 
  1. nano ~/kube-cluster/workers.yml
复制

将以下文本添加到文件中以将工作人员添加到集群:

~/kube-cluster/workers.yml
---
- hosts: control_plane
  become: yes
  gather_facts: false
  tasks:
    - name: get join command
      shell: kubeadm token create --print-join-command
      register: join_command_raw

    - name: set join command
      set_fact:
        join_command: "{{ join_command_raw.stdout_lines[0] }}"


- hosts: workers
  become: yes
  tasks:
    - name: join cluster
      shell: "{{ hostvars['control1'].join_command }} >> node_joined.txt"
      args:
        chdir: $HOME
        creates: node_joined.txt
复制

这是剧本的作用:

  • 第一次播放获取需要在工作节点上运行的连接命令。该命令将采用以下格式:kubeadm join --token <token> <control-plane-ip>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>. 一旦它获得具有正确令牌哈希值的实际命令,该任务将其设置为事实,以便下一次播放将能够访问该信息。

  • 第二个游戏有一个任务,在所有工作节点上运行 join 命令。完成此任务后,两个工作节点将成为集群的一部分。

完成后保存并关闭文件。

使用以下命令在本地运行 playbook:

 
 
  1. ansible-playbook -i hosts ~/kube-cluster/workers.yml
复制

完成后,您将看到类似于以下内容的输出:

 
Output

PLAY [control1] **** TASK [get join command] **** changed: [control1] TASK [set join command] ***** ok: [control1] PLAY [workers] ***** TASK [Gathering Facts] ***** ok: [worker1] ok: [worker2] TASK [join cluster] ***** changed: [worker1] changed: [worker2] PLAY RECAP ***** control1 : ok=2 changed=1 unreachable=0 failed=0 worker1 : ok=2 changed=1 unreachable=0 failed=0 worker2 : ok=2 changed=1 unreachable=0 failed=0

随着工作节点的添加,您的集群现在已完全设置并正常运行,工作人员已准备好运行工作负载。在调度应用程序之前,让我们验证集群是否按预期工作。

第 6 步 — 验证集群

集群有时会在设置过程中失败,因为节点已关闭或控制平面和工作人员之间的网络连接无法正常工作。让我们验证集群并确保节点正常运行。

您需要从控制平面节点检查集群的当前状态,以确保节点已准备就绪。如果您与控制平面节点断开连接,您可以使用以下命令通过 SSH 重新连接到该节点:

 
 
  1. ssh ubuntu@control_plane_ip
复制

然后执行以下命令获取集群的状态:

 
 
  1. kubectl get nodes
复制

您将看到类似于以下内容的输出:

 
Output

NAME STATUS ROLES AGE VERSION control1 Ready control-plane,master 3m21s v1.22.0 worker1 Ready <none> 32s v1.22.0 worker2 Ready <none> 32s v1.22.0

如果您的所有节点都具有 的值ReadySTATUS则表示它们是集群的一部分并准备好运行工作负载。

但是,如果一些节点具有NotReadySTATUS则可能意味着工作节点尚未完成设置。等待大约五到十分钟,然后重新运行kubectl get nodes并检查新输出。如果有几个节点仍然NotReady处于状态,您可能需要验证并重新运行前面步骤中的命令。

现在您的集群已成功验证,让我们在集群上安排一个示例 Nginx 应用程序。

第 7 步 — 在集群上运行应用程序

您现在可以将任何容器化应用程序部署到您的集群。为了保持熟悉,让我们使用部署服务来部署 Nginx ,以探索如何将这个应用程序部署到集群中。您也可以将以下命令用于其他容器化应用程序,前提是您更改 Docker 映像名称和任何相关标志(例如portsvolumes)。

确保您已登录到控制平面节点,然后运行以下命令来创建名为 的部署nginx

 
 
  1. kubectl create deployment nginx --image=nginx
复制

部署是一种 Kubernetes 对象,可确保始终基于定义的模板运行指定数量的 pod,即使 pod 在集群的生命周期内崩溃。上述部署将从 Docker 注册表的Nginx Docker Image创建一个带有一个容器的 pod 。

接下来,运行以下命令来创建一个名为的服务,该服务nginx将公开公开应用程序。它将通过NodePort执行此操作,该方案将使 pod 可以通过在集群的每个节点上打开的任意端口访问:

 
 
  1. kubectl expose deploy nginx --port 80 --target-port 80 --type NodePort
复制

服务是另一种类型的 Kubernetes 对象,它向内部和外部客户端公开集群内部服务。它们还能够对多个 pod 的请求进行负载平衡,并且是 Kubernetes 中不可或缺的组件,经常与其他组件交互。

运行以下命令:

 
 
  1. kubectl get services
复制

此命令将输出类似于以下内容的文本:

 
Output

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d nginx NodePort 10.109.228.209 <none> 80:nginx_port/TCP 40m

从上面输出的突出显示的行中,您可以检索 Nginx 正在运行的端口。Kubernetes 将分配一个大于30000自动的随机端口,同时确保该端口尚未被其他服务绑定。

要测试一切是否正常,请访问或通过本地计算机上的浏览器。你会看到 Nginx 熟悉的欢迎页面。http://worker_1_ip:nginx_porthttp://worker_2_ip:nginx_port

如果您想删除 Nginx 应用程序,请先nginx从控制平面节点中删除该服务:

 
 
  1. kubectl delete service nginx
复制

运行以下命令以确保服务已被删除:

 
 
  1. kubectl get services
复制

您将看到以下输出:

 
Output

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d

然后删除部署:

 
 
  1. kubectl delete deployment nginx
复制

运行以下命令以确认这是否有效:

 
 
  1. kubectl get deployments
复制
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值