如何在 Ubuntu 20.04 上使用 Kubeadm 创建 Kubernetes 集群

介绍

Kubernetes是一个集装箱管制系统,以规模管理集装箱. 最初由谷歌开发,基于其在生产中运行集装箱的经验,Kubernetes是开源的,并积极由世界各地的社区开发。

<$>[注] 注: 本教程使用了 Kubernetes 的版本 1.22,这是本文发布时官方支持的版本。 有关最新版本的最新信息,请参阅 当前发布的注释在官方 Kubernetes 文档中。

[Kubeadm] (https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/) 将Kubernetes组件的安装和配置自动化,如API服务器,Controller管理器,和Kube DNS等. 然而,它并不创建用户或处理操作系统级依赖及其配置的安装. 对于这些初步任务,可以使用AnsibleSaltStack等配置管理工具. 使用这些工具使创建额外的集群或重新创建现有的集群变得简单得多,更不容易出错.

在本指南中,您将使用 Ansible 和 Kubeadm 从头开始设置一个 Kubernetes 集群,然后部署一个集装箱化的 Nginx 应用程序。

目标

您的集群将包括以下物理资源:

*一个 控制机节点

控制平面节点(Kubernetes 中的 node 指的是服务器)负责管理集群的状态。 它运行在 Etcd,该节点将集群数据存储在计划工作负载到工人节点的组件之间。

*两个工人节点

工人节点是您的 workloads (即容器化应用程序和服务) 将运行的服务器. 工人将继续运行您的工作负载,一旦他们被分配给它,即使在计划完成后,控制平面下降。

完成本指南后,您将有一个集群准备运行容器化应用程序,只要集群中的服务器有足够的 CPU 和 RAM 资源来消耗您的应用程序. 几乎任何传统的 Unix 应用程序,包括 Web 应用程序,数据库,戴蒙和命令行工具,都可以集群化并在集群上运行。

一旦集群已设置,您将部署 Web 服务器 Nginx以确保它正确运行工作负载。

前提条件

注意:如果您没有进入这些服务器中的每个服务器至少一次之前遵循本教程,您可能会被要求在不方便的时间接受他们的主机指纹。你应该现在这样做,或者作为替代方法,你可以(https://docs.ansible.com/ansible/latest/user_guide/connection_details.html# managing-host-key-checking)。

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

在本节中,您将在本地机器上创建一个目录,该目录将作为您的工作空间。您将本地配置 Ansible,以便它可以与您的远程服务器进行通信和执行命令。

你的三個伺服器中,其中一個將是控制平面, IP 顯示為「control_plane_ip」 其他兩個伺服器將是工人,將有「worker_1_ip」和「worker_2_ip」的 IP。

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

1[environment local]
2mkdir ~/kube-cluster
3cd ~/kube-cluster

此目录将是您在本教程的剩余时间工作空间,并将包含您的所有Ansible播放簿,它也将是您将运行所有本地命令的目录。

使用nano或您最喜欢的文本编辑器创建名为~/cube-cluster/hosts的文件:

1[environment local]
2nano ~/kube-cluster/hosts

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

 1[environment local]
 2[label ~/kube-cluster/hosts]
 3[control_plane]
 4control1 ansible_host=control_plane_ip ansible_user=root 
 5
 6[workers]
 7worker1 ansible_host=worker_1_ip ansible_user=root
 8worker2 ansible_host=worker_2_ip ansible_user=root
 9
10[all:vars]
11ansible_python_interpreter=/usr/bin/python3

您可能还记得,在 Ansible 中, inventory files用于指定服务器信息,如 IP 地址,远程用户和服务器组合,以作为执行命令的单个单位进行目标。

control plane 组中,有一个名为)并指定了Ansible应该作为 root 用户运行远程命令。

同样,在工作者组中,有两个工作者服务器的条目()也指定了ansible_user作为根。

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

添加文本后保存并关闭文件. 如果您使用nano,请按Ctrl+X,然后在提示时按YEnter

设置服务器库存组之后,让我们继续安装操作系统级别依赖并创建配置设置。

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

在此区域中, 您将创建一个拥有所有服务器的 sudo 权限的非 root 用户, 以便您能够作为非特权用户手动进入 SSH 。 例如,如果您想看到带有 上/ 上 命令的系统信息, 查看运行中的容器列表, 或更改由 root 拥有的配置文件, 这一点就可能有用 。 这些操作通常在集群维护期间进行,使用非终端用户执行这些任务可将修改或删除重要文件或无意进行其他危险操作的风险降至最低.

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

1[environment local]
2nano ~/kube-cluster/initial.yml

接下来,将下列 play 添加到文件中,以在所有服务器上创建具有 sudo 特权的非 root 用户。

 1[environment local]
 2[label ~/kube-cluster/initial.yml]
 3---
 4- hosts: all
 5  become: yes
 6  tasks:
 7    - name: create the 'ubuntu' user
 8      user: name=ubuntu append=yes state=present createhome=yes shell=/bin/bash
 9
10    - name: allow 'ubuntu' to have passwordless sudo
11      lineinfile:
12        dest: /etc/sudoers
13        line: 'ubuntu ALL=(ALL) NOPASSWD: ALL'
14        validate: 'visudo -cf %s'
15
16    - name: set up authorized keys for the ubuntu user
17      authorized_key: user=ubuntu key="{{item}}"
18      with_file:
19        - ~/.ssh/id_rsa.pub

以下是这本剧本所做的分解:

  • 创建非根用户)添加到远程ubuntu用户的授权密钥列表。

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

接下来,本地运行 Playbook:

1[environment local]
2ansible-playbook -i hosts ~/kube-cluster/initial.yml

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

 1[environment local]
 2[secondary_label Output]
 3PLAY [all] ****
 4
 5TASK [Gathering Facts] ****
 6ok: [control1]
 7ok: [worker1]
 8ok: [worker2]
 9
10TASK [create the 'ubuntu' user] ****
11changed: [control1]
12changed: [worker1]
13changed: [worker2]
14
15TASK [allow 'ubuntu' user to have passwordless sudo] ****
16changed: [control1]
17changed: [worker1]
18changed: [worker2]
19
20TASK [set up authorized keys for the ubuntu user] ****
21changed: [worker1] => (item=ssh-rsa AAAAB3...)
22changed: [worker2] => (item=ssh-rsa AAAAB3...)
23changed: [control1] => (item=ssh-rsa AAAAB3...)
24
25PLAY RECAP ****
26control1                     : ok=4 changed=3 unreachable=0 failed=0   
27worker1                    : ok=4 changed=3 unreachable=0 failed=0   
28worker2                    : ok=4 changed=3 unreachable=0 failed=0

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

第3步:安装Kubernetetes依赖

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

  • Docker - 容器运行时间. 它是运行您的容器的组件. Kubernetes支持其他运行时间,但Docker仍然是一个流行的和简单的选择. * kubeadm - 一个CLI工具,将以标准的方式安装和配置集群的各种组件。 * kubelet - 一个系统服务 / 程序,运行在所有节点和处理节点级操作。 * kubectl - 用于通过其API服务器发出命令到集群的CLI工具。

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

1[environment local]
2nano ~/kube-cluster/kube-dependencies.yml

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

 1[environment local]
 2[label ~/kube-cluster/kube-dependencies.yml]
 3---
 4- hosts: all
 5  become: yes
 6  tasks:
 7   - name: create Docker config directory
 8     file: path=/etc/docker state=directory
 9
10   - name: changing Docker to systemd driver
11     copy:
12      dest: "/etc/docker/daemon.json"
13      content: |
14        {
15        "exec-opts": ["native.cgroupdriver=systemd"]
16        }        
17
18   - name: install Docker
19     apt:
20       name: docker.io
21       state: present
22       update_cache: true
23
24   - name: install APT Transport HTTPS
25     apt:
26       name: apt-transport-https
27       state: present
28
29   - name: add Kubernetes apt-key
30     apt_key:
31       url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
32       state: present
33
34   - name: add Kubernetes' APT repository
35     apt_repository:
36      repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
37      state: present
38      filename: 'kubernetes'
39
40   - name: install kubelet
41     apt:
42       name: kubelet=1.22.4-00
43       state: present
44       update_cache: true
45
46   - name: install kubeadm
47     apt:
48       name: kubeadm=1.22.4-00
49       state: present
50
51- hosts: control_plane
52  become: yes
53  tasks:
54   - name: install kubectl
55     apt:
56       name: kubectl=1.22.4-00
57       state: present
58       force: yes

剧本中的第一场戏做得如下:

  • 安装 Docker,容器运行时间,并配置兼容性设置。 * 安装「apt-transport-https」,允许您将外部 HTTPS 源添加到 APT 源列表中。 * 添加 Kubernetes APT 存储库的 apt-key 以进行密钥验证。 * 将 Kubernetes APT 存储库添加到远程服务器的 APT 源列表中。

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

<美元 > [注] 注: 虽然Kubernetes文档建议您使用最新稳定的Kubernetes在您环境中发布,但此教程使用特定版本. 这将确保您能够成功跟随步骤, 因为Kubernetes会迅速变化, 而最新版本可能无法使用此教程 。 虽然"xenial"是Ubuntu 16.04的取名,而这个教程是针对Ubuntu 20.04的,但Kubernetes默认仍指Ubuntu 16.04包源,在此情况下,它们于20.04被支持. < $ > (美元)

保存并关闭文件,当你完成。

接下来,使用以下命令本地运行播放簿:

1[environment local]
2ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml

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

 1[environment local]
 2[secondary_label Output]
 3PLAY [all] ****
 4
 5TASK [Gathering Facts] ****
 6ok: [worker1]
 7ok: [worker2]
 8ok: [control1]
 9
10TASK [create Docker config directory] ****
11changed: [control1]
12changed: [worker1]
13changed: [worker2]
14
15TASK [changing Docker to systemd driver] ****
16changed: [control1]
17changed: [worker1]
18changed: [worker2]
19
20TASK [install Docker] ****
21changed: [control1]
22changed: [worker1]
23changed: [worker2]
24
25TASK [install APT Transport HTTPS] *****
26ok: [control1]
27ok: [worker1]
28changed: [worker2]
29
30TASK [add Kubernetes apt-key] *****
31changed: [control1]
32changed: [worker1]
33changed: [worker2]
34
35TASK [add Kubernetes' APT repository] *****
36changed: [control1]
37changed: [worker1]
38changed: [worker2]
39
40TASK [install kubelet] *****
41changed: [control1]
42changed: [worker1]
43changed: [worker2]
44
45TASK [install kubeadm] *****
46changed: [control1]
47changed: [worker1]
48changed: [worker2]
49
50PLAY [control1] *****
51
52TASK [Gathering Facts] *****
53ok: [control1]
54
55TASK [install kubectl] ******
56changed: [control1]
57
58PLAY RECAP ****
59control1                     : ok=11 changed=9 unreachable=0 failed=0   
60worker1                    : ok=9 changed=8 unreachable=0 failed=0  
61worker2                    : ok=9 changed=8 unreachable=0 failed=0

在运行本游戏本后,将在所有远程服务器上安装Docker、 " kubeadm " 和 " kubelet " 。 kubectl'不是一个必要的组成部分,仅是执行集群命令所需的。 只有在控制平面节点安装才有意义,因为您只能从控制平面上运行kubectl指令。 但请注意,kubectl'命令可以从任何工人节点或任何可以安装和配置以指向集群的机器上运行.

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

步骤4 - 设置控制飞机节点

然而,在创建任何播放书之前,值得涵盖一些概念,如 Pods 和 _Pod 网络插件,因为您的集群将包括两者。

Pod 是运行一个或多个集装箱的原子单位,这些集装箱共享文件卷和网络接口等共同的资源。Pod 是 Kubernetes 编程的基本单元:一个集装箱中的所有集装箱都保证在一个节点上运行。

每个pod都有自己的IP地址,一个节点上的pod应该能够使用pod的IP访问另一个节点上的pod。单个节点上的容器可以通过本地接口轻松通信。

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

在本地计算机上创建一个名为 'control-plane.yml' 的 Ansible 播放簿:

1[environment local]
2nano ~/kube-cluster/control-plane.yml

将下列播放添加到文件中,以初始化集群并安装 Flannel:

 1[environment local]
 2[label ~/kube-cluster/control-plane.yml]
 3---
 4- hosts: control_plane
 5  become: yes
 6  tasks:
 7    - name: initialize the cluster
 8      shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
 9      args:
10        chdir: $HOME
11        creates: cluster_initialized.txt
12
13    - name: create .kube directory
14      become: yes
15      become_user: ubuntu
16      file:
17        path: $HOME/.kube
18        state: directory
19        mode: 0755
20
21    - name: copy admin.conf to user's kube config
22      copy:
23        src: /etc/kubernetes/admin.conf
24        dest: /home/ubuntu/.kube/config
25        remote_src: yes
26        owner: ubuntu
27
28    - name: install Pod network
29      become: yes
30      become_user: ubuntu
31      shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml >> pod_network_setup.txt
32      args:
33        chdir: $HOME
34        creates: pod_network_setup.txt

以下是这场戏的分裂:

  • 联合国 第一个任务通过运行kubeadm init来初始化集群。 通过`-pod-network-cidr=10.244.0.0/16'这一论点,可以确定将分配给IP的私人子网。 Flannel默认使用上面的子网;我们告诉"kubeadm"使用同一个子网.
  • 联合国 第二项任务是在/home/ubuntu'建立一个.kube'目录。 此目录将持有配置信息, 如连接集群所需的管理员密钥文件, 以及集群的 API 地址 。
  • 联合国 第三项任务复制了/etc/kubernetes/admin.conf'。 从 kubeadm init生成到您的非根用户主目录的文件。 这将允许您使用 kubectl` 访问新创建的集群 。
  • 联合国 最后一项任务为安装 " Flannel " 。 kubetl适用-f 描述符。 是命令kubectl创建描述符文件所描述的对象的语法。[yml|json]。 kube-flannel.yml'文件载有在集群中设置`Flannel'所需对象的说明。 .

保存并关闭文件,当你完成。

使用以下命令本地运行播放簿:

1[environment local]
2ansible-playbook -i hosts ~/kube-cluster/control-plane.yml

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

 1[environment local]
 2[secondary_label Output]
 3
 4PLAY [control1] ****
 5
 6TASK [Gathering Facts] ****
 7ok: [control1]
 8
 9TASK [initialize the cluster] ****
10changed: [control1]
11
12TASK [create .kube directory] ****
13changed: [control1]
14
15TASK [copy admin.conf to user's kube config] *****
16changed: [control1]
17
18TASK [install Pod network] *****
19changed: [control1]
20
21PLAY RECAP ****
22control1                     : ok=5 changed=4 unreachable=0 failed=0

要检查控制平面节点的状态,用以下命令 SSH 输入它:

1[environment local]
2ssh ubuntu@control_plane_ip

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

1kubectl get nodes

您现在将看到以下结果:

1[secondary_label Output]
2NAME STATUS ROLES AGE VERSION
3control1 Ready control-plane,master 51s v1.22.4

<$>[注] 注: 自Ubuntu 20.04开始,kubernetes正在更新他们的旧术语。我们在整个教程中称之为控制飞机的节点被称为节点,有时你会看到kubernetes同时分配两个角色的兼容性原因。

输出表示控制平面节点已完成所有初始化任务,并处于准备状态,可以开始接受工人节点并执行发送到API服务器的任务。

步骤5 - 设置工人节点

将工人添加到群集中,需要在每个群集中执行一个单一的命令,该命令包括必要的群集信息,例如控制层的API服务器的IP地址和端口,以及一个安全的代币。

返回工作区,创建一个名为workers.yml的播放簿:

1[environment local]
2nano ~/kube-cluster/workers.yml

将下列文本添加到文件中,以将工人添加到集群中:

 1[environment local]
 2[label ~/kube-cluster/workers.yml]
 3---
 4- hosts: control_plane
 5  become: yes
 6  gather_facts: false
 7  tasks:
 8    - name: get join command
 9      shell: kubeadm token create --print-join-command
10      register: join_command_raw
11
12    - name: set join command
13      set_fact:
14        join_command: "{{ join_command_raw.stdout_lines[0] }}"
15
16- hosts: workers
17  become: yes
18  tasks:
19    - name: join cluster
20      shell: "{{ hostvars['control1'].join_command }} >> node_joined.txt"
21      args:
22        chdir: $HOME
23        creates: node_joined.txt

以下是《剧本》所做的:

  • 联合国 第一种游戏获得需要运行在工人节点上的联合命令. 此命令将采用以下格式 : 'kubeadm join -- token < control-plane-ip>: < control-plane-port> --发现-token-ca-cert-hash sha256:`. 一旦它得到带有适当的 token** 和** hash** 值的实际命令,任务就将其设定为事实,以便下一场游戏能够访问该信息.
  • 联合国 第二出戏有一个单一的任务,在所有工人节点上运行联合指令. 在完成这项任务后,两个工人节点将成为集群的一部分. .

保存并关闭文件,当你完成。

按本地运行播放簿,使用以下命令:

1[environment local]
2ansible-playbook -i hosts ~/kube-cluster/workers.yml

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

 1[environment local]
 2[secondary_label Output]
 3PLAY [control1] ****
 4
 5TASK [get join command] ****
 6changed: [control1]
 7
 8TASK [set join command] *****
 9ok: [control1]
10
11PLAY [workers] *****
12
13TASK [Gathering Facts] *****
14ok: [worker1]
15ok: [worker2]
16
17TASK [join cluster] *****
18changed: [worker1]
19changed: [worker2]
20
21PLAY RECAP *****
22control1                     : ok=2 changed=1 unreachable=0 failed=0   
23worker1                    : ok=2 changed=1 unreachable=0 failed=0  
24worker2                    : ok=2 changed=1 unreachable=0 failed=0

随着工人节点的添加,您的集群现在已经完全设置和功能,工人准备运行工作负载。

步骤6 - 验证集群

集群在设置过程中有时会失败,因为一个节点处于停机状态或控制平面和工人之间的网络连接不正常工作,让我们检查集群并确保节点正常工作。

您将需要从控制平面节点检查集群的当前状态,以确保节点准备好了. 如果您从控制平面节点中脱离了连接,您可以用以下命令SSH返回它:

1[environment local]
2ssh ubuntu@control_plane_ip

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

1kubectl get nodes

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

1[secondary_label Output]
2NAME STATUS ROLES AGE VERSION
3control1 Ready control-plane,master 3m21s v1.22.0
4worker1 Ready    <none>                 32s v1.22.0
5worker2 Ready    <none>                 32s v1.22.0

如果您的所有节点都具有状态准备值,则意味着它们是集群的一部分,并准备运行工作负载。

但是,如果一些节点有NotReady作为STATUS,这可能意味着工人节点尚未完成设置。在重新运行kubectl get nodes并检查新输出之前,请等待大约五到十分钟。

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

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

现在您可以将任何集装箱应用程序部署到您的集群中。为了让事情熟悉,让我们使用 DeploymentsServices 部署 Nginx 来探索该应用程序如何部署到集群中。

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

1kubectl create deployment nginx --image=nginx

部署是一种类型的 Kubernetes 对象,可确保根据定义的模板始终有特定数量的 pods 运行,即使在集群的生命周期中,pod 会崩溃。

接下来,运行以下命令来创建一个名为nginx的服务,它将通过一个 NodePort 来公开曝光应用程序。

1kubectl expose deploy nginx --port 80 --target-port 80 --type NodePort

服务是另一种类型的Kubernetes对象,它们向内部和外部客户端暴露集群内部服务,它们还能够对多个Pod进行负载平衡请求,并且是Kubernetes的组成部分,经常与其他组件相互作用。

运行以下命令:

1kubectl get services

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

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

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

要测试一切是否正常工作,请通过本地机器的浏览器访问http://worker_1_ip:nginx_port或http://worker_2_ip:nginx_port。您将看到 Nginx 熟悉的欢迎页面。

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

1kubectl delete service nginx

执行以下操作以确保该服务已被删除:

1kubectl get services

您将看到以下结果:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)        AGE
3kubernetes ClusterIP 10.96.0.1        <none>                443/TCP 1d

然后删除部署:

1kubectl delete deployment nginx

运行以下操作来确认这是有效的:

1kubectl get deployments
1[secondary_label Output]
2No resources found.

结论

在本指南中,您已成功在Ubuntu 20.04上设置了一个Kubernetes集群,使用Kubeadm和Ansible进行自动化。

如果您想知道如何使用集群现在它已经设置了,一个好的下一步将是方便地部署自己的应用程序和服务到集群中。

您可以查看的其他重要概念是 Volumes, IngressesSecrets,所有这些都是在部署生产应用程序时非常有用的。

Kubernetes 有很多功能和功能可供提供。 Kubernetes 官方文档是了解概念,找到特定任务的指南,并搜索各种对象的API引用最好的地方。您还可以查看我们的 Kubernetes for Full-Stack Developers 课程

Published At
Categories with 技术
comments powered by Disqus