一.系统环境

本文主要基于Kubernetes1.22.2和Linux操作系统Ubuntu 18.04。

服务器版本 docker软件版本 Kubernetes(k8s)集群版本 CPU架构
Ubuntu 18.04.5 LTS Docker version 20.10.14 v1.22.2 x86_64

Kubernetes集群架构:k8scludes1作为master节点,k8scludes2,k8scludes3作为worker节点。

服务器 操作系统版本 CPU架构 进程 功能描述
k8scludes1/192.168.110.128 Ubuntu 18.04.5 LTS x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
k8scludes2/192.168.110.129 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
k8scludes3/192.168.110.130 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

二.前言

下图描述了软件部署方式的变迁:传统部署时代虚拟化部署时代容器部署时代

传统部署时代

早期,各个组织是在物理服务器上运行应用程序。 由于无法限制在物理服务器中运行的应用程序资源使用,因此会导致资源分配问题。 例如,如果在同一台物理服务器上运行多个应用程序, 则可能会出现一个应用程序占用大部分资源的情况,而导致其他应用程序的性能下降。 一种解决方案是将每个应用程序都运行在不同的物理服务器上, 但是当某个应用程式资源利用率不高时,剩余资源无法被分配给其他应用程式, 而且维护许多物理服务器的成本很高。

虚拟化部署时代

因此,虚拟化技术被引入了。虚拟化技术允许你在单个物理服务器的 CPU 上运行多台虚拟机(VM)。 虚拟化能使应用程序在不同 VM 之间被彼此隔离,且能提供一定程度的安全性, 因为一个应用程序的信息不能被另一应用程序随意访问。

虚拟化技术能够更好地利用物理服务器的资源,并且因为可轻松地添加或更新应用程序, 而因此可以具有更高的可扩缩性,以及降低硬件成本等等的好处。 通过虚拟化,你可以将一组物理资源呈现为可丢弃的虚拟机集群。

每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

容器部署时代

容器类似于 VM,但是更宽松的隔离特性,使容器之间可以共享操作系统(OS)。 因此,容器比起 VM 被认为是更轻量级的。且与 VM 类似,每个容器都具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。

容器因具有许多优势而变得流行起来,例如:

  • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
  • 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
  • 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
  • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  • 资源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度。

在这篇博客中,我们将详细介绍如何在Ubuntu 18.04上安装和部署Kubernetes 1.22.2集群。我们将使用kubeadm工具,这是Kubernetes官方推荐的用于快速部署Kubernetes集群的工具。

如果您的平台在Centos系统上,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Centos7 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/16686769.html。

如果您对Ubuntu系统不熟悉,Ubuntu系统的详细操作,请查看博客《centos系统和Ubuntu系统命令区别以及常见操作》。

三.Kubernetes

3.1 概述

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。

Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。 Kubernetes 建立在 Google 大规模运行生产工作负载十几年经验的基础上, 结合了社区中最优秀的想法和实践。

Kubernetes 为你提供的功能如下:

  1. 服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址来曝露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
  2. 存储编排:Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
  3. 自动部署和回滚:你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
  4. 自动完成装箱计算:你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。
  5. 自我修复:Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。
  6. 密钥与配置管理:Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

3.2 Kubernetes 组件

Kubernetes 集群架构如下:

Kubernetes 集群组件如下:

Kubernetes有两种节点类型:master节点,worker节点。master节点又称为控制平面(Control Plane)。控制平面有很多组件,控制平面组件会为集群做出全局决策,比如资源的调度。 以及检测和响应集群事件,例如当不满足部署的 replicas 字段时, 要启动新的 pod)。

控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。

3.2.1 控制平面组件

控制平面组件如下

  1. kube-apiserver:API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。

    Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平扩缩,也就是说,它可通过部署多个实例来进行扩缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。
  2. etcd:etcd 是兼顾一致性与高可用性的键值对数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。你的 Kubernetes 集群的 etcd 数据库通常需要有个备份计划。
  3. kube-scheduler:kube-scheduler 是控制平面的组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰及最后时限。
  4. kube-controller-manager:kube-controller-manager 是控制平面的组件, 负责运行控制器进程。从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。

    这些控制器包括:

    节点控制器(Node Controller):负责在节点出现故障时进行通知和响应

    任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成

    端点控制器(Endpoints Controller):填充端点(Endpoints)对象(即加入 Service 与 Pod)

    服务帐户和令牌控制器(Service Account & Token Controllers):为新的命名空间创建默认帐户和 API 访问令牌
  5. cloud-controller-manager:一个 Kubernetes 控制平面组件, 嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。cloud-controller-manager 仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。

    与 kube-controller-manager 类似,cloud-controller-manager 将若干逻辑上独立的控制回路组合到同一个可执行文件中, 供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。

    下面的控制器都包含对云平台驱动的依赖:

    节点控制器(Node Controller):用于在节点终止响应后检查云提供商以确定节点是否已被删除

    路由控制器(Route Controller):用于在底层云基础架构中设置路由

    服务控制器(Service Controller):用于创建、更新和删除云提供商负载均衡器

3.2.2 Node组件

节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。

node组件如下

  1. kubelet:kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
  2. kube-proxy:kube-proxy 是集群中每个节点(node)所上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。

四.配置节点的基本环境

先配置节点的基本环境,3个节点都要同时设置,在此以k8scludes1作为示例。

查看Ubuntu系统版本。

root@localhost:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.5 LTS
Release: 18.04
Codename: bionic

首先设置主机名。

root@localhost:~# vim /etc/hostname 

root@localhost:~# cat /etc/hostname
k8scludes1

配置节点静态IP地址(可选)。

root@localhost:~# vim /etc/netplan/01-netcfg.yaml

root@localhost:~# cat /etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
ens32:
dhcp4: no
addresses: [192.168.110.128/24]
gateway4: 192.168.110.2
nameservers:
addresses: [192.168.110.2,114.114.114.114]

使配置生效。

root@localhost:~# netplan apply

测试机器是否可以访问网络。

root@localhost:~# ping www.baidu.com
PING www.baidu.com (14.215.177.39) 56(84) bytes of data.
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=1 ttl=128 time=48.0 ms
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=2 ttl=128 time=52.9 ms
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=3 ttl=128 time=39.8 ms
^C
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2009ms
rtt min/avg/max/mdev = 39.843/46.940/52.968/5.417 ms

配置IP地址和主机名映射。

root@localhost:~# ifconfig
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.110.128 netmask 255.255.255.0 broadcast 192.168.110.255
inet6 fe80::20c:29ff:fe92:3462 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:92:34:62 txqueuelen 1000 (Ethernet)
RX packets 3600 bytes 909889 (909.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2327 bytes 225443 (225.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 54 bytes 6421 (6.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 54 bytes 6421 (6.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 root@localhost:~# vim /etc/hosts root@localhost:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 tom
192.168.110.128 k8scludes1
192.168.110.129 k8scludes2
192.168.110.130 k8scludes3 # The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

重启机器之后,主机名变为k8scludes1,另外两台机器也进行相同操作。

k8scludes1可以ping通其他两个节点则成功。

root@k8scludes1:~# ping k8scludes1
PING k8scludes1 (192.168.110.128) 56(84) bytes of data.
64 bytes from k8scludes1 (192.168.110.128): icmp_seq=1 ttl=64 time=0.014 ms
64 bytes from k8scludes1 (192.168.110.128): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from k8scludes1 (192.168.110.128): icmp_seq=3 ttl=64 time=0.058 ms
^C
--- k8scludes1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2048ms
rtt min/avg/max/mdev = 0.014/0.037/0.058/0.018 ms root@k8scludes1:~# ping k8scludes2
PING k8scludes2 (192.168.110.129) 56(84) bytes of data.
64 bytes from k8scludes2 (192.168.110.129): icmp_seq=1 ttl=64 time=0.465 ms
64 bytes from k8scludes2 (192.168.110.129): icmp_seq=2 ttl=64 time=2.98 ms
64 bytes from k8scludes2 (192.168.110.129): icmp_seq=3 ttl=64 time=2.34 ms
^C
--- k8scludes2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2048ms
rtt min/avg/max/mdev = 0.465/1.932/2.983/1.069 ms root@k8scludes1:~# ping k8scludes3
PING k8scludes3 (192.168.110.130) 56(84) bytes of data.
64 bytes from k8scludes3 (192.168.110.130): icmp_seq=1 ttl=64 time=0.450 ms
64 bytes from k8scludes3 (192.168.110.130): icmp_seq=2 ttl=64 time=3.71 ms
^C
--- k8scludes3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1022ms
rtt min/avg/max/mdev = 0.450/2.083/3.717/1.634 ms

配置Ubuntu软件源,软件源如下,最后三行是k8s源。

root@localhost:~# cat /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable
# deb-src [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable

apt-key.gpg是k8s的deb源公钥,加载k8s的deb源公钥命令为:apt-key add apt-key.gpg,下载并加载k8s的deb源公钥命令为:curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - ; apt-get update,但是谷歌的网址访问不了,我们直接去网上下载apt-key.gpg文件。

#apt-key.gpg文件下载好了
root@localhost:~# ls
apt-key.gpg

加载k8s的deb源公钥。

root@localhost:~# cat apt-key.gpg | apt-key add -
OK

更新软件源。

root@localhost:~# apt-get update
Hit:1 http://mirrors.aliyun.com/ubuntu bionic InRelease
Hit:2 http://mirrors.aliyun.com/ubuntu bionic-security InRelease
Hit:3 http://mirrors.aliyun.com/ubuntu bionic-updates InRelease
Get:4 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial InRelease [9,383 B]
Hit:5 http://mirrors.aliyun.com/ubuntu bionic-proposed InRelease
Hit:6 http://mirrors.aliyun.com/ubuntu bionic-backports InRelease
Hit:7 https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic InRelease
Ign:8 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
Get:8 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages [54.7 kB]
Fetched 54.7 kB in 2s (33.3 kB/s)
Reading package lists... Done

关闭防火墙。

root@k8scludes1:~# ufw disable
Firewall stopped and disabled on system startup

Linux swapoff命令用于关闭系统交换分区(swap area)。

注意:如果不关闭swap,就会在kubeadm初始化Kubernetes的时候报错:“[ERROR Swap]: running with swap on is not supported. Please disable swap”。

root@k8scludes1:~# swapoff -a ;sed -i '/swap/d' /etc/fstab

root@k8scludes1:~# cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/tom--vg-root / ext4 errors=remount-ro 0 1

此时基本环境就配置完毕了。

五.节点安装docker,并进行相关配置

k8s是容器编排工具,需要容器管理工具,所以三个节点同时安装docker,还是以k8scludes1为例。

安装docker。

root@k8scludes1:~# apt-get install docker-ce
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
containerd.io dbus-user-session docker-ce-cli docker-ce-rootless-extras docker-scan-plugin libltdl7 pigz
......
Processing triggers for libc-bin (2.27-3ubuntu1.2) ...

查看docker安装包。

root@k8scludes	1:~# dpkg -l | grep docker
ii docker-ce 5:20.10.14~3-0~ubuntu-bionic amd64 Docker: the open-source application container engine
ii docker-ce-cli 5:20.10.14~3-0~ubuntu-bionic amd64 Docker CLI: the open-source application container engine
ii docker-ce-rootless-extras 5:20.10.14~3-0~ubuntu-bionic amd64 Rootless support for Docker.
ii docker-scan-plugin 0.17.0~ubuntu-bionic amd64 Docker scan cli plugin.

设置docker开机自启动并现在启动docker。

root@k8scludes1:~# systemctl enable docker --now
Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable docker

查看docker状态。

root@k8scludes1:~# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-04-16 21:39:46 CST; 3min 21s ago
Docs: https://docs.docker.com
Main PID: 1822 (dockerd)
Tasks: 9
CGroup: /system.slice/docker.service
└─1822 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

查看docker版本。

root@k8scludes1:~# docker --version
Docker version 20.10.14, build a224086

注意kubernetes V1.22.2版本及其以后,要求容器的cgroup driver 为systemd,但是docker默认的cgroup driver 是cgroupfs,kubernetes 1.21版本及其之前,是不需要修改cgroup driver的。

可以使用docker info | grep -i cgroup查看cgroup driver。

root@k8scludes1:~# docker info | grep -i cgroup
WARNING: No swap limit support
Cgroup Driver: cgroupfs
Cgroup Version: 1

配置docker镜像加速器,并设置docker的cgroup driver 为systemd。

root@k8scludes1:~# cat > /etc/docker/daemon.json <<EOF
> {
> "registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
> "exec-opts": ["native.cgroupdriver=systemd"]
> }
> EOF root@k8scludes1:~# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}

重启docker。

root@k8scludes1:~# systemctl restart docker

root@k8scludes1:~# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-04-16 21:51:29 CST; 8s ago
Docs: https://docs.docker.com
Main PID: 3541 (dockerd)
Tasks: 9
CGroup: /system.slice/docker.service
└─3541 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

这时Cgroup Driver就变为systemd了。

root@k8scludes1:~# docker info | grep -i cgroup
Cgroup Driver: systemd
Cgroup Version: 1
WARNING: No swap limit support

设置iptables不对bridge的数据进行处理,启用IP路由转发功能。

root@k8scludes1:~# cat <<EOF> /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> net.ipv4.ip_forward = 1
> EOF

使配置生效。

root@k8scludes1:~# sysctl -p /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

六.安装kubelet,kubeadm,kubectl

三个节点都安装kubelet,kubeadm,kubectl,以k8scludes1为例:

  • Kubelet 是 kubernetes 工作节点上的一个代理组件,运行在每个节点上
  • Kubeadm 是一个快捷搭建kubernetes(k8s)的安装工具,它提供了 kubeadm init 以及 kubeadm join 这两个命令来快速创建 kubernetes 集群,kubeadm 通过执行必要的操作来启动和运行一个最小可用的集群
  • kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。
root@k8scludes1:~# apt-get -y install kubelet=1.22.2-00 kubeadm=1.22.2-00 kubectl=1.22.2-00
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
conntrack cri-tools kubernetes-cni socat
......
Unpacking kubeadm (1.22.2-00) ...
Setting up conntrack (1:1.4.4+snapshot20161117-6ubuntu2) ...
Setting up kubernetes-cni (0.8.7-00) ...
Setting up cri-tools (1.23.0-00) ...
Setting up socat (1.7.3.2-2ubuntu2) ...
Setting up kubelet (1.22.2-00) ...
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /lib/systemd/system/kubelet.service.
Setting up kubectl (1.22.2-00) ...
Setting up kubeadm (1.22.2-00) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...

设置kubelet开机自启动并现在启动kubelet。

root@k8scludes1:~# systemctl enable kubelet --now

kubelet现在是启动不了的。

root@k8scludes1:~# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
Drop-In: /etc/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: activating (auto-restart) (Result: exit-code) since Sat 2022-04-16 22:07:09 CST; 7s ago
Docs: https://kubernetes.io/docs/home/
Process: 5282 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS (code=exited, status=1/FAILURE)
Main PID: 5282 (code=exited, status=1/FAILURE)

七.kubeadm初始化

更新软件源。

root@k8scludes1:~# apt update

查看可得的kubeadm软件包版本。

root@k8scludes1:~# apt-cache madison kubeadm | grep 1.22
kubeadm | 1.22.8-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.7-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.6-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.5-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.4-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.3-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.2-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.1-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
kubeadm | 1.22.0-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages

kubeadm init:在主节点k8scludes1上初始化 Kubernetes 控制平面节点。

  • --image-repository registry.aliyuncs.com/google_containers:表示使用阿里云镜像仓库,不然有些镜像下载不下来 ;
  • --kubernetes-version=v1.22.2:指定kubernetes的版本;
  • --pod-network-cidr=10.244.0.0/16:指定pod的网段 ;
  • coredns是一个用go语言编写的开源的DNS服务。
root@k8scludes1:~# kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.22.2 --pod-network-cidr=10.244.0.0/16

[init] Using Kubernetes version: v1.22.2
[preflight] Running pre-flight checks
......
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.110.128:6443 --token ju8p1y.8gjm5q00l6u5y1rp \
--discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e

进行kubeadm初始化的时候会去下载各种镜像,可以使用docker images查看。

root@k8scludes1:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.aliyuncs.com/google_containers/kube-apiserver v1.22.2 e64579b7d886 7 months ago 128MB
registry.aliyuncs.com/google_containers/kube-controller-manager v1.22.2 5425bcbd23c5 7 months ago 122MB
registry.aliyuncs.com/google_containers/kube-proxy v1.22.2 873127efbc8a 7 months ago 104MB
registry.aliyuncs.com/google_containers/kube-scheduler v1.22.2 b51ddc1014b0 7 months ago 52.7MB
registry.aliyuncs.com/google_containers/etcd 3.5.0-0 004811815584 10 months ago 295MB
registry.aliyuncs.com/google_containers/coredns v1.8.4 8d147537fb7d 10 months ago 47.6MB
registry.aliyuncs.com/google_containers/pause 3.5 ed210e3e4a5b 13 months ago 683kB

根据提示创建目录和配置文件。

root@k8scludes1:~# mkdir -p $HOME/.kube

root@k8scludes1:~# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

root@k8scludes1:~# sudo chown $(id -u):$(id -g) $HOME/.kube/config

现在已经可以看到master节点了。

root@k8scludes1:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8scludes1 NotReady control-plane,master 178m v1.22.2

八.添加worker节点到k8s集群

接下来把另外的两个worker节点也加入到k8s集群。

kubeadm init的时候输出了如下这句。

kubeadm join 192.168.110.128:6443 --token ju8p1y.8gjm5q00l6u5y1rp \
--discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e

在另外两个worker节点执行这一命令就可以把节点加入到k8s集群里。

如果加入集群的token忘了,可以使用如下的命令获取最新的加入命令token。

root@k8scludes1:~# kubeadm token create --print-join-command
kubeadm join 192.168.110.128:6443 --token 4xk96a.qizykuirhn8ccvcw --discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e

在k8scludes2执行加入集群的token命令。

root@k8scludes2:~# kubeadm join 192.168.110.128:6443 --token 4xk96a.qizykuirhn8ccvcw --discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

可以发现worker节点加入到k8s集群后多了两个镜像。

root@k8scludes2:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.aliyuncs.com/google_containers/pause 3.5 ed210e3e4a5b 13 months ago 683kB
registry.aliyuncs.com/google_containers/kube-proxy v1.22.2 873127efbc8a 7 months ago 104MB

在k8scludes3执行加入集群的token命令。

root@k8scludes3:~# kubeadm join 192.168.110.128:6443 --token 4xk96a.qizykuirhn8ccvcw --discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

可以发现worker节点加入到k8s集群后多了两个镜像。

root@k8scludes3:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.aliyuncs.com/google_containers/kube-proxy v1.22.2 873127efbc8a 7 months ago 104MB
registry.aliyuncs.com/google_containers/pause 3.5 ed210e3e4a5b 13 months ago 683kB

在k8scludes1查看节点状态,可以看到两个worker节点都加入到了k8s集群。

root@k8scludes1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8scludes1 NotReady control-plane,master 3h2m v1.22.2
k8scludes2 NotReady <none> 60s v1.22.2
k8scludes3 NotReady <none> 57s v1.22.2

九.部署CNI网络插件calico

虽然现在kubernetes集群已经有1个master节点,2个worker节点,但是此时三个节点的状态都是NotReady的,原因是没有CNI网络插件,为了节点间的通信,需要安装cni网络插件,常用的cni网络插件有calico和flannel,两者区别为:flannel不支持复杂的网络策略,calico支持网络策略,因为今后还要配置kubernetes网络策略networkpolicy,所以本文选用的cni网络插件为calico!

现在去官网下载calico.yaml文件:

官网:https://projectcalico.docs.tigera.io/about/about-calico

搜索框里直接搜索calico.yaml。

找到下载calico.yaml的命令。

下载calico.yaml文件。

root@k8scludes1:~# curl https://docs.projectcalico.org/manifests/calico.yaml -O
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 212k 100 212k 0 0 8736 0 0:00:24 0:00:24 --:--:-- 18568 root@k8scludes1:~# ls
aa.txt apt-key.gpg calico.yaml set.sh

查看需要下载的calico镜像。

root@k8scludes1:~# grep image calico.yaml
image: docker.io/calico/cni:v3.22.2
image: docker.io/calico/cni:v3.22.2
image: docker.io/calico/pod2daemon-flexvol:v3.22.2
image: docker.io/calico/node:v3.22.2
image: docker.io/calico/kube-controllers:v3.22.2

这四个镜像需要在所有节点都下载,以k8scloudes1为例。

root@k8scludes1:~# docker pull docker.io/calico/cni:v3.22.2

root@k8scludes1:~# docker pull docker.io/calico/pod2daemon-flexvol:v3.22.2

root@k8scludes1:~# docker pull docker.io/calico/node:v3.22.2

root@k8scludes1:~# docker pull docker.io/calico/kube-controllers:v3.22.2

此时三个节点都有calico镜像了。

root@k8scludes1:~# docker images | grep calico
calico/kube-controllers v3.22.2 a1a88662416b 2 days ago 132MB
calico/cni v3.22.2 be7dfc21ba2e 2 days ago 236MB
calico/pod2daemon-flexvol v3.22.2 d6660bf471e1 2 days ago 19.7MB
calico/node v3.22.2 fd1608dbbc19 2 days ago 198MB root@k8scludes2:~# docker images | grep calico
calico/kube-controllers v3.22.2 a1a88662416b 2 days ago 132MB
calico/cni v3.22.2 be7dfc21ba2e 2 days ago 236MB
calico/pod2daemon-flexvol v3.22.2 d6660bf471e1 2 days ago 19.7MB
calico/node v3.22.2 fd1608dbbc19 2 days ago 198MB root@k8scludes3:~# docker images | grep calico
calico/kube-controllers v3.22.2 a1a88662416b 2 days ago 132MB
calico/cni v3.22.2 be7dfc21ba2e 2 days ago 236MB
calico/pod2daemon-flexvol v3.22.2 d6660bf471e1 2 days ago 19.7MB
calico/node v3.22.2 fd1608dbbc19 2 days ago 198MB

修改calico.yaml 文件,CALICO_IPV4POOL_CIDR的IP段要和kubeadm初始化时候的pod网段一致,注意格式要对齐,不然会报错。

root@k8scludes1:~# vim calico.yaml 

root@k8scludes1:~# cat calico.yaml | egrep "CALICO_IPV4POOL_CIDR|"10.244""
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"

不直观的话看图片:修改calico.yaml 文件。

应用calico.yaml文件。

root@k8scludes1:~# kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
......
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
Warning: policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
poddisruptionbudget.policy/calico-kube-controllers created

查看calico pod。

root@k8scludes1:~# kubectl get pod -A | grep calico
kube-system calico-kube-controllers-65898446b5-gtsz6 1/1 Running 0 58s
kube-system calico-node-d6564 1/1 Running 0 59s
kube-system calico-node-jgvjb 0/1 Running 0 59s
kube-system calico-node-snkxp 1/1 Running 0 59s

此时发现三个节点都是Ready状态了。

root@k8scludes1:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8scludes1 Ready control-plane,master 3h44m v1.22.2
k8scludes2 Ready <none> 42m v1.22.2
k8scludes3 Ready <none> 42m v1.22.2

十.配置kubectl命令tab键自动补全

查看kubectl自动补全命令。

root@k8scludes1:~# kubectl --help | grep bash
completion Output shell completion code for the specified shell (bash or zsh)

添加source <(kubectl completion bash)到/etc/profile,并使配置生效。

root@k8scludes1:~# vim /etc/profile

root@k8scludes1:~# cat /etc/profile | head -3
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
source <(kubectl completion bash) root@k8scludes1:~# source /etc/profile

此时即可kubectl命令tab键自动补全。

root@k8scludes1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8scludes1 Ready control-plane,master 3h46m v1.22.2
k8scludes2 Ready <none> 45m v1.22.2
k8scludes3 Ready <none> 45m v1.22.2

十一.总结

至此,我们已经成功在Ubuntu 18.04上安装并部署了Kubernetes 1.22.2集群。你现在可以开始创建和管理你的Kubernetes资源了。

Ubuntu 安装部署Kubernetes(k8s)集群的更多相关文章

  1. Centos7 安装部署Kubernetes(k8s)集群

    目录 一.系统环境 二.前言 三.Kubernetes 3.1 概述 3.2 Kubernetes 组件 3.2.1 控制平面组件 3.2.2 Node组件 四.安装部署Kubernetes集群 4. ...

  2. China Azure中部署Kubernetes(K8S)集群

    目前China Azure还不支持容器服务(ACS),使用名称"az acs create --orchestrator-type Kubernetes -g zymtest -n kube ...

  3. 5.基于二进制部署kubernetes(k8s)集群

    1 kubernetes组件 1.1 Kubernetes 集群图 官网集群架构图 1.2 组件及功能 1.2.1 控制组件(Control Plane Components) 控制组件对集群做出全局 ...

  4. Centos 7 部署Kubernetes(K8S)集群

    资源链接:https://pan.baidu.com/s/1-PT_QQAf7cTu_znX-S-r9Q 密码:33sr 转发:http://blog.51cto.com/lizhenliang/19 ...

  5. Istio(二):在Kubernetes(k8s)集群上安装部署istio1.14

    目录 一.模块概览 二.系统环境 三.安装istio 3.1 使用 Istioctl 安装 3.2 使用 Istio Operator 安装 3.3 生产部署情况如何? 3.4 平台安装指南 四.Ge ...

  6. 使用kubectl管理Kubernetes(k8s)集群:常用命令,查看负载,命名空间namespace管理

    目录 一.系统环境 二.前言 三.kubectl 3.1 kubectl语法 3.2 kubectl格式化输出 四.kubectl常用命令 五.查看kubernetes集群node节点和pod负载 5 ...

  7. 企业运维实践-还不会部署高可用的kubernetes集群?使用kubeadm方式安装高可用k8s集群v1.23.7

    关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 文章目录: 0x00 前言简述 ...

  8. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之自签TLS证书及Etcd集群部署(二)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.服务器设置 1.把每一 ...

  9. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录

    0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.感谢 在此感谢.net ...

  10. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之集群部署环境规划(一)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.环境规划 软件 版本 ...

随机推荐

  1. 2020-09-18:LRU手撸,说下时间复杂度和空间复杂度。

    福哥答案2020-09-18: 方法:哈希表 + 双向链表.时间复杂度:对于 put 和 get 都是 O(1).空间复杂度:O(capacity),因为哈希表和双向链表最多存储 capacity+1 ...

  2. 2021-07-12:缺失的第一个正数。给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。比如[3,4,5

    2021-07-12:缺失的第一个正数.给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数.请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案.比如[3,4,5 ...

  3. 不是单例的单例——巧用ClassLoader

    本文通过如何将一个单例类实例化两次的案例,用代码实践来引入 Java 类加载器相关的概念与工作机制.理解并熟练掌握相关知识之后可以扩宽解决问题的思路,另辟蹊径,达到目的. 背景 单例模式是最常用的设计 ...

  4. 用token辅助 密码爆破

    第一步:打开皮卡丘,点击暴力破解,token防爆破,输入正确用户名,错误密码 BP拦截请求,点击皮卡丘Login,然后拦截后, 发送给Intruder 第二步: 爆破方式选择音叉方式,   & ...

  5. WPF入门教程系列二十七 ——DataGrid使用示例MVVM模式(4)

    WPF入门教程系列目录 WPF入门教程系列二--Application介绍 WPF入门教程系列三--Application介绍(续) WPF入门教程系列四--Dispatcher介绍 WPF入门教程系 ...

  6. 在技术圈混,不知道这些你就 OUT 了

    技术之路就是漫长的打怪升级,不断学习前人的踩坑经验才能提升自己,切忌闭门造车.所谓独乐乐不如众乐乐,强烈推荐以下公众号,让你的生活多点意思,希望小伙伴们能在 coding 的路上走的更远. OSC开源 ...

  7. DOS系统中EXE程序加载过程

    1.在内存区中寻找一段容量足够的空闲内存区. 2.这段内存区的前256字节中,创建一个称为程序段前缀(PSP)的数据区. 3.这段内存区256字节之后,将程序装入,程序的地址被设为SA+10H : 0 ...

  8. Java如何生成随机数?要不要了解一下!

    前言 我们在学习 Java 基础时就知道可以生成随机数,可以为我们枯燥的学习增加那么一丢丢的乐趣.本文就来介绍 Java 随机数. 一.Random类介绍 在 Java 中使用 Random 工具类来 ...

  9. 【HarmonyOS】一文教你如何在H5页面中使用电话、定位及导航

    ​[关键字] HarmonyOS.H5页面.拨打电话.获取系统定位.跳转高德地图导航 [1.写在前面] 上一篇中我们带领大家实现了一个在低码项目中跳转加载H5页面的功能,有兴趣的可以参考以下文章: h ...

  10. CKS 考试题整理 (01)-NetworkPolicy

    Task 创建一个名为 pod-restriction 的 NetworkPolicy 来限制对在 namespace dev-team 中运行的 Pod products-service 的访问. ...