kubeadm搭建kubernetes(k8s)

kubeadm搭建kubernetes(k8s)

一、环境准备

节点 IP 安装软件
master(2C/4G,cpu核心数要求大于2) 192.168.174.15 docker、kubeadm、kubelet、kubectl、flannel
node01(2C/2G) 192.168.174.18 docker、kubeadm、kubelet、kubectl、flannel
node02(2C/2G) 192.168.174.19 docker、kubeadm、kubelet、kubectl、flannel
Harbor节点(hub.exo.com 192.168.174.16 docker、docker-compose、harbor-offline-v1.2.2

1.所有节点,关闭防火墙规则,关闭selinux,关闭swap交换

复制代码
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
swapoff -a						#交换分区必须要关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab		#永久关闭swap分区,&符号在sed命令中代表上次匹配的结果
#加载 ip_vs 模块
for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done

2.修改主机名

复制代码
hostnamectl set-hostname master01
hostnamectl set-hostname node01
hostnamectl set-hostname node02

3.所有节点修改hosts文件

复制代码
vim /etc/hosts
192.168.174.15 master01
192.168.174.18 node01
192.168.174.19 node02

4.调整内核参数

复制代码
cat > /etc/sysctl.d/kubernetes.conf << EOF
#开启网桥模式,可将网桥的流量传递给iptables链
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
#关闭ipv6协议
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
EOF

5.生效参数

复制代码
sysctl --system  

二、 安装软件

1.所有节点安装docker

复制代码
yum install -y yum-utils device-mapper-persistent-data lvm2 
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
yum install -y docker-ce docker-ce-cli containerd.io
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  }
}
EOF
#使用Systemd管理的Cgroup来进行资源控制与管理,因为相对Cgroupfs而言,Systemd限制CPU、内存等资源更加简单和成熟稳定。
#日志使用json-file格式类型存储,大小为100M,保存在/var/log/containers目录下,方便ELK等日志系统收集和管理日志。
systemctl daemon-reload
systemctl restart docker.service
systemctl enable docker.service 

docker info | grep "Cgroup Driver"

2.所有节点安装kubeadm,kubelet和kubectl

(1)定义kubernetes源

复制代码
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

yum install -y kubelet-1.20.11 kubeadm-1.20.11 kubectl-1.20.11

(2)开机自启kubelet

复制代码
systemctl enable kubelet.service
#K8S通过kubeadm安装出来以后都是以Pod方式存在,即底层是以容器方式运行,所以kubelet必须设置开机自启

三、部署K8S集群

1.查看初始化需要的镜像

复制代码
kubeadm config images list

(1)在 master 节点上传 v1.20.11.zip压缩包至 /opt 目录

复制代码
unzip v1.20.11.zip -d /opt/k8s
cd /opt/k8s/v1.20.11
for i in $(ls *.tar); do docker load -i $i; done

(2)复制镜像和脚本到 node 节点,并在 node 节点上执行脚本加载镜像文件

复制代码
scp -r /opt/k8s root@192.168.174.18:/opt
scp -r /opt/k8s root@192.168.174.19:/opt
cd /opt/k8s/v1.20.11
for i in $(ls *.tar); do docker load -i $i; done

(3)初始化kubeadm

复制代码
方法一:
kubeadm config print init-defaults > /opt/kubeadm-config.yaml

cd /opt/
vim kubeadm-config.yaml
......
11 localAPIEndpoint:
12   advertiseAddress: 192.168.174.15		#指定master节点的IP地址
13   bindPort: 6443
......
34 kubernetesVersion: v1.20.11				#指定kubernetes版本号
35 networking:
36   dnsDomain: cluster.local
37   podSubnet: "10.244.0.0/16"				#指定pod网段,10.244.0.0/16用于匹配flannel默认网段
38   serviceSubnet: 10.96.0.0/16			#指定service网段
39 scheduler: {}

#末尾再添加以下内容
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs									#把默认的kube-proxy调度方式改为ipvs模式

kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log
#--experimental-upload-certs 参数可以在后续执行加入节点时自动分发证书文件,K8S V1.16版本开始替换为 --upload-certs
#tee kubeadm-init.log 用以输出日志

2.查看 kubeadm-init 日志

复制代码
less kubeadm-init.log

kubernetes配置文件目录
ls /etc/kubernetes/

//存放ca等证书和密码的目录
ls /etc/kubernetes/pki

方法二:

复制代码
kubeadm init \
--apiserver-advertise-address=192.168.174.15 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.20.11 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16 \

--token-ttl=0

初始化集群需使用kubeadm init命令,可以指定具体参数初始化,也可以指定配置文件初始化。
可选参数:
--apiserver-advertise-address:apiserver通告给其他组件的IP地址,一般应该为Master节点的用于集群内部通信的IP地址,0.0.0.0表示节点上所有可用地址
--apiserver-bind-port:apiserver的监听端口,默认是6443
--cert-dir:通讯的ssl证书文件,默认/etc/kubernetes/pki
--control-plane-endpoint:控制台平面的共享终端,可以是负载均衡的ip地址或者dns域名,高可用集群时需要添加
--image-repository:拉取镜像的镜像仓库,默认是k8s.gcr.io
--kubernetes-version:指定kubernetes版本
--pod-network-cidr:pod资源的网段,需与pod网络插件的值设置一致。Flannel网络插件的默认为10.244.0.0/16,Calico插件的默认值为192.168.0.0/16;
--service-cidr:service资源的网段
--service-dns-domain:service全域名的后缀,默认是cluster.local

--token-ttl:默认token的有效期为24小时,如果不想过期,可以加上 --token-ttl=0 这个参数

方法二初始化后需要修改 kube-proxy 的 configmap,开启 ipvs
kubectl edit cm kube-proxy -n=kube-system
修改mode: ipvs

3.设定kubectl

kubectl需经由API server认证及授权后方能执行相应的管理操作,kubeadm 部署的集群为其生成了一个具有管理员权限的认证配置文件 /etc/kubernetes/admin.conf,它可由 kubectl 通过默认的 "$HOME/.kube/config" 的路径进行加载。

复制代码
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

(1)如果 kubectl get cs 发现集群不健康,更改以下两个文件

复制代码
vim /etc/kubernetes/manifests/kube-scheduler.yaml 
vim /etc/kubernetes/manifests/kube-controller-manager.yaml

修改如下内容

把--bind-address=127.0.0.1变成--bind-address=192.168.174.15		#修改成k8s的控制节点master01的ip
把httpGet:字段下的hosts由127.0.0.1变成192.168.174.15(有两处)
#- --port=0					# 搜索port=0,把这一行注释掉

systemctl restart kubelet

4.所有节点部署网络插件flannel

方法一:

(1)所有节点上传flannel镜像 flannel.tar 到 /opt 目录,master节点上传 kube-flannel.yml 文件

复制代码
cd /opt
unzip kuadmin-flannel.zip
docker load -i flannel-cni-v1.2.0.tar 
docker load -i flannel-v0.22.2.tar
mv cni cni_bak
mkdir cni/bin -p
tar zxvf cni-plugins-linux-amd64-v1.2.0.tgz -C cni/bin
ll cni/bin

(2)在 master 节点创建 flannel 资源

复制代码
kubectl apply -f kube-flannel.yml 

方法二:

复制代码
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

5.在 node 节点上执行 kubeadm join 命令加入群集

复制代码
kubeadm join 192.168.174.15:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:c93b6ce2fe56803f792c49da16d0faf04c001f93c8ee8abd24a5fb344474b50c 

6.在master节点查看节点状态

复制代码
kubectl get nodes

kubectl get pods -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-bccdc95cf-c9w6l          1/1     Running   0          71m
coredns-bccdc95cf-nql5j          1/1     Running   0          71m
etcd-master                      1/1     Running   0          71m
kube-apiserver-master            1/1     Running   0          70m
kube-controller-manager-master   1/1     Running   0          70m
kube-flannel-ds-amd64-kfhwf      1/1     Running   0          2m53s
kube-flannel-ds-amd64-qkdfh      1/1     Running   0          46m
kube-flannel-ds-amd64-vffxv      1/1     Running   0          2m56s
kube-proxy-558p8                 1/1     Running   0          2m53s
kube-proxy-nwd7g                 1/1     Running   0          2m56s
kube-proxy-qpz8t                 1/1     Running   0          71m
kube-scheduler-master            1/1     Running   0          70m
  • 报错:
  • 解决方案:

(1)查看所有的机器防火墙等是否关闭

(2)执行:

复制代码
kubectl delete -f kube-flannel.yml
kubectl apply -f kube-flannel.yml

(3)执行后需等待可再次查看状态

复制代码
kubectl get pods -n kube-flannel

7.测试 pod 资源创建

复制代码
kubectl create deployment nginx --image=nginx

kubectl get pods -o wide
NAME                     READY   STATUS              RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
nginx-6799fc88d8-4bplj   0/1     ContainerCreating   0          6s    <none>   node02   <none>           <none>

8.暴露端口提供服务

复制代码
kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        56m
nginx        NodePort    10.96.173.35   <none>        80:30291/TCP   19s

9.测试访问

curl http://192.168.174.18:30291

10.扩展3个副本

复制代码
kubectl scale deployment nginx --replicas=3
kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
nginx-6799fc88d8-4bplj   1/1     Running   0          5m15s   10.244.2.2   node02   <none>           <none>
nginx-6799fc88d8-kn9cc   1/1     Running   0          19s     10.244.2.4   node02   <none>           <none>
nginx-6799fc88d8-z6r42   1/1     Running   0          19s     10.244.2.3   node02   <none>           <none>

四、部署 Dashboard

1.在 master01 节点上操作

复制代码
#上传 recommended.yaml 文件到 /opt/k8s 目录中
cd /opt/k8s
vim recommended.yaml
#默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001     #添加
  type: NodePort          #添加
  selector:
    k8s-app: kubernetes-dashboard
	
kubectl apply -f recommended.yaml

2.创建service account并绑定默认cluster-admin管理员集群角色

复制代码
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

3.使用输出的token登录Dashboard

复制代码
https://192.168.174.18:30001

(1)空敲this is unsafe (不用空格),回车即可,选择token输入查到的token登录即可

五、安装Harbor私有仓库

1.修改主机名

复制代码
hostnamectl set-hostname hub.exo.com

2.所有节点加上主机名映射

复制代码
echo '192.168.174.16 hub.exo.com' >> /etc/hosts

3.安装 docker

复制代码
yum install -y yum-utils device-mapper-persistent-data lvm2 
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
yum install -y docker-ce docker-ce-cli containerd.io

mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "insecure-registries": ["https://hub.exo.com"]
}
EOF

systemctl start docker
systemctl enable docker

4.所有 node 节点都修改 docker 配置文件,加上私有仓库配置

复制代码
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "insecure-registries": ["https://hub.exo.com"]
}
EOF

systemctl daemon-reload
systemctl restart docker

5.安装 Harbor

(1)上传 harbor-offline-installer-v1.2.2.tgz 和 docker-compose 文件到 /opt 目录

复制代码
cd /opt
cp docker-compose /usr/local/bin/
chmod +x /usr/local/bin/docker-compose

tar zxvf harbor-offline-installer-v1.2.2.tgz
cd harbor/
vim harbor.cfg
5  hostname = hub.exo.com
9  ui_url_protocol = https
24 ssl_cert = /data/cert/server.crt
25 ssl_cert_key = /data/cert/server.key
59 harbor_admin_password = Harbor12345

(2)生成证书

复制代码
mkdir -p /data/cert
cd /data/cert
#生成私钥
openssl genrsa -des3 -out server.key 2048
输入两遍密码:123456

#生成证书签名请求文件
openssl req -new -key server.key -out server.csr
输入私钥密码:123456
输入国家名:cn
输入省名:js
输入市名:nj
输入组织名:exo
输入机构名:exo
输入域名:hub.exo.com
输入管理员邮箱:admin@exo.com
其它全部直接回车

#备份私钥
cp server.key server.key.org

#清除私钥密码
openssl rsa -in server.key.org -out server.key
输入私钥密码:123456

#签名证书
openssl x509 -req -days 1000 -in server.csr -signkey server.key -out server.crt

chmod +x /data/cert/*

cd /opt/harbor/
./install.sh

6.测试

在本地使用火狐浏览器访问:https://hub.exo.com

添加例外 -> 确认安全例外

用户名:admin

密码:Harbor12345

7.在一个node节点上登录harbor

复制代码
docker login -u admin -p Harbor12345 https://hub.exo.com

(1)上传镜像

复制代码
docker pull nginx
docker tag nginx:latest hub.exo.com/library/nginx:v1
docker push hub.exo.com/library/nginx:v1

(2)在master节点上删除之前创建的nginx资源

复制代码
kubectl delete deployment nginx

kubectl create deployment nginx-deployment --image=hub.exo.com/library/nginx:v1 --port=80 --replicas=3

kubectl expose deployment nginx-deployment --port=30000 --target-port=80

kubectl get svc,pods
NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP        163m
service/nginx              NodePort    10.96.173.35    <none>        80:30291/TCP   106m
service/nginx-deployment   ClusterIP   10.96.134.133   <none>        30000/TCP      18s

NAME                                    READY   STATUS             RESTARTS   AGE
pod/nginx-deployment-6ff97578b8-2d4z6   0/1     ImagePullBackOff   0          24s
pod/nginx-deployment-6ff97578b8-g8z8k   0/1     ImagePullBackOff   0          24s
pod/nginx-deployment-6ff97578b8-xwgbw   0/1     ImagePullBackOff   0          24s



yum install ipvsadm -y
ipvsadm -Ln

curl 10.96.134.133:30000



kubectl edit svc nginx-deployment
25   type: NodePort						#把调度策略改成NodePort

kubectl get svc
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP           172m
nginx              NodePort    10.96.173.35    <none>        80:30291/TCP      116m
nginx-deployment   NodePort    10.96.134.133   <none>        30000:32070/TCP   9m59s

(3)浏览器访问:

复制代码
192.168.174.15:32070
192.168.174.18:32070
192.168.174.19:32070

8.将cluster-admin角色权限授予用户system:anonymous

复制代码
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

9.内核参数优化方案

复制代码
cat > /etc/sysctl.d/kubernetes.conf <<EOF
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									#禁止使用 swap 空间,只有当系统内存不足(OOM)时才允许使用它
vm.overcommit_memory=1							#不检查物理内存是否够用
vm.panic_on_oom=0								#开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963							#指定最大文件句柄数
fs.nr_open=52706963								#仅4.4以上版本支持
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
相关推荐
这就是佬们吗几秒前
初识 docker [上]
java·开发语言·笔记·docker·容器
FJW0208141 小时前
负载均衡集群HAproxy
linux·服务器·云原生·负载均衡
BigBigHang1 小时前
【docker】DM8达梦数据库的docker-compose以及一些启动踩坑
数据库·docker·容器
云道轩1 小时前
使用Docker在Rocky Linux 9.5上在线部署LangFlow
linux·人工智能·docker·容器·langflow
伟大的大威1 小时前
Docker 部署 Supabase并连接
运维·docker·容器
杰克逊的日记2 小时前
k8s的csi对接GPFS
云原生·容器·kubernetes·存储·gpfs
岚天start2 小时前
云服务器以域名形式访问机房Kubernetes集群服务之解决方案
nginx·docker·kubernetes·kubesphere·解决方案·云服务器·机房
容器魔方6 小时前
「中科类脑」正式加入 Karmada 用户组!携手社区共建多集群生态
云原生·容器·云计算
终端行者6 小时前
k8s之ingress定义https访问方式
容器·https·kubernetes
小醉你真好6 小时前
7、Docker 常用命令大全
docker·容器·eureka