# ubuntu20下使用kubeadm安装k8s1.21

## 1. 前置知识点

### 1.1 生产环境可部署Kubernetes集群的两种方式

目前生产部署Kubernetes集群主要有两种方式：

* kubeadm：Kubeadm是一个K8s部署工具，提供kubeadm init和kubeadm join，用于快速部署Kubernetes集群。
* 二进制包：从github下载发行版的二进制包，手动部署每个组件，组成Kubernetes集群。

这里采用kubeadm搭建集群。

kubeadm工具功能：

* kubeadm init： 初始化一个Master节点
* kubeadm join： 将工作节点加入集群
* kubeadm upgrade： 升级K8s版本
* kubeadm token： 管理 kubeadm join 使用的令牌
* kubeadm reset： 清空 kubeadm init 或者 kubeadm join 对主机所做的任何更改
* kubeadm version： 打印 kubeadm 版本
* kubeadm alpha： 预览可用的新功能

### 1.2 准备环境

服务器要求：

* 建议最小硬件配置：2核CPU、2G内存、20G硬盘
* 服务器最好可以访问外网，会有从网上拉取镜像需求，如果服务器不能上网，需要提前下载对应镜像并导入节点

软件环境：

| 软件         | 版本                 |
| ---------- | ------------------ |
| 操作系统       | Ubuntu 20.04.3 LTS |
| Docker     | 20.10.12           |
| Kubernetes | 1.21               |

服务器规划：

| 角色         | IP             |
| ---------- | -------------- |
| k8s-master | 192.168.121.10 |
| k8s-node1  | 192.168.121.11 |
| k8s-node2  | 192.168.121.12 |

架构图：

![img](/files/uV4aZmFRWRHEsKNjbm3H)

### 1.3 操作系统初始化配置 【所有节点】

```shell
# 关闭防火墙
  sudo ufw disable

# 关闭swap
swapoff -a  # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab   # 永久

# 根据规划设置主机名
hostnamectl set-hostname <hostname>

# 在master添加hosts
cat >> /etc/hosts << EOF
192.168.121.10 k8s-master
192.168.121.11 k8s-node1
192.168.121.12 k8s-node2
EOF

# 时间同步
apt install ntpdate
ntpdate time.windows.com
```

## 2. 安装Docker/kubeadm/kubelet【所有节点】

这里使用Docker作为容器引擎，也可以换成别的，例如containerd

### 2.1 安装Docker

参考：[Install Docker Engine on Ubuntu | Docker Documentation](https://docs.docker.com/engine/install/ubuntu/)

```shell
sudo apt-get update
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

docker info

# 配置镜像加速器
cat > /etc/docker/daemon.json << EOF
{
 "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
```

### 2.2 安装kubeadm，kubelet和kubectl

参考：[在 Linux 系统中安装并设置 kubectl | Kubernetes](https://kubernetes.io/zh/docs/tasks/tools/install-kubectl-linux/#install-using-native-package-management)

```shell
# 更新 apt 包索引，并安装使用 Kubernetes apt 仓库所需要的包
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

# 下载 Google Cloud 公开签名秘钥
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - 

# 添加 k8s 镜像源
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

# 更新源列表
apt-get update

# 下载 kubectl，kubeadm以及 kubelet
sudo apt-get install -y kubernetes-cni kubelet=1.21.0-00 kubeadm=1.21.0-00 kubectl=1.21.0-00 --allow-downgrades

# 注意，这里需要指定版本，高版本的kubeadm无法安装低版本的k8s集群
# 如果已经装了高版本，可以使用命令移除并重新安装 apt-get remove -y kubelet kubeadm kubectl

systemctl enable kubelet
```

## 3. 部署Kubernetes Master

在主节点k8s-master上执行：

```shell
kubeadm init \
 --apiserver-advertise-address=192.168.121.10 \
 --image-repository registry.aliyuncs.com/google_containers \
 --kubernetes-version v1.21.0 \
 --service-cidr=10.96.0.0/12 \
 --pod-network-cidr=10.244.0.0/16 \
 --ignore-preflight-errors=all
```

* \--apiserver-advertise-address 集群通告地址
* \--image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问，这里指定阿里云镜像仓库地址
* \--kubernetes-version K8s版本，与上面安装的一致
* \--service-cidr 集群内部虚拟网络，Pod统一访问入口
* \--pod-network-cidr Pod网络，与下面部署的CNI网络组件yaml中保持一致

或者 使用配置文件引导：

```shell
vi kubeadm.conf
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.21.0
imageRepository: registry.aliyuncs.com/google_containers 
networking:
 podSubnet: 10.244.0.0/16 
 serviceSubnet: 10.96.0.0/12 

kubeadm init --config kubeadm.conf --ignore-preflight-errors=all  
```

初始化完成后，最后会输出一个join命令，先记住，下面用。拷贝kubectl使用的连接k8s认证文件到默认路径：

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

查看工作节点：

```shell
root@k8s-master:~# kubectl  get nodes
NAME         STATUS     ROLES                  AGE     VERSION
k8s-master   NotReady   control-plane,master   5m27s   v1.21.0
```

注：由于网络插件还没有部署，还没有准备就绪 NotReady

## 4. 加入Kubernetes Node

在两个工作节点上执行（node1和node2）：

```shell
kubeadm join 192.168.121.10:6443 --token xt2yqv.xz8pio7autncbyj6 \
  --discovery-token-ca-cert-hash sha256:e44fb8d47d0f39799e6c954bc17a5c91a00cbf87026c9291ec59aa06cffe1599
```

默认token有效期为24小时，当过期之后，该token就不可用了。这时就需要重新创建token，可以直接使用命令快捷生成：

```shell
kubeadm token create --print-join-command
```

参考资料：<https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/>

> 如果执行报错，请执行 kubeadm reset命令，并将.kube文件删除，然后重来

## 5. 部署容器网络（CNI）

Calico是一个纯三层的数据中心网络方案，是目前Kubernetes主流的网络方案。

下载YAML：

```shell
wget https://docs.projectcalico.org/manifests/calico.yaml
```

下载完后还需要修改里面定义Pod网络（CALICO\_IPV4POOL\_CIDR），与前面kubeadm init的 --pod-network-cidr指定的一样。

修改完后文件后，部署：10.244.0.0/16

```shell
kubectl apply -f calico.yaml
kubectl get pods -n kube-system
```

等Calico Pod都Running，节点也会准备就绪。

Core DNS 问题处理：

```shell
kubectl get pods -n kube-system
NAME                   READY  STATUS       RESTARTS  AGE
calico-kube-controllers-8db96c76-z7h5p  1/1   Running       0      16m
calico-node-pshdd             1/1   Running       0      16m
calico-node-vjwlg             1/1   Running       0      16m
coredns-545d6fc579-5hd9x         0/1   ImagePullBackOff  0      16m
coredns-545d6fc579-wdbsz         0/1   ImagePullBackOff  0      16m
```

在所有节点执行：

```shell
docker pull registry.aliyuncs.com/google_containers/coredns:1.8.0
docker tag registry.aliyuncs.com/google_containers/coredns:1.8.0 registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
```

过一会儿，CoreDNS Pod会自动恢复正常。

注：以后所有yaml文件都只在Master节点执行。

安装目录：/etc/kubernetes/

组件配置文件目录：/etc/kubernetes/manifests/

参考资料：<https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network>

## 6. 测试kubernetes集群

在Kubernetes集群中创建一个pod，验证是否正常运行：

```shell
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc
```

访问地址： [http://NodeIP:Port>](https://yangsx95.gitbook.io/notes/devops/kubernetes/an-zhuang-k8s/http:/NodeIP:Port>)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yangsx95.gitbook.io/notes/devops/kubernetes/an-zhuang-k8s/ubuntu20-xia-shi-yong-kubeadm-an-zhuang-k8s1.21.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
