容器技术
ubuntu使用APT安装docker并指定版本
Helm部署与使用
Helm常用命令
从Helm仓库创建应用流程示例
Helm部署与使用
K8S中部署mysql-ha高可用集群
helm启动mysql-ha
helm几个常用仓库
Kubernetes使用helm部署Mysql-Ha
k8s入门:Helm 构建 MySQL
docker批量修改tag(批量push)
k8s之yaml文件详解
将 MySQL 通过 bitpoke/mysql-operator 部署到 k8s 内部
k8s pvc扩容:pvc创建后扩容
K8S性能分析
部署Metrics Server
Kubernetes集群搭建
kubespray 部署常见问题和优化汇总
kubernetes-sigs/kubespray at release-2.15
K8S-pod配置文件详解
KubeSphere知识库
在 Kubernetes 上最小化安装 KubeSphere
卸载 KubeSphere 和 Kubernetes
KubeSphere 应用商店
修改pod中容器的时区
k8s之Pod安全策略
Harbor 登陆失败,用户名或者密码不正确。405 Not Allowed
Docker-leanote_n1
kubesphere/kubekey
Kubernetes Static Pod (静态Pod)
kubernets kube-proxy的代理 iptables和ipvs - 30岁再次出发 - 博客园
k8s生产实践之获取客户端真实IP - SSgeek - 博客园
kube-proxy ip-tables故障解决
k8s入门:Helm 构建 MySQL
docker批量修改tag(批量push)
prometheus operator 监控redis-exporter
Helm3 安装 ElasticSearch & Kibana 7.x 版本
kubernete强力删除namespace_redis删除namespace命令
EFK (Elasticsearch + Fluentd + Kibana) 日志分析系统
k8s日志收集实战(无坑)
fluentd收集k8s集群pod日志
Elasticsearch+Fluentd+Kibana 日志收集系统的搭建
TKE/EKS之configmap,secret只读挂载
K8s基于Reloader的ConfigMap/Secret热更新
使用 Reloader 实现热部署_k8s reloader
k8s使用Reloader实现更新configmap后自动重启pod
在 Kubernetes 上对 gRPC 服务器进行健康检查 | Kubernetes
Kubernetes ( k8s ) gRPC服务 健康检查 ( livenessProbe ) 与 就绪检查 ( readinessProbe )
排查kubernetes中高磁盘占用pod
helm 安装 MongoDB 集群
helm 安装 Redis 1 主 2 从 3哨兵
【k8s】使用 Reloader 实现热部署
k8s证书过期,更新后kubelet启动失败
kubeadm证书/etcd证书过期处理
三种监控 Kubernetes 集群证书过期方案
K8s 集群(kubeadm) CA 证书过期解决方案
k8s调度、污点、容忍、不可调度、排水、数据卷挂载
5分钟搞懂K8S的污点和容忍度(理论+实战)
Kubernetes进阶-8基于Istio实现微服务治理
macvlan案例配置
快速解决Dockerhub镜像站无法访问问题
info_scan开源漏洞扫描主系统部署
本文档使用 MrDoc 发布
-
+
首页
Kubernetes集群搭建
节点数 >=3台 CPU >=2 Memory >=2G 安全组:关闭(允许节点之间任意端口访问,以及ipip隧道协议通讯) 计划使用阿里云的同学看过来: 多个节点同时购买,同一个账号,同一个地域,同一个可用区,保证内网ip可以联通! ### 1.2. 演示环境说明 我们这里使用的是三台centos 7.5的虚拟机,具体信息如下表: | 系统类型 | IP地址 | 节点角色 | CPU | Memory | Hostname | | --- | --- | --- | --- | --- | --- | | centos-7.5 | 192.168.18.131 | master | \>=2 | \>=2G | node-1 | | centos-7.5 | 192.168.18.132 | master | \>=2 | \>=2G | node-2 | | centos-7.5 | 192.168.18.133 | worker | \>=2 | \>=2G | node-3 |  [设置主机名](https://blog.csdn.net/weixin_40612128/article/details/119008039) [设置静态ip](https://blog.csdn.net/weixin_40612128/article/details/119007776) [关闭防火墙](https://blog.csdn.net/weixin_40612128/article/details/107575374) ## 2\. 系统设置(所有节点) 注意:所有操作使用root用户执行 ### 2.1 主机名 主机名必须合法,并且每个节点都不一样(建议命名规范:数字+字母+中划线组合,不要包含其他特殊字符)。 ``` # 查看主机名 $ hostname # 修改主机名 $ hostnamectl set-hostname <your_hostname> ``` ### 2.2 关闭防火墙、selinux、swap,重置iptables ``` # 关闭selinux $ setenforce 0 $ sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config # 关闭防火墙 $ systemctl stop firewalld && systemctl disable firewalld # 设置iptables规则 $ iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT # 关闭swap $ swapoff -a && free –h # 关闭dnsmasq(否则可能导致容器无法解析域名) $ service dnsmasq stop && systemctl disable dnsmasq ```  ### 2.3 k8s参数设置 ## 制作配置文件 ``` $ cat > /etc/sysctl.d/kubernetes.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_nonlocal_bind = 1 net.ipv4.ip_forward = 1 vm.swappiness = 0 vm.overcommit_memory = 1 EOF # 生效文件 $ sysctl -p /etc/sysctl.d/kubernetes.conf ```  注意,如果这里有报错,输入 ``` modprobe br_netfilter ``` 参见文档: [配置内核参数报sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory](https://blog.csdn.net/weixin_41831919/article/details/108110194)  ### 2.4 移除docker相关软件包(可选) ``` $ yum remove -y docker* $ rm -f /etc/docker/daemon.json ```  ## 3\. 使用kubespray部署集群 这部分只需要在一个 操作 节点执行,可以是集群中的一个节点,也可以是集群之外的节点。甚至可以是你自己的笔记本电脑。我们这里使用更普遍的集群中的任意一个linux节点。 ### 3.1 配置免密 使 操作 节点可以免密登录到所有节点 ``` # 1. 生成keygen(执行ssh-keygen,一路回车下去) $ ssh-keygen # 2. 查看并复制生成的pubkey $ cat /root/.ssh/id_rsa.pub # 3. 分别登陆到每个节点上,将pubkey写入/root/.ssh/authorized_keys $ mkdir -p /root/.ssh $ echo "<上一步骤复制的pubkey>" >> /root/.ssh/authorized_keys ``` 我这里在node-1上进行操作。    进行免登陆测试,在node-1上进行登录node-2和node-3  ### 3.2 依赖软件下载、安装 这个也只要在操作节点执行,这里我在node-1操作。 ``` # 安装基础软件 $ yum install -y epel-release python36 python36-pip git # 下载kubespray源码 $ wget https://github.com/kubernetes-sigs/kubespray/archive/v2.15.0.tar.gz # 解压缩 $ tar -xvf v2.15.0.tar.gz && cd kubespray-2.15.0 # 安装requirements $ cat requirements.txt $ pip3.6 install -r requirements.txt ## 如果install遇到问题可以先尝试升级pip ## $ pip3.6 install --upgrade pip ```      这里报错,升级下pip ``` pip3.6 install --upgrade pip ``` 然后重新执行 ``` pip3.6 install -r requirements.txt ```  这样好了。 ### 3.3 生成配置 ``` 项目中有一个目录是集群的基础配置,示例配置在目录inventory/sample中,我们复制一份出来作为自己集群的配置 # copy一份demo配置,准备自定义 $ cp -rpf inventory/sample inventory/mycluster 由于kubespray给我们准备了py脚本,可以直接根据环境变量自动生成配置文件,所以我们现在只需要设定好环境变量就可以啦 # 使用真实的hostname(否则会自动把你的hostname改成node1/node2...这种哦) $ export USE_REAL_HOSTNAME=true # 指定配置文件位置 $ export CONFIG_FILE=inventory/mycluster/hosts.yaml # 定义ip列表(你的服务器内网ip地址列表,3台及以上,前两台默认为master节点) $ declare -a IPS=(192.168.18.131 192.168.18.132 192.168.18.133) # 生成配置文件 $ python3 contrib/inventory_builder/inventory.py ${IPS[@]} ``` 注意,这里的ip改成自己的ip  ### 3.4 个性化配置 ``` 配置文件都生成好了,虽然可以直接用,但并不能完全满足大家的个性化需求,比如用docker还是containerd?docker的工作目录是否用默认的/var/lib/docker?等等。当然默认的情况kubespray还会到google的官方仓库下载镜像、二进制文件,这个就需要你的服务器可以上外面的网,想上外网也需要修改一些配置。 # 定制化配置文件 # 1. 节点组织配置(这里可以调整每个节点的角色) $ vi inventory/mycluster/hosts.yaml # 2. containerd配置(教程使用containerd作为容器引擎) $ vi inventory/mycluster/group_vars/all/containerd.yml # 3. 全局配置(可以在这配置http(s)代理实现外网访问) $ vi inventory/mycluster/group_vars/all/all.yml # 4. k8s集群配置(包括设置容器运行时、svc网段、pod网段等) $ vi inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml # 5. 修改etcd部署类型为host(默认是docker) $ vi ./inventory/mycluster/group_vars/etcd.yml # 6. 附加组件(ingress、dashboard等) $ vi ./inventory/mycluster/group_vars/k8s-cluster/addons.yml ``` 配置文件内容: 1.节点组织配置(这里可以调整每个节点的角色) ``` vi inventory/mycluster/hosts.yaml ```  1. containerd配置(教程使用containerd作为容器引擎) vi inventory/mycluster/group\_vars/all/containerd.yml  1. 全局配置(可以在这配置http(s)代理实现外网访问) vi inventory/mycluster/group\_vars/all/all.yml 配置代理  1. k8s集群配置(包括设置容器运行时、svc网段、pod网段等) ``` vi inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml ```  修改地址  修改为containerd  5 修改etcd部署类型为host(默认是docker) ``` vi ./inventory/mycluster/group_vars/etcd.yml ```  6 附加组件(ingress、dashboard等) ``` vi ./inventory/mycluster/group_vars/k8s-cluster/addons.yml ```  打开darshboard  使用ingress\_nginx  ### 3.5 一键部署 配置文件都调整好了后,就可以开始一键部署啦,不过部署过程不出意外会非常慢。 如果您使用的是教程同一个版本建议下使用网盘下载好二进制文件和镜像 网盘下载二进制(可选) ``` 链接: https://pan.baidu.com/s/11eDin8BDJVzGgXJW9e6cog 提取码: mrj9 ``` 下载好之后解压到每个节点的根目录即可,解压完成后的目录是/tmp/releases  ``` cd / tar -zxvf kubespray-k8s-releases-v2.15.0.tar.gz ```  注意,开始一键部署之前更新下yum,这个不要忘记了!! ``` sudo yum -y update ``` 一键部署 ``` # -vvvv会打印最详细的日志信息,建议开启 $ ansible-playbook -i inventory/mycluster/hosts.yaml -b cluster.yml -vvvv ```  经过漫长的等待后,如果没有问题,整个集群都部署起来啦。   下载镜像(可选) 为了减少“一键部署”的等待时间,可以在部署的同时,预先下载一些镜像。 ``` $ curl https://gitee.com/pa/pub-doc/raw/master/kubespray-v2.15.0-images.sh|bash -x ``` 重要:此操作需要确保上面的"一键部署"执行后,并成功安装了containerd后即可手动下载镜像)    最后差不多1小时左右就下载好了。    ### 3.6 清理代理设置 清理代理设置(运行时不再需要代理,删掉代理配置即可) 删除docker的http代理(在每个节点执行) ``` $ rm -f /etc/systemd/system/containerd.service.d/http-proxy.conf $ systemctl daemon-reload $ systemctl restart containerd ```  删除yum代理 ``` # 把grep出来的代理配置手动删除即可 $ grep 8118 -r /etc/yum* ``` 注意,这里的/etc/yum.conf是要使用vim打开删除红色框或者注释掉。   ### 3.7 安装完查看下各种资源 #### (1)获取命名空间 ``` kubectl get ns ```  注意,这里遇到一个问题,就是输入命令后报错,如下:  解决办法,取消代理,每个节点都要执行一下。 ``` unset http_proxy unset https_proxy ``` #### (2)获取命名空间下资源 ``` # 默认命名空间 kubectl get all kubectl get all -n ingress-nginx kubectl get all -n kube-node-lease kubectl get all -n kube-public kubectl get all -n kube-system ```       #### (3)我们发现在执行 kubectl get all -n kube-system,有一个niginx-proxy-node-3 ``` kubectl get all -n kube-system ```  去node3查一下: ``` crictl ps ```  来验证一下这个node3上的这个nginx\_proxy是哪里来的,应该是单独启的一个pod node3上查看 ``` cat /etc/kubernetes/manifests/nginx-proxy.yml ```  node3上挂载的nginx的配置文件 ``` cat /etc/nginx/nginx.conf ```  为了实现高可用和负载均衡,只有node3是一个单纯的worker节点,其他2个节点是主节点,6443已经占用了,不会再启动nginx了。 ## 二、集群冒烟测试 ## 1\. 创建nginx ds ``` # 写入配置 cat > nginx-ds.yml <<EOF apiVersion: v1 kind: Service metadata: name: nginx-ds labels: app: nginx-ds spec: type: NodePort selector: app: nginx-ds ports: - name: http port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ds spec: selector: matchLabels: app: nginx-ds template: metadata: labels: app: nginx-ds spec: containers: - name: my-nginx image: nginx:1.19 ports: - containerPort: 80 EOF # 创建ds kubectl apply -f nginx-ds.yml ```  ## 2\. 检查各种ip连通性 ``` # 检查各 Node 上的 Pod IP 连通性 $ kubectl get pods -o wide # 在每个节点上ping pod ip $ ping <pod-ip> # 检查service可达性 $ kubectl get svc # 在每个节点上访问服务 $ curl <service-ip>:<port> # 在每个节点检查node-port可用性 $ curl <node-ip>:<port> ```        ## 3\. 检查dns可用性 ``` # 创建一个nginx pod $ cat > pod-nginx.yaml <<EOF apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: docker.io/library/nginx:1.19 ports: - containerPort: 80 EOF # 创建pod $ kubectl apply -f pod-nginx.yaml # 进入pod,查看dns $ kubectl exec nginx -it -- /bin/bash # 查看dns配置 root@nginx:/# cat /etc/resolv.conf # 查看名字是否可以正确解析 root@nginx:/# ping nginx-ds ```   ## 4\. 日志功能 测试使用kubectl查看pod的容器日志 ``` $ kubectl get pods $ kubectl logs <pod-name> ```  ## 5\. Exec功能 测试kubectl的exec功能 ``` $ kubectl get pods -l app=nginx-ds $ kubectl exec -it <nginx-pod-name> -- nginx -v ```  ## 三、 访问dashboard ## 1\. 创建service ``` $ cat > dashboard-svc.yaml <<EOF apiVersion: v1 kind: Service metadata: namespace: kube-system name: dashboard labels: app: dashboard spec: type: NodePort selector: k8s-app: kubernetes-dashboard ports: - name: https nodePort: 30000 port: 443 targetPort: 8443 EOF $ kubectl apply -f dashboard-svc.yaml ``` ## 2\. 访问dashboard ``` https://192.168.18.131:30000/ ``` 为了集群安全,从 1.7 开始,dashboard 只允许通过 https 访问,我们使用nodeport的方式暴露服务,可以使用 https://NodeIP:NodePort 地址访问 关于自定义证书 默认dashboard的证书是自动生成的,肯定是非安全的证书,如果大家有域名和对应的安全证书可以自己替换掉。使用安全的域名方式访问dashboard。 在dashboard-all.yaml中增加dashboard启动参数,可以指定证书文件,其中证书文件是通过secret注进来的。 ``` - –tls-cert-file - dashboard.cer - –tls-key-file - dashboard.key ```  ## 3\. 登录dashboard Dashboard 默认只支持 token 认证,所以如果使用 KubeConfig 文件,需要在该文件中指定 token,我们这里使用token的方式登录 ``` # 创建service account $ kubectl create sa dashboard-admin -n kube-system # 创建角色绑定关系 $ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin # 查看dashboard-admin的secret名字 $ ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}') # 打印secret的token $ kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}' ```  生成的token: ``` eyJhbGciOiJSUzI1NiIsImtpZCI6IlhLS21FX2tOaHJJdzN3ZGx3YjhMcFNrS0EwWVNTUmJrWWtOSnhfanBGcGcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tOTc2eGIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiOGU0MzU4ZmEtMDExZS00Zjc2LTgwNWEtODdkNDQ5ZWRlZWM2Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.ogAibpox4FT6JLJVfRbJMamG_mygGk10OiwQR4orazc2amVuJrvowuM-FDp8FtA-XRuKr1zcU6VerCEf1Aklt-ilP2yZWp9sShLifNEBg04H0RiWV4gj61f3wwjzz2OFGDzY1JWB-Y1BQjxKS4D8hGC8ZogEqF28xbK27JGZQUtX4NMgl95LsGAwmBtXBrSWKnXAmdtUNhaaqwiWTTHPvqJxSrk_LsKdbG5L0X4E9Mx8Wl3d_NaRkHY50oCFdUpQm8FxH7D1DUhJC6FfMOahJ216kWgJ0lMdtdcMakflgZrlxnTy6QtaOYXhfxiOdcFVzNFQx0RyAAmf8JKXGHXpOQ ``` 进行登录  登录进来了  查看Pods  查看其中一个  查看日志  下载日志  进入命令行   进行编辑   可以进行删除  ## 四、集群运维 ## 1\. Master节点 ### 增加master节点 ``` # 1.编辑hosts.yaml,增加master节点配置 $ vi inventory/mycluster/hosts.yaml # 2.执行cluster.yml(不要用scale.yml) $ ansible-playbook -i inventory/mycluster/hosts.yaml cluster.yml -b -v # 3.重启nginx-proxy - 在所有节点执行下面命令重启nginx-proxy $ docker ps | grep k8s_nginx-proxy_nginx-proxy | awk '{print $1}' | xargs docker restart ``` ### 删除master节点 如果你要删除的是配置文件中第一个节点,需要先调整配置,将第一行配置下移,再重新运行cluster.yml,使其变成非第一行配置。举例如下: ``` # 场景:下线node-1节点 $ vi inventory/mycluster/hosts.yaml # 变更前的配置 children: kube-master: hosts: node-1: node-2: node-3: # 变更后的配置 children: kube-master: hosts: node-2: node-1: node-3: # 再执行一次cluster.yml $ ansible-playbook -i inventory/mycluster/hosts.yaml -b cluster.yml ``` 非第一行的master节点下线流程: ``` # 执行remove-node.yml(不要在hosts.yaml中删除要下线的节点) $ ansible-playbook -i inventory/mycluster/hosts.yaml remove-node.yml -b -v -e "node=NODE-NAME" # 同步hosts.yaml(编辑hosts.yaml将下线的节点删除,保持集群状态和配置文件的一致性) $ vi inventory/mycluster/hosts.yaml ``` ## 2\. Worker节点 ### 增加worker节点 ``` # 刷新缓存 $ ansible-playbook -i inventory/mycluster/hosts.yaml facts.yml -b -v # 修改配置hosts.yaml,增加节点 $ vi inventory/mycluster/hosts.yaml # 执行scale添加节点,--limit限制只在某个固定节点执行 $ ansible-playbook -i inventory/mycluster/hosts.yaml scale.yml --limit=NODE-NAME -b -v ``` ### 删除worker节点 ``` # 此命令可以下线节点,不影响其他正在运行中的节点,并清理节点上所有的容器以及kubelet,恢复初始状态,多个节点逗号分隔 $ ansible-playbook -i inventory/mycluster/hosts.yaml remove-node.yml -b -v -e "node=NODE-NAME-1,NODE-NAME-2,..." # 同步hosts.yaml(编辑hosts.yaml将下线的节点删除,保持集群状态和配置文件的一致性) $ vi inventory/mycluster/hosts.yaml ``` ## 3\. ETCD节点 如果要变更的etcd节点同时也是master或worker节点,需要先将master/worker节点按照前面的文档操作下线,保留纯粹的etcd节点 ### 增加etcd节点 ``` # 编辑hosts.yaml(可以增加1个或2个etcd节点配置) $ vi inventory/mycluster/hosts.yaml # 更新etcd集群 $ ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml --limit=etcd,kube-master -e ignore_assert_errors=yes -e etcd_retries=10 ``` ### 删除etcd节点 ``` # 执行remove-node.yml(不要在hosts.yaml中删除要下线的节点) $ ansible-playbook -i inventory/mycluster/hosts.yaml remove-node.yml -b -v -e "node=NODE-NAME" # 同步hosts.yaml(编辑hosts.yaml将下线的节点删除,保持集群状态和配置文件的一致性) $ vi inventory/mycluster/hosts.yaml # 运行cluster.yml给node节点重新生成etcd节点相关的配置 $ ansible-playbook -i inventory/mycluster/hosts.yaml -b cluster.yml ``` ## 4\. 其他常用命令 ### 集群reset ``` # 运行reset.yml一键清理集群 $ ansible-playbook -i inventory/mycluster/hosts.yaml -b -v reset.yml ``` ### 自定义play起始点 当我们执行play的过程中如果有问题,需要重新的时候,如果重新执行指令会重新经历前面漫长的等待,这个时候“跳过”功能就显得非常有用 ``` # 通过--start-at-task指定从哪个task处开始执行,会跳过前面的任务,举例如下 $ ansible-playbook --start-at-task="reset | gather mounted kubelet dirs" ``` ### 忽略错误 当有些错误是我们确认可以接受的或误报的,可以配置ignore\_errors: true,避免task出现错误后影响整个流程的执行。 ``` # 示例片段如下: - name: "Remove physical volume from cluster disks." environment: PATH: "{{ ansible_env.PATH }}:/sbin" become: true command: "pvremove {{ disk_volume_device_1 }} --yes" ignore_errors: true ```
adouk
2023年2月12日 23:45
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码