Kubernetes(K8s)集群部署含10年证书
🌟 前言 手搭建一个 k8s 集群,一个master管理节点二个work工作节点,适用于没有科学上网渠道的同学;
一、初始化CentOS 7操作系统
🍇节点规划
主机名 | 内网IP | 权限 | 入门配置 | 应用组件 |
---|---|---|---|---|
master | 192.168.100.221 | master | 2C 4G | |
node1 | 192.168.100.222 | work | 2C 4G | |
node2 | 192.168.100.223 | work | 2C 4G |
Kubernetes(K8s)集群组件版本
[root@master ~]# kubeadm config images list
I1207 11:57:36.768397 7341 version.go:255] remote version is much newer: v1.25.4; falling back to: stable-1.22
k8s.gcr.io/kube-apiserver:v1.22.16
k8s.gcr.io/kube-controller-manager:v1.22.16
k8s.gcr.io/kube-scheduler:v1.22.16
k8s.gcr.io/kube-proxy:v1.22.16
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4
🍇 环境架构
🍇 设置hosts解析
操作节点:所有节点(k8s-master, k8s-node)均需执行
[root@localhost ~]# hostnamectl set-hostname master #设置master节点的hostname
[root@localhost ~]# hostnamectl set-hostname node1 #设置node1节点的hostname
[root@localhost ~]# hostnamectl set-hostname node2 #设置node2节点的hostname
添加 hosts 解析
cat >>/etc/hosts<<EOF
192.168.100.221 master
192.168.100.222 node1
192.168.100.223 node2
EOF
设置安全组开放端口
如果节点间无安全组限制(内网机器间可以任意访问),可以忽略,否则,至少保证如下端口可通:
k8s-master 节点:TCP:6443,2379,2380,60080,60081;UDP协议端口全部打开
k8s-slave 节点:UDP协议端口全部打开
设置iptables
[root@master ~]# iptables -P FORWARD ACCEPT
[root@node1 ~]# iptables -P FORWARD ACCEPT
[root@node2 ~]# iptables -P FORWARD ACCEPT
关闭swap交换分区
[root@master ~]# swapoff -a
[root@node1 ~]# swapoff -a
[root@node2 ~]# swapoff -a
## 永久关闭
[root@master ~]# sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
[root@node1 ~]# sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
[root@node2 ~]# sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
初始化centos系统镜像源
## 这里我们引用阿里云系统镜像源
[root@master ~]# curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@node1 ~]# curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@node2 ~]# curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
## 使用阿里国内docker-ce镜像源
[root@master ~]# curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@node1 ~]# curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@node2 ~]# curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
## 使用阿里源国内kubernetes镜像源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum clean all && yum makecache
🍇 安装docker-ce
# step 1: 安装必要的一些系统工具
yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2:在上一步已添加源
sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# Step 3: 更新并安装Docker-CE
yum makecache fast
yum -y install docker-ce
# Step 5: 开启Docker服务
systemctl start docker.service
systemctl status docker.service
# 注意:
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
# 将[docker-ce-test]下方的enabled=0修改为enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
# Loading mirror speeds from cached hostfile
# Loaded plugins: branch, fastestmirror, langpacks
# docker-ce.x86_64 3:20.10.9-3.el7 docker-ce-stable
# docker-ce.x86_64 3:18.09.7-3.el7 docker-ce-stable
# docker-ce.x86_64 3:19.03.8-3.el7 docker-ce-stable
# Available Packages
# Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]
# kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了
sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://mm16iitq.mirror.aliyuncs.com"]
}
EOF
[root@master ~]# scp -r /etc/docker/daemon.json node1:/etc/docker/
[root@master ~]# scp -r /etc/docker/daemon.json node2:/etc/docker/
# 重启生效
systemctl daemon-reload
systemctl restart docker
二、初始化Kubernetes(K8s)集群组件
🍇 安装 kubeadm、kubelet 和 kubectl
## disableexcludes=kubernetes 指定或者说禁掉除了这个之外的的仓库
[root@master ~]# yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 --disableexcludes=kubernetes
[root@node1 ~]# yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 --disableexcludes=kubernetes
[root@node2 ~]# yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 --disableexcludes=kubernetes
## 查看组件版本
[root@master ~]# kubeadm config images list
I1207 11:57:36.768397 7341 version.go:255] remote version is much newer: v1.25.4; falling back to: stable-1.22
k8s.gcr.io/kube-apiserver:v1.22.16
k8s.gcr.io/kube-controller-manager:v1.22.16
k8s.gcr.io/kube-scheduler:v1.22.16
k8s.gcr.io/kube-proxy:v1.22.16
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4
[root@master ~]# systemctl enable kubelet.service
[root@node1 ~]# systemctl enable kubelet.service
[root@node2 ~]# systemctl enable kubelet.service
[root@master ~]# systemctl daemon-reload && systemctl status kubelet.service
[root@node1 ~]# systemctl daemon-reload && systemctl status kubelet.service
[root@node2 ~]# systemctl daemon-reload && systemctl status kubelet.service
## 初始化之前,所有节点cat如下内容
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
[root@master ~]# sysctl --system
[root@node1 ~]# sysctl --system
[root@node2 ~]# sysctl --system
🍇 初始化master节点
[root@master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 --image-repository=registry.aliyuncs.com/google_containers
## 根据初始化结果输入提示,配置kubectl客户端认证
[root@master ~]# mkdir -p $HOME/.kube
[root@master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
🍇 安装网络插件,否则 node 是 NotReady 状态
下载 flannel 的 yaml 文件
[root@master ~]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
修改配置,指定网卡名称,大概在文件的 159 行,添加一行配置
## vim kube-flannel.yml
...
- name: kube-flannel
#image: flannelcni/flannel:v0.20.2 for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=eth0 # 如果机器存在多网卡的话,指定内网网卡的名称,默认不指定的话会找第一块网卡
resources:
执行安装flannel 网络插件
## 方法一、很有可能国内网络访问不到这个资源,在https://www.ipaddress.com/ 查询raw.githubuercontent.com的真实IP,在/etc/hosts/中绑定查到的host。
[root@master ~]# vim /etc/hosts
104.247.82.170 raw.githubusercontent.com
[root@master ~]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
## 先拉取镜像,此过程速度比较慢
$ docker pull rancher/mirrored-flannelcni-flannel:v0.20.2 ## kube-flannel.yml中版本对应
## 执行flannel安装
$ kubectl apply -f kube-flannel.yml
🍇 初始添加node节点到集群
[root@node1 ~]# kubeadm join 192.168.100.224:6443 --token qaf3jz.iemtpzc2buxkzgeu --discovery-token-ca-cert-hash sha256:2b7afdc3ed8f9833c7dc361f7c069526cc328e6c1597ebc0677eca8b145ff865
[root@node2 ~]# kubeadm join 192.168.100.224:6443 --token qaf3jz.iemtpzc2buxkzgeu --discovery-token-ca-cert-hash sha256:2b7afdc3ed8f9833c7dc361f7c069526cc328e6c1597ebc0677eca8b145ff865
## 如果忘记添加命令,可以通过如下命令生成:
[root@master ~]# kubeadm token create --print-join-command
三、Kubernetes(K8s)集群设置
🍇 设置 master 节点是否可调度
[root@master ~]# kubectl taint node k8s-master node-role.kubernetes.io/master:NoSchedule-
🍇 设置kubectl自动补全
[root@master ~]# yum install bash-completion -y
[root@master ~]# source /usr/share/bash-completion/bash_completion
[root@master ~]# source <(kubectl completion bash)
[root@master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
四、Kubernetes(K8s)集群证书配置
使用 kubeadm 安装的集群,证书默认有效期为 1 年,可以通过如下方式修改为 10 年。
[root@master ~]# cd /etc/kubernetes/pki
# 查看当前证书有效期
[root@master ~]# for i in $(ls *.crt); do echo "===== $i ====="; openssl x509 -in $i -text -noout | grep -A 3 'Validity' ; done
[root@master ~]# mkdir backup_key; cp -rp ./* backup_key/
[root@master ~]# git clone https://github.com/yuyicai/update-kube-cert.git
[root@master ~]# cd update-kube-cert/
[root@master ~]# bash update-kubeadm-cert.sh all
# 重建管理服务
[root@master ~]# kubectl -n kube-system delete po kube-apiserver-k8s-master kube-controller-manager-k8s-master kube-scheduler-k8s-master
五、Kubernetes(K8s)集群验证
master节点执行
[root@master ~]# kubectl get pods --all-namespaces
[root@master ~]# kubectl get node
创建NGINX体验
[root@master ~]# kubectl run nginx --image=nginx:alpine
[root@master ~]# kubectl get pod -o wide
六、部署dashborad
下载并修改配置
[root@master ~]# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
vi recommended.yaml
# 修改Service为NodePort类型,文件的44行添加type: NodePort
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
type: NodePort # 加上type=NodePort变成NodePort类型的服务
---
查看访问地址,本例为 30618/TCP端口
[root@master ~]# kubectl apply -f recommended.yaml
[root@master ~]# kubectl -n kubernetes-dashboard get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics** ClusterIP 10.105.115.104 <none> 8000/TCP 24s
kubernetes-dashboard NodePort 10.97.245.100 <none> 443:30618/TCP 24s
访问,地址为Kubernetes Dashboard,基于安全限制,需使用火狐、Edge,谷歌不好使。
创建ServiceAccount 进行访问
[root@master ~]# vim dashboard-admin.conf
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: admin
namespace: kubernetes-dashboard
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: kubernetes-dashboard
[root@master ~]# vim dashboard-admin.conf
[root@master ~]# kubectl apply -f dashboard-admin.conf
[root@master ~]# kubectl -n kubernetes-dashboard get secret |grep admin-token
admin-token-2ftsc kubernetes.io/service-account-token 3 17s
# 使用该命令拿到token,然后粘贴到浏览器
[root@master ~]# kubectl -n kubernetes-dashboard get secret admin-token-2ftsc -o jsonpath={.data.token}|base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6IjJWMVIwYWdTcEZjVlAtY29jVlVKQjR0bXdCN2VOTU5SaDZ6R2FRc3hXcTQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi0yZnRzYyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjJjOGNiZmFmLTc0NjktNGQ1OC1iMWQ4LTE5OWJlODhlM2EwMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbiJ9.XZKBMhgJg6a4Z0pkhSd2LnYg6W3Qmymr4w-1T2H-SoBJIZEcr_M0U9FG4KL5ELa_YUfRPqoQFk4cB_TNiwzZie_K38RkvRTL5MTx9mWCkJcp_NubrxEBVFtP7JKaXA2VuP3E-F7fX5l6bSNPz6-tAJz_zGu5AjaW2xsPWOeO90JpR3M8dTmIOuiLHBMUPmYsBBs5Skieg5DUJTQjQUJuWAFmS6l58Jc0NuZuxx-4mx0AtPbgoHD2uJseeYvxjQg0JbU6sq8_HVfJMkwRPY4aHVfyAVGkMDhfyXgy79iDz08UpP_DHCoPqE4zbRudvuCH2SpNDrSf8Pp_NCZE1TtjlA
🍇 清理集群
如果在集群安装过程中遇到了其他问题,可以使用下面的命令来进行重置:
# 在全部集群节点执行
kubeadm reset
ifconfig cni0 down && ip link delete cni0
ifconfig flannel.1 down && ip link delete flannel.1
rm -rf /run/flannel/subnet.env
rm -rf /var/lib/cni/
mv /etc/kubernetes/ /tmp
mv /var/lib/etcd /tmp
mv ~/.kube /tmp
iptables -F
iptables -t nat -F
ipvsadm -C
ip link del kube-ipvs0
ip link del dummy0
# 第一步到node节点下传镜像
docker pull rancher/mirrored-flannelcni-flannel:v0.20.2
docker pull rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0
# 第二部在master重启flannel
kubectl delete -f kube-flannel.yml
kubectl apply -f kube-flannel.yml
七、总价
K8S 是目前容器管理的一个主流,是实现 PaaS 的重要组成部分,所以我认为学习它是非常有价值的;
但是 K8S 可以说博大精深,不是短时间内可以掌握的,或者说只能掌握一些简单的操作;
另外 docker 已经被弃用了,早期的 k8s 的确是用 docker 作为容器运行时,但是从去年还是前年就不用了,取而代之的是 CRI-O 或者直接调用 containerd ,所以 docker 可以简单了解一下,不用花太多精力深入。