Kubernetes集群部署笔记
本作品由Galen Suen采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。由原作者转载自个人站点。
概述
本文用于整理基于Debian操作系统使用kubeadm工具部署Kubernetes集群的操作过程。该集群部署于一组本地虚拟服务器上,用于学习Kubernetes
的基础概念和基本操作,并作为今后其他学习内容的实践部署提供环境。
考虑到不同的网络环境,本文中一些步骤会记录两种操作方式,通过镜像等方式加快部署效率、避免部署错误。有关镜像同步的方案,可参考附件内容中的同步所需镜像。
随着操作系统和各相关组件版本的更新,笔者将在验证通过后对本文进行补充和更新。
服务器
受限于本地物理服务器的配置,虚拟服务器配置规划如下表。
Host | OS | IP | CPU | RAM | K8s | Roles |
---|---|---|---|---|---|---|
k8s-n0 |
Debian 10.10 | 10.0.0.50 |
2 vCPUs | 4 GB | v1.22.1 | control-plane , master |
k8s-n1 |
Debian 10.10 | 10.0.0.51 |
4 vCPUs | 6 GB | v1.22.1 | |
k8s-n2 |
Debian 10.10 | 10.0.0.52 |
4 vCPUs | 6 GB | v1.22.1 | |
k8s-n3 |
Debian 10.10 | 10.0.0.53 |
4 vCPUs | 6 GB | v1.22.1 |
所有虚拟服务器CPU均为amd64
架构。
截止本文发布时,笔者基于最新Debian 11 ("bullseye")部署的集群仍然存在一些问题,故暂且发布基于Debian 10 ("buster")的笔记。
网络环境
本地网络IP地址范围为10.0.0.0/24
,其中:
10.0.0.2
-10.0.0.99
为静态分配,供虚拟服务器使用10.0.0.100
-10.0.0.200
用于DHCP
自动分配10.0.0.201
-10.0.0.254
为静态分配,供负载均衡器使用
其他组件
容器运行时
containerd v1.4.9Pod网络组件
flannel v0.14.0负载均衡器
metallb v0.10.2持久卷供应
local-path-provisioner v0.0.20
准备工作
服务器配置
本文假设服务器硬件和操作系统已经配置完毕,所有服务器上都已经正确配置了ssh
服务和sudo
权限。
作为参考,这里记录笔者配置sudo
权限和ssh
服务的过程。
配置
sudo
权限如操作人员的登录用户已经被正确配置了sudo权限,可跳过此步骤。
本示例中,操作人员的登录用户名为
tiscs
,需要实际环境情况进行替换。# 使用root用户登录系统
# 安装sudo,并配置sudo权限
apt update
apt install sudo
echo "tiscs ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/tiscs # 这在生产环境绝不是个好主意,仅仅是为了演练环境操作方便
配置
ssh
服务# 安装openssh-server,并配置ssh服务为自动启动
sudo apt update
sudo apt install openssh-server
sudo systemctl enable ssh --now
配置过程
安装容器运行时
本文配置的集群选择containerd作为容器运行时。
在所有节点上执行如下操作。
配置模块加载
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF sudo modprobe overlay
sudo modprobe br_netfilter
配置
sysctl
参数cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF sudo sysctl --system
配置APT源
# 安装依赖项
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# 根据网络环境选择官方源或镜像源 # 1. 配置Docker官方源
curl -fsSL https://download.docker.com/linux/debian/gpg \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 2. 配置Aliyun镜像源
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
echo "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装containerd
sudo apt update
sudo apt install -y containerd.io
初始化配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 配置systemd cgroup驱动
sudo sed -i 's|\(\s\+\)\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options\]|\1\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options\]\n\1 SystemdCgroup = true|g' /etc/containerd/config.toml
# (可选)配置阿里云容器镜像源
sudo sed -i 's/registry-1.docker.io/xrb7j2ja.mirror.aliyuncs.com/g' /etc/containerd/config.toml
# (可选)配置sandbox image地址
# 为了方便,这里配置为与kubelet所需相同的版本(可以使用kubeadm config images list命令查看)
sudo sed -i 's|k8s.gcr.io/pause:.\+|registry.cn-beijing.aliyuncs.com/choral-k8s/pause:3.5|g' /etc/containerd/config.toml
# 重启containerd服务
sudo systemctl restart containerd
安装kubeadm
在所有节点上执行如下操作。
配置APT源
# 根据网络环境选择官方源或镜像源 # 1. 配置Docker官方源
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" \
| sudo tee /etc/apt/sources.list.d/kubernetes.list # 2. 配置Aliyun镜像源
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" \
| sudo tee /etc/apt/sources.list.d/kubernetes.list
安装
kubeadm
、kubelet
和kubectl
sudo apt install -y kubelet=1.22.1-00 kubeadm=1.22.1-00 kubectl=1.22.1-00
sudo apt-mark hold kubelet kubeadm kubectl
安装并配置
crictl
(可选)可以安装并配置
crictl
,便于在k8s
节点上管理容器运行时。# 安装crictl工具
sudo apt install -y cri-tools # 配置crictl使用containerd运行时
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF # 验证crictl配置
sudo crictl images # 列出所有镜像
配置控制平面节点
在k8s-n0
节点上执行如下操作。
预先下载所需镜像
# 查看所需的镜像列表
kubeadm config images list --kubernetes-version=v1.22.1 # --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s # 1. 使用默认容器镜像仓库
sudo kubeadm config images pull --kubernetes-version=v1.22.1 # 2. 使用自建容器镜像仓库
sudo kubeadm config images pull --kubernetes-version=v1.22.1 \
--image-repository registry.cn-beijing.aliyuncs.com/choral-k8s
初始化控制平面节点
# --apiserver-advertise-address: 当前节点IP地址
# --pod-network-cidr : Pod网络地址段(CIDR: https://datatracker.ietf.org/doc/html/rfc4632) # 1. 使用默认容器镜像仓库
sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \
--pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.1 # 2. 使用自建容器镜像仓库
sudo kubeadm init --apiserver-advertise-address 10.0.0.50 \
--pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.1 \
--image-repository registry.cn-beijing.aliyuncs.com/choral-k8s
执行完上述操作后,
kubeadm init
命令会输出用于添加节点到集群中的说明,请保存该说明中的内容。示例如下:sudo kubeadm join 10.0.0.50:6443 \
--token vafq03.5dl6j1cbcd1yzf3c \
--discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
添加kubectl配置(可选)
mkdir -p ~/.kube
sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
安装网络组件
# 1. 使用默认镜像仓库(quay.io/coreos)安装
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 2. 使用给自定义镜像仓库安装
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \
| sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f - # 2.1 如果访问raw.githubusercontent.com上的文件存在网络问题
# 可以使用jsdelivr提供的GitHub CDN地址(https://www.jsdelivr.com/github)
curl -s https://cdn.jsdelivr.net/gh/coreos/flannel@master/Documentation/kube-flannel.yml \
| sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f -
添加工作节点
在k8s-n1
、k8s-n2
和k8s-n3
节点上执行如下操作。该操作中需要的token值和hash值通过上述步骤中的kubeadm init
操作获取。
添加工作节点
sudo kubeadm join 10.0.0.50:6443 \
--token vafq03.5dl6j1cbcd1yzf3c \
--discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
查看节点状态
在
k8s-n0
节点上执行如下操作。kubectl get nodes
kubectl top nodes
安装Helm工具(可选)
本文暂不涉及使用helm
执行的操作,该步骤可选。
安装Helm工具
# 下载并安装
curl -sL https://get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz | tar xzf - linux-amd64/helm
sudo cp ./linux-amd64/helm /usr/local/bin/helm
rm -rf ./linux-amd64
sudo chown root:root /usr/local/bin/helm
sudo chmod 755 /usr/local/bin/helm # 验证helm安装
helm version
安装Metrics Server(可选)
部署metrics server
以启用指标服务,未安装metrics server
前,kubectl top
命令无法正常执行。
在k8s-n0
节点上执行如下操作。
执行清单文件
这里需要注意,为解决证书错误,需要添加
metrics-server
容器的参数--kubelet-insecure-tls
,这里选择通过sed
命令修改清单文件后再使用kubectl
执行。# 1. 使用官方镜像地址直接安装
curl -sL https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \
| sed -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" | kubectl apply -f -
# 1.1 为避免特殊网络环境中的清单文件加载问题,可以使用FastGit提供的加速方案
curl -sL https://endpoint.fastgit.org/https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \
| sed -e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" | kubectl apply -f - # 2. 使用自定义镜像地址安装
curl -sL https://endpoint.fastgit.org/https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml \
| sed \
-e "s|\(\s\+\)- args:|\1- args:\n\1 - --kubelet-insecure-tls|" \
-e "s|k8s.gcr.io/metrics-server|registry.cn-beijing.aliyuncs.com/choral-k8s|g" \
| kubectl apply -f -
#
安装负载均衡组件
由云服务商提供的Kubernetes
服务,通常会提供内置的负载均衡实现。而笔者部署环境为私有环境,需要一个轻量的负载均衡实现以支撑LoadBalancer
类型的服务。
笔者选择MetalLB作为负载均衡实现,配置为二层网络模式。LoadBalancer
地址范围配置为10.0.0.201-10.0.0.254
,需根据具体网络环境进行修改。
在k8s-n0
节点上执行如下操作。
安装
MetalLB
# 创建用于部署MetalLB的命名空间
kubectl create namespace metallb-system # 创建必须的配置文件
cat <<EOF | kubectl apply -f - --dry-run=client
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 10.0.0.201-10.0.0.254
EOF # 1. 直接执行清单文件
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml
# 1.1 为避免特殊网络环境中的清单文件加载问题,可以使用jsdelivr提供的加速方案加速地址
kubectl apply -f https://cdn.jsdelivr.net/gh/metallb/metallb@v0.10.2/manifests/metallb.yaml # 2. 替换命名空间。命名空间需要与刚刚创建的ConfigMap相同。
curl -sL https://cdn.jsdelivr.net/gh/metallb/metallb@v0.10.2/manifests/metallb.yaml \
| sed -e "s|namespace: metallb-system|namespace: kube-system|g" | kubectl apply -f -
安装持久卷供应程序
Kubernetes
内置的local-storage
存储类无法动态供应卷,为便于基于该环境演练时自动创建持久卷,选择使用local-path-provisioner
作为持久卷供应程序。
创建所需的目录
在所有节点上执行如下操作。
sudo mkdir -p /opt/local-path-provisioner
安装
local-path-provisioner
在
k8s-n0
节点上执行如下操作。# 1. 使用官方清单文件地址直接安装
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
# 1.1 同样可以使用jsdelivr提供的加速方案
kubectl apply -f https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml # 2. 替换命名空间
curl -s https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml \
| sed \
-e "1,6d" \
-e "s/local-path-storage/kube-system/" \
| kubectl apply -f -
配置默认存储类
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
检查集群工作状态
在k8s-n0
节点上执行如下操作。
查看节点状态
kubectl get nodes
kubectl top nodes
查看Pod状态
kubectl get pods -A
kubectl top pods -A
附加内容
同步所需镜像
由于特殊网络环境问题,需要同步kubelet所需镜像至其他镜像仓库的,可参考如下操作。
笔者开发环境中使用podman管理容器和镜像,已将docker
设置为podman
的别名(alias docker=podman
)。
同步kubelet所需镜像
首先,需要创建私有镜像仓库认证凭据。
# 根据需要将`registry.cn-beijing.aliyuncs.com`替换为私有镜像仓库地址
docker login registry.cn-beijing.aliyuncs.com
创建一个脚本
gcr_mirror_sync.sh
,内容如下。# gcr_mirror_sync.sh
# 根据需要将`registry.cn-beijing.aliyuncs.com/choral-k8s/`替换为私有镜像仓库地址
while read o
do {
t=$(echo $o | sed 's|k8s.gcr.io.*/|registry.cn-beijing.aliyuncs.com/choral-k8s/|g')
docker pull $o
docker tag $o $t
docker push $t
docker rmi $o
docker rmi $t
}
done < "${1:-/dev/stdin}"
该脚本有两种使用方法。
kubeadm config images list --kubernetes-version=v1.22.1 | bash gcr_mirror_sync.sh
# 列出所需镜像列表并保存到文件
kubeadm config images list --kubernetes-version=v1.22.1 > gcr-image-list
# 拷贝该文件至gcr_mirror_sync.sh所在主机,然后执行该脚本
bash gcr_mirror_sync.sh gcr-image-list
同步附加组件镜像
# 根据需要将`registry.cn-beijing.aliyuncs.com/choral-k8s/`替换为私有镜像仓库地址。 # 同步metrics server所需镜像
docker pull k8s.gcr.io/metrics-server/metrics-server:v0.5.0
docker tag k8s.gcr.io/metrics-server/metrics-server:v0.5.0 registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
docker push registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
docker rmi k8s.gcr.io/metrics-server/metrics-server:v0.5.0
docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0 # 同步flannel所需镜像
docker pull quay.io/coreos/flannel:v0.14.0
docker tag quay.io/coreos/flannel:v0.14.0 registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
docker push registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
docker rmi quay.io/coreos/flannel:v0.14.0
docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
参考资料
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
https://github.com/flannel-io/flannel/blob/master/Documentation/kubernetes.md
Kubernetes集群部署笔记的更多相关文章
- kubernetes集群部署
鉴于Docker如此火爆,Google推出kubernetes管理docker集群,不少人估计会进行尝试.kubernetes得到了很多大公司的支持,kubernetes集群部署工具也集成了gce,c ...
- Kubernetes集群部署关键知识总结
Kubernetes集群部署需要安装的组件东西很多,过程复杂,对服务器环境要求很苛刻,最好是能连外网的环境下安装,有些组件还需要连google服务器下载,这一点一般很难满足,因此最好是能提前下载好准备 ...
- RocketMQ 简单梳理 及 集群部署笔记【转】
一.RocketMQ 基础知识介绍Apache RocketMQ是阿里开源的一款高性能.高吞吐量.队列模型的消息中间件的分布式消息中间件. 上图是一个典型的消息中间件收发消息的模型,RocketMQ也 ...
- 基于Kubernetes集群部署skyDNS服务
目录贴:Kubernetes学习系列 在之前几篇文章的基础,(Centos7部署Kubernetes集群.基于kubernetes集群部署DashBoard.为Kubernetes集群部署本地镜像仓库 ...
- 为Kubernetes集群部署本地镜像仓库
目录贴:Kubernetes学习系列 经过之前两篇文章:Centos7部署Kubernetes集群.基于kubernetes集群部署DashBoard,我们基本上已经能够在k8s的集群上部署一个应用了 ...
- Kubernetes 集群部署(2) -- Etcd 集群
Kubenetes 集群部署规划: 192.168.137.81 Master 192.168.137.82 Node 192.168.137.83 Node 以下在 Master 节点操作. ...
- Gitlab CI 集成 Kubernetes 集群部署 Spring Boot 项目
在上一篇博客中,我们成功将 Gitlab CI 部署到了 Docker 中去,成功创建了 Gitlab CI Pipline 来执行 CI/CD 任务.那么这篇文章我们更进一步,将它集成到 K8s 集 ...
- Docker学习-Kubernetes - 集群部署
Docker学习 Docker学习-VMware Workstation 本地多台虚拟机互通,主机网络互通搭建 Docker学习-Docker搭建Consul集群 Docker学习-简单的私有Dock ...
- kubernetes 集群部署
kubernetes 集群部署 环境JiaoJiao_Centos7-1(152.112) 192.168.152.112JiaoJiao_Centos7-2(152.113) 192.168.152 ...
随机推荐
- P6753 [BalticOI 2013 Day1] Ball Machine
P6753 [BalticOI 2013 Day1] Ball Machine 题意 给你一个树,每次从根节点放一个求,如果其子节点有空这个球会向下滚,若有多个节点为空则找儿子中以子树内编号的最小值为 ...
- URL 参数为sql 有空格 的解决办法
var strsql=" select e.* from es_doc_main e where 1=1" +" and e.doccode='"+prtNo+ ...
- HCNA Routing&Switching之交换技术基础
什么是交换机?顾名思义,交换机就是用来数据包交换的:广泛用于终端接入:它的前身是hub(集线器),hub是一个古老的设备,它的作用也是用于终端接入,但hub有一个最大的缺点是它不能隔离冲突域:所谓冲突 ...
- 总结开发中基于DevExpress的Winform界面效果
DevExpress是一家全球知名的控件开发公司, DevExpress 也特指此公司出品的控件集合或某系列控件或其中某控件.我们应用最为广泛的是基于Winform的DevExpress控件组,本篇随 ...
- JAVA虚拟机的组成>从零开始学java系列
目录 JAVA虚拟机的组成 什么是虚拟机? JAVA虚拟机的组成部分 堆区(堆内存) 方法区 虚拟机栈 本地方法栈 程序计数器 字符串常量池 JAVA虚拟机的组成 什么是虚拟机? 虚拟机是运行在隔离环 ...
- C运算符(算数运算符)
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号.C 语言内置了丰富的运算符,并提供了以下类型的运算符: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 杂项运算符 1 //实列 2 3 ...
- Install Redmine on Virtual Machine with Vagrant
Initialize VM: chad@typcserver ~/docs/vagrant-prj $ vagrant --version Vagrant 1.4.3 chad@typcserver ...
- 使用vimdiff做hg的版本比较工具
gvim的文本比较功能很强,命令行用法:gvim -d file1 file2,hg自带的hg diff没有颜色标示,含义也不够清晰,所以需要用vim的diff代替它,实现方法是在全局配置文件中增加: ...
- tomcat及springboot实现Filter、Servlet、Listener
tomcat实现: 核心类org.apache.catalina.startup.ContextConfig //支持注解 see:org.apache.catalina.deploy.WebXml ...
- [06 Go语言基础-包]
[06 Go语言基础-包] 包 什么是包,为什么使用包? 到目前为止,我们看到的 Go 程序都只有一个文件,文件里包含一个 main 函数和几个其他的函数.在实际中,这种把所有源代码编写在一个文件的方 ...