如何在 Debian 9 上使用 Kubeadm 创建 Kubernetes 集群

_ 作者选择了 免费和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

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

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

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

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

如果您正在寻找一个管理的Kubernetes托管服务,请查看我们的简单的,用于增长的管理的Kubernetes服务(https://www.digitalocean.com/products/kubernetes)。

目标

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

  • 一个主节点* 主节点(Kubernetes中a_node_指服务器)负责管理集群状态. 它运行[Etcd] (https://github.com/coreos/etcd),将集群数据存储在将工作量排入工人节点的组件之间. *两个工人节点 工人节点是您所运行的 workloads(即容器化的应用程序和服务)的服务器. 一个工人会继续承担你的工作量 一旦他们被分配到它, 即使主人下去,一旦时间安排完成。 一个集群的能力可以通过增加工人来提高. .

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

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

前提条件

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

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

在你的三個伺服器中,一個將是主機, IP 顯示為「master_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[masters]
 4master ansible_host=master_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 地址,远程用户和服务器组合,以作为执行命令的单个单位进行目标。

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

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

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

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

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

第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- hosts: all
 4  become: yes
 5  tasks:
 6    - name: create the 'sammy' user
 7      user: name=sammy append=yes state=present createhome=yes shell=/bin/bash
 8
 9    - name: allow 'sammy' to have passwordless sudo
10      lineinfile:
11        dest: /etc/sudoers
12        line: 'sammy ALL=(ALL) NOPASSWD: ALL'
13        validate: 'visudo -cf %s'
14
15    - name: set up authorized keys for the sammy user
16      authorized_key: user=sammy key="{{item}}"
17      with_file:
18        - ~/.ssh/id_rsa.pub

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

  • 创建非根用户「sammy」。 * 配置「sudoers」文件以允许「sammy」用户在没有密码提示的情况下运行「sudo」命令。 * 将本地机器的公共密钥(通常是「~/.ssh/id_rsa.pub」)添加到远程「sammy」用户的授权密钥列表。

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

接下来,通过本地运行运行播放簿:

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: [master]
 7ok: [worker1]
 8ok: [worker2]
 9
10TASK [create the 'sammy' user] ****
11changed: [master]
12changed: [worker1]
13changed: [worker2]
14
15TASK [allow 'sammy' user to have passwordless sudo] ****
16changed: [master]
17changed: [worker1]
18changed: [worker2]
19
20TASK [set up authorized keys for the sammy user] ****
21changed: [worker1] => (item=ssh-rsa AAAAB3...)
22changed: [worker2] => (item=ssh-rsa AAAAB3...)
23changed: [master] => (item=ssh-rsa AAAAB3...)
24
25PLAY RECAP ****
26master                     : ok=5 changed=4 unreachable=0 failed=0   
27worker1                    : ok=5 changed=4 unreachable=0 failed=0   
28worker2                    : ok=5 changed=4 unreachable=0 failed=0

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

第3步:安装Kubernetes依赖

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

  • Docker - 一个容器运行时间. 它是运行您的容器的组件. 支持其他运行时间,如 rkt正在 Kubernetes 积极开发中。 * 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- hosts: all
 4  become: yes
 5  tasks:
 6   - name: install remote apt deps
 7     apt:
 8       name: "{{ item }}"
 9       state: present
10     with_items:
11       - apt-transport-https
12       - ca-certificates
13       - gnupg2
14       - software-properties-common
15
16   - name: add Docker apt-key
17     apt_key:
18       url: https://download.docker.com/linux/debian/gpg
19       state: present
20
21   - name: add Docker's APT repository
22     apt_repository:
23      repo: deb https://download.docker.com/linux/debian stretch stable
24      state: present
25      filename: 'docker'
26
27   - name: install Docker
28     apt:
29       name: docker-ce
30       state: present
31       update_cache: true
32
33   - name: add Kubernetes apt-key
34     apt_key:
35       url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
36       state: present
37
38   - name: add Kubernetes' APT repository
39     apt_repository:
40      repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
41      state: present
42      filename: 'kubernetes'
43
44   - name: install kubelet
45     apt:
46       name: kubelet=1.14.0-00
47       state: present
48       update_cache: true
49
50   - name: install kubeadm
51     apt:
52       name: kubeadm=1.14.0-00
53       state: present
54
55- hosts: master
56  become: yes
57  tasks:
58   - name: install kubectl
59     apt:
60       name: kubectl=1.14.0-00
61       state: present
62       force: yes

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

  • 添加用于从远程存储库中添加、验证和安装包的依赖性 * 添加 Docker APT 存储库的 apt-key 用于密钥验证 * 安装 Docker,容器运行时间 * 添加 Kubernetes APT 存储库的 apt-key 用于密钥验证 * 添加 Kubernetes APT 存储库到远程服务器的 APT 源列表 * 安装 kubelet 和 `kubeadm'。

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

注意:虽然Kubernetes文档建议您为您的环境使用最新稳定版本的Kubernetes,但本教程使用的是特定版本。

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

接下来,通过本地运行运行播放簿:

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: [master]
 9
10TASK [install Docker] ****
11changed: [master]
12changed: [worker1]
13changed: [worker2]
14
15TASK [install APT Transport HTTPS] *****
16ok: [master]
17ok: [worker1]
18changed: [worker2]
19
20TASK [add Kubernetes apt-key] *****
21changed: [master]
22changed: [worker1]
23changed: [worker2]
24
25TASK [add Kubernetes' APT repository] *****
26changed: [master]
27changed: [worker1]
28changed: [worker2]
29
30TASK [install kubelet] *****
31changed: [master]
32changed: [worker1]
33changed: [worker2]
34
35TASK [install kubeadm] *****
36changed: [master]
37changed: [worker1]
38changed: [worker2]
39
40PLAY [master] *****
41
42TASK [Gathering Facts] *****
43ok: [master]
44
45TASK [install kubectl] ******
46ok: [master]
47
48PLAY RECAP ****
49master                     : ok=9 changed=5 unreachable=0 failed=0   
50worker1                    : ok=7 changed=5 unreachable=0 failed=0  
51worker2                    : ok=7 changed=5 unreachable=0 failed=0

執行後,Docker、kubeadm 和 kubelet 會安裝在所有遠端伺服器上。「kubectl」並不是必需的組件,只需要執行集群命令。在這種情況下,只在主節點上安裝它是有意義的,因為你只會從主節點執行「kubectl」命令。 但是,請注意,「kubectl」命令可以從任何工作節點或任何可以安裝和配置到集群的機器上執行。

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

第4步:设置主节点

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

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

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

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

在本地机器上创建一个名为master.yml的Ansible播放簿:

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

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

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

以下是这场戏的分裂:

  • 联合国 第一个任务通过运行kubeadm init来初始化集群。 通过`-pod-network-cidr=10.244.0.0/16'这一论点,可以确定将分配给IP的私人子网。 Flannel默认使用上面的子网;我们告诉"kubeadm"使用同一个子网.
  • 联合国 第二项任务在/home/Sammy'创建了.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/master.yml

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

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

要检查主节点的状态,用以下命令 SSH 进入它:

1[environment local]
2ssh sammy@master_ip

一旦进入主节点,执行:

1kubectl get nodes

您现在将看到以下结果:

1[secondary_label Output]
2NAME STATUS ROLES AGE VERSION
3master Ready master 1d v1.14.0

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

步骤5 - 设置工人节点

将工人添加到群集中涉及在每个群集上执行一个单一的命令. 此命令包含必要的群集信息,如主 API Server 的 IP 地址和端口,以及一个安全的代币。

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

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

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

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

以下是《剧本》所做的:

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

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

通过本地运行运行播放簿:

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

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

 1[environment local]
 2[secondary_label Output]
 3PLAY [master] ****
 4
 5TASK [get join command] ****
 6changed: [master]
 7
 8TASK [set join command] *****
 9ok: [master]
10
11PLAY [workers] *****
12
13TASK [Gathering Facts] *****
14ok: [worker1]
15ok: [worker2]
16
17TASK [join cluster] *****
18changed: [worker1]
19changed: [worker2]
20
21PLAY RECAP *****
22master                     : 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 sammy@master_ip

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

1kubectl get nodes

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

1[secondary_label Output]
2NAME STATUS ROLES AGE VERSION
3master Ready master 1d v1.14.0
4worker1 Ready     <none>    1d v1.14.0
5worker2 Ready     <none>    1d v1.14.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.

结论

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

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

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

Kubernetes 有很多功能和功能可供提供。 Kubernetes 官方文档是了解概念,找到特定任务的指南和搜索各种对象的 API 参考的最佳场所。

Published At
Categories with 技术
comments powered by Disqus