Sealos K8s
手动配置 kubernetes 集群十分耗时,有没有更简单的方式呢?
当然有,本文将介绍如何使用 sealos 在10分钟内快速部署 kubernetes 集群。
准备工作
如果你需要配置高可用的集群,至少需要准备三台linux系统主机(Ubuntu 22.04 LTS),资源有限的情况下可以考虑使用单台机器。
| 节点名称 | 节点IP |
|---|---|
k8s-master01 |
192.168.1.189 |
k8s-worker01 |
192.168.4.61 |
k8s-worker02 |
192.168.13.199 |
机器准备好之后需要确定已卸载 docker、kubeadm 等工具,最好重装系统。
三台机器的root密码设置为相同密码,并且允许ssh方式root用户登录。
首先修改一下主机名称
# master节点修改主机名称
hostnamectl set-hostname k8s-master01
bash
# worker节点1修改主机名称
hostnamectl set-hostname k8s-worker01
bash
# worker节点2修改主机名称
hostnamectl set-hostname k8s-worker02
bash
# 修改所有节点hosts文件内容
cat >> /etc/hosts << EOF
192.168.1.189 k8s-master01
192.168.4.61 k8s-worker01
192.168.13.199 k8s-worker02
EOF
# 验证各节点是否互通
ping k8s-master01
ping k8s-worker01
ping k8s-worker02
接下来配置系统参数,所有节点都要操作
# 关闭swap
swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab
# 关闭 SELinux
apt update && apt install selinux-utils
setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinuxconfig
# 关闭防火墙,清空防火墙规则
sudo ufw disable && ufw status
# 设置时区
timedatectl set-timezone Asia/Shanghai
# 同步系统时间
apt install -y ntpdate
ntpdate time1.aliyun.com
# 重启一下系统
reboot
# master节点生成秘钥,用于通过ssh连接worker节点
ssh-keygen
# 拷贝master秘钥公钥到worker节点
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.4.61
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.13.199
使用云服务商的机器,还需要开放相关端口
| 端口 | 说明 |
|---|---|
6443 |
Kubernetes API server |
8443 |
Kubernetes Dashboard |
2379-2380 |
etcd server client API |
10250 |
Kubelet API |
10251 |
kube-scheduler |
10252 |
kube-controller-manager |
10255 |
Read-only Kubelet API (Heapster) |
30000-32767 |
NodePort Services默认端口范围 |
安装sealos
Sealos 是一款基于 Kubernetes 的云操作系统发行版,它旨在简化 Kubernetes 集群的部署和管理过程。Sealos 的特点在于它采用云原生的方法来构建和管理集群,使得用户能够像使用个人电脑一样简便地管理 Kubernetes 集群。官方文档
官方提供了多种安装方式,这里使用二进制安装,我们只需要在master节点进行安装。
# 查看系统内核,确定安装哪个版本的 sealos,查看版本列表(https://github.com/labring/sealos/releases)
uname -a
# 下载最新版sealos,在版本下面的安装包右键复制地址
wget https://githubfast.com/labring/sealos/releases/download/v5.0.0/sealos_5.0.0_linux_amd64.tar.gz && \
tar -zxvf sealos_5.0.0_linux_amd64.tar.gz sealos && chmod +x sealos && mv sealos /usr/bin
# 验证安装是否成功
sealos help
Sealos镜像仓库
云服务器网络原因无法使用Docker Hub镜像,我们可以使用Sealos私有仓库。
首先将本地的docker镜像导出为tar包:website-api.tar
# 在master节点登录 sealos 私有仓库
sealos login -u admin -p passw0rd sealos.hub:5000
# 上传本地镜像到服务器,用 sealos 加载
sealos load -i website-api.tar
sealos push sealos.hub:5000/website_api:latest
创建集群
Sealos 提供了阿里云镜像仓库服务,我们替换为阿里云镜像仓库,以加速镜像拉取。
部署集群命令参考。对应的镜像版本可以在dockerhub或aliyuncshttps://explore.ggcr.dev上搜索查看,比如搜索:labring/kubernetes,后面的小版本越高越稳定
# 生成配置文件 Clusterfile,注意:labring/helm 应当在 labring/calico 之前
sealos gen registry.cn-shanghai.aliyuncs.com/labring/kubernetes:v1.25.0 registry.cn-shanghai.aliyuncs.com/labring/helm:v3.14.1-amd64 registry.cn-shanghai.aliyuncs.com/labring/calico:v3.24.1 \
--masters 192.168.1.189 \
--nodes 192.168.4.61,192.168.13.199 \
--passwd 你的主机root密码 -o Clusterfile
# 启动集群,中间可能会卡住一段时间比较慢,看网络,快的话10分钟左右
sealos apply -f Clusterfile
# 后续增加主节点
sealos add --masters ip1,ip2,ip3
# 后续增加工作节点
sealos add --nodes ip1,ip2,ip3
集群运行成功后会把 Clusterfile 保存到 .sealos/default/Clusterfile 文件中,可以修改其中字段来重新 apply 对集群进行变更
安装过程中如果终端断连导致日志不输出,可以执行
如果安装失败,需要清理安装文件进行重装,需要执行reset命令:
集群验证
部署完成后,可以查看集群状态
集群部署完成后,我们还需要进行一些配置,方便我们快速使用集群。
# 使用阿里云镜像源
cat >> /etc/containers/registries.conf << EOF
[[registry.mirror]]
prefix = "docker.io/labring"
location = "registry.cn-shanghai.aliyuncs.com/labring"
EOF
# 需要在master节点外的机器上控制集群
kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes
# 允许master节点上创建pod
kubectl taint nodes k8s-master01 node-role.kubernetes.io/control-plane:NoSchedule-
查看集群证书
# 查看集群证书剩余时间
kubeadm certs check-expiration
# 证书作用
admin.conf 用于管理员与Kubernetes API服务器进行交互的身份验证。这个配置文件包含了访问API服务器所需的证书和密钥。
apiserver 安全通信:API服务器使用此证书与其他集群组件(如kubelet、控制器管理器等)进行TLS加密通信。确保只有授权的客户端可以访问API服务器。
apiserver-etcd-client API服务器用于与etcd集群通信的客户端证书,确保API服务器与etcd之间的通信是加密和安全的。
apiserver-kubelet-client API服务器用于与kubelet通信的客户端证书,确保API服务器可以安全地与集群中的节点进行通信。
controller-manager.conf 控制器管理器用于与API服务器交互的身份验证证书,确保控制器管理器可以访问和操作集群资源。
etcd-healthcheck-client 用于etcd健康检查的客户端证书,确保可以安全地检查etcd集群的健康状态。
etcd-peer etcd集群中节点之间通信的证书,确保etcd集群内部的通信是加密和安全的。
etcd-server etcd服务器用于与客户端通信的证书,确保etcd服务器可以安全地与集群中的其他组件进行通信。
front-proxy-client 前端代理客户端证书,用于与API服务器进行身份验证,通常与某些代理或负载均衡器相关。
scheduler.conf
# 根证书
ca(Certificate Authority) 根证书颁发机构,用于签发和验证集群中其他所有证书的有效性。这是整个证书信任链的起点。
etcd-ca etcd集群的根证书颁发机构,专门用于签发和验证etcd相关的证书。
front-proxy-ca 前端代理的根证书颁发机构,用于签发和验证与前端代理相关的证书。
安装dashboard
下载依赖文件:recommended.yaml,重命名文件为 dashboard.yaml 。
修改一下 dashboard.yaml 配置,将类型改为 NodePort ,并设置 spec.ports.nodePort: 30043
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30043
selector:
k8s-app: kubernetes-dashboard
通过 yaml 部署:
配置一下访问权限,首先在命名空间kubernetes-dashboard创建名为admin-user的服务帐户。
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
现在我们需要找到可用于登录的令牌。执行以下命令:
# 创建admin-user
kubectl apply -f dashboard-adminuser.yaml
# 获取token
kubectl -n kubernetes-dashboard create token admin-user
为了避免每次登录都需要获取令牌,我们还可以创建一个带有绑定服务帐户的密钥的令牌,令牌将保存在密钥中:
apiVersion: v1
kind: Secret
metadata:
name: admin-user
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: "admin-user"
type: kubernetes.io/service-account-token
创建秘钥后,我们可以执行以下命令来获取保存在秘密中的令牌,方便下次取用:
# 创建秘钥
kubectl apply -f dashboard-adminuser-secret.yaml
# 这里获取的token多了一个'%'号,不要复制它(不知道为啥会出现,囧)
kubectl get secret admin-user -n kubernetes-dashboard -o jsonpath={".data.token"} | base64 -d
将admin-user权限授权给cluster-admin:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
执行命令,为ServiceAccount创建ClusterRoleBinding:
我们已经配置好了,访问dashboard:https://121.37.19.93:30043。
但是使用token方式登录比较麻烦,token也会过期,我们配置一下kubeconfig文件验证登录。
需要的证书内容在配置文件中,位于 ~/.kube/config,查看内容:cat ~/.kube/config
# 查看证书文件内容
cat ~/.kube/config | grep certificate-authority-data | awk -F ":" '{print $2}' | tr -d " " | base64 -d > ca.crt
获取Kubernetes API Server 的信息。执行以下命令:
输出:https://apiserver.cluster.local:6443,根据config内容cluster: kubernetes知道,集群名称为 kubernetes,用户名是 kubernetes-admin。
使用 kubectl 工具,生成 kubeconfig 登录认证文件。
# 创建集群
kubectl config set-cluster kubernetes \
--certificate-authority=./ca.crt \
--embed-certs=true \
--server=https://apiserver.cluster.local:6443 \
--kubeconfig=kubernetes-admin.conf
# 获取token
SECRET=$(kubectl get secret -n kubernetes-dashboard | grep dashboard-admin | awk '{print $1}')
kubectl describe secret -n kubernetes-dashboard $SECRET
# 创建credentials
kubectl config set-credentials kubernetes-admin \
--token=上一步获取的token \
--kubeconfig=kubernetes-admin.conf
# 创建context
kubectl config set-context kubernetes-admin@kubernetes \
--cluster=kubernetes \
--user=kubernetes-admin \
--kubeconfig=kubernetes-admin.conf
# 切换context的current-context
kubectl config use-context kubernetes-admin@kubernetes --kubeconfig=kubernetes-admin.conf
登录的时候选择刚刚生成的 kubernetes-admin.conf ,可以保存到本地电脑备用
MetalLB 负载均衡
由于我们购买的是特价云服务器,没有负载均衡功能,这里使用免费的 MetalLB 用作负载均衡。参考文档
需要修改一下 kube 配置文件:
kubectl edit configmap -n kube-system kube-proxy
# 修改如下内容,
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
# 修改完更新一下pod
kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
准备 metallb 配置文件下载地址。
# 下载后保存到本地
wget https://raw.githubusercontent.com/metallb/metallb/v0.14.0/config/manifests/metallb-native.yaml
地址池,这里配置的公网IP地址
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: metallb-ippool
namespace: metallb-system
spec:
addresses:
- 公网IP1/32
- 公网IP2/32
- 公网IP3/32
autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: metallb-l2
namespace: metallb-system
spec:
ipAddressPools:
- metallb-ippool
部署命令:
kubectl apply -f metallb-native.yaml
kubectl apply -f metallb-ippool.yaml
# 检查状态
kubectl get all -n metallb-system
kubectl get ipaddresspool -n metallb-system
# 排查日志
kubectl logs deployment/controller -n metallb-system
# 查看哪些ip地址被分配出去了
kubectl get po --all-namespaces -o wide
部署过程报错秘钥不存在,可以手动创建一下:
# 查看创建的密钥
kubectl -n metallb-system get secrets
## 不存在就创建密钥
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
Ingress 控制器
我们想再集群外部访问集群内的服务,需要一个暴露服务的组件,Ingress 控制器就是用来实现这个功能的。
可以通过 Sealos 快速部署一个 Nginx Ingress Controller:
sealos run registry.cn-shanghai.aliyuncs.com/labring/ingress-nginx:v1.9.4-amd64
# 查看 Ingress Controller 服务的状态
kubectl get svc -n ingress-nginx
# 检查类型是否为LoadBalancer(TYPE=LoadBalancer)
kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller
# 查看ingress的外部ip地址(当我们部署metallb之后,会自动分配),用于域名解析
kubectl get svc ingress-nginx-controller -n ingress-nginx
配置tls用于支持https请求,首先准备好CA证书,一般域名服务商会提供免费的。
# 没有CA证书的话可以通过下面命令创建自签CA证书
openssl genrsa -out ingress.key 2048
openssl req -new -key ingress.key -out ingress.csr -subj "/CN=book.wsfss.top"
openssl x509 -req -days 365 -in ingress.csr -signkey ingress.key -out ingress.crt
# 这里我没有使用自签CA,用了腾讯云的。使用命令创建secret,$ kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE} -n ${NAMESPACE}
# 先校验一下证书有效性
openssl x509 -in book.wsfss.top_bundle.crt -text -noout
# 创建secret
kubectl create secret tls book-tls-secret --key book.wsfss.top.key --cert book.wsfss.top_bundle.crt -n prod
配置 Ingress 开启 TLS,一个 Ingress 只能使用一个 secret,也就是说只能用一个证书,或者说如果你在一个 Ingress 中配置了多个域名,那么使用 TLS 的话必须保证证书支持该 Ingress 下所有域名。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mkdocs-ingress
namespace: prod
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false" #不强制使用ssl
spec:
tls:
- hosts:
- book.wsfss.top
secretName: book-tls-secret
rules:
- host: book.wsfss.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mkdocs
port:
name: http
如果访问不了,检查下 ingress-nginx-controller SSL对应的端口是否开放安全组。
域名访问
我们虽然使用了 ingress-nginx 来实现域名解析,但是 ingress-nginx 并没有开放80端口和443端口给外部访问,我们通过nginx来进行一层转发
物理机安装nginx,用来支持域名访问不加端口(这里ingress的外部ip地址对应的机器都要安装)
# 安装nginx
apt install nginx
# 修改nginx配置
vim /etc/nginx/nginx.conf
# 反向代理到ingress-nginx的控制器外部IP地址的80端口和443端口
server {
listen 80;
server_name *.top;
location / {
proxy_pass http://121.37.19.93;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 443 ssl;
server_name *.top;
ssl_certificate /root/cert/book.wsfss.top_bundle.pem; #ssl证书文件
ssl_certificate_key /root/cert/book.wsfss.top.key; #ssl证书文件
location / {
proxy_pass https://121.37.19.93;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# 启动
sudo systemctl start nginx
# 停止
sudo systemctl stop nginx
# 设置开机启动
sudo systemctl enable nginx
# 查看状态
sudo systemctl status nginx
# 重载
sudo nginx -s reload