Kubernetes---通过ansible自动化快速部署k8s集群

Kubernetes-通过ansible自动化快速部署k8s集群


一、安装ansible

使用官方epel源

yum install -y epel-release

使用阿里源

cat >/etc/yum.repos.d/epel-7.repo<<EOF
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=http://mirrors.aliyun.com/epel/7/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
baseurl=http://mirrors.aliyun.com/epel/7/$basearch/debug
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=0

[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
baseurl=http://mirrors.aliyun.com/epel/7/SRPMS
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=0
EOF

安装ansible

yum -y install ansible

二、环境准备

此次使用三台虚拟机,每台配置最低2cpu,2G内存。
一台做k8s-master,两台做k8s-node1、k8s-node2。
三台虚拟机均需安装ansible。

1.添加本地解析,修改hostname。

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.76.100 master
192.168.76.101 node1
192.168.76.102 node2
[root@master /]# cat /etc/hostname
master

[root@master /]# echo "master" > /proc/sys/kernel/hostname #将hostname写入内核进行修改

exit后重新登录,修改成功。

2.配置ansible主机清单,发送公钥

[root@master /]# cd /etc/ansible/
[root@master ansible]# cat hosts.ini
[k8s-master]
master

[k8s-nodes]
node1
node2

[k8s]

[k8s:children]
k8s-master
k8s-nodes
[root@master ansible]# cat hosts.yml
---
- name: 同步所有节点的 /etc/hosts 文件 并且设置主机名
  hosts: k8s
  gather_facts: no
  tasks:
    - name: 同步 hosts 文件
      copy: src=/etc/hosts dest=/etc/hosts
    - name: 设置各自的主机名
      shell:
        cmd: hostnamectl set-hostname "{{ inventory_hostname }}"
      register: sethostname
    - name: 验证是否成功设置了主机名
      debug: var=sethostname.rc
...
[root@master ansible]# cat send-pubkey.yml
- hosts: all
  gather_facts: no
  remote_user: root
  vars:
    ansible_ssh_pass: 123
  tasks:
  - name: Set authorized key taken from file
    authorized_key:
      user: root
      state: present
      key: "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"

执行ansible指令

[root@master ansible]# ansible-playbook -i hosts.ini hosts.yml

在这里插入图片描述

[root@master ansible]# ansible-playbook -i hosts.ini send-pubkey.yml

在这里插入图片描述

3.系统环境设置

[root@master ansible]# cat environment.yml
---
- name: 开始部署集群之前的检查和设置
  hosts: k8s
  gather_facts: no
  tasks:
    - name: 配置禁用 SELinux 和 firewalld
      shell: |
        systemctl stop firewalld
        systemctl disable firewalld
        setenforce 0;
        sed -ri '/^SELINUX=/ c SELINUX=disabled' /etc/selinux/config
      tags:
        - swap

    - name: 关闭交互分区
      shell:
        cmd: swapoff -a; sed -ri 's/.*swap.*/#&/g' /etc/fstab
        warn: no
      tags:
        - swap

    - name: 创建模块配置文件 /etc/modules-load.d/k8s.conf
      blockinfile:
        path: /etc/modules-load.d/k8s.conf
        create: yes
        block: |
          br_netfilter
          ip_vs
          ip_vs_rr
          ip_vs_wrr
          ip_vs_sh
          nf_conntrack_ipv4

    - name: 确保节点上的 iptables 能够正确地查看桥接流量
      blockinfile:
        path: /etc/sysctl.d/k8s.conf
        create: yes
        block: |
          net.bridge.bridge-nf-call-ip6tables = 1
          net.bridge.bridge-nf-call-iptables = 1
          net.ipv4.ip_forward = 1

    - name: 执行加载模块的命令
      shell: modprobe br_netfilter

    - name: 对时
      shell: ntpdate cn.pool.ntp.org

    - name: 检查 SELinux and Swap
      shell: |
        hostname > /tmp/host-info;
        getenforce >> /tmp/host-info;
        free -m |grep 'Swap' >> /tmp/host-info;
        lsmod | grep br_netfilter >> /tmp/host-info;
        sysctl --system |grep 'k8s.conf' -A 2 >> /tmp/host-info;

    - name: 获取 mac 信息并写入信息文件
      shell: |
        host=$(hostname);
        ip link |
        awk -v host=$host '/link\/ether/ {print $2, host}' >> /tmp/host-info ;
        echo "---------------------------" >> /tmp/host-info

    - name: 获取比对报告
      fetch:
        src: /tmp/host-info
        dest: ./
...

执行指令

[root@master ansible]# ansible-playbook -i hosts.ini environment.yml

在这里插入图片描述


在这里插入图片描述

4.检查端口

[root@master ansible]# cat check-port.yml
- hosts: k8s
  gather_facts: no
  tasks:
    - name: hello
      script: ./check-port.py
      register: ret
    - debug: var=item
      loop: "{{ ret.stdout_lines }}"
[root@master ansible]# cat check-port.py
#!/bin/env python
#coding:utf-8
import re
import subprocess
import socket

hostname = socket.gethostname()

ports_set = set()
if 'master' in hostname:
    check_ports = {"6443", "10250", "10251", "102502", "2379", "2380"}
else:
    check_ports = {str(i) for i in xrange(30000, 32768) }
    check_ports.add("10250")

r = subprocess.Popen("ss -nta", stdout=subprocess.PIPE,shell=True)
result = r.stdout.read()

for line in result.splitlines():
        if re.match('^(ESTAB|LISTEN|SYN-SENT)', line):
            line = line.split()[3]
            port = line.split(':')[-1]
            ports_set.add(port)

used_ports = check_ports & ports_set
used_ports = ' '.join(used_ports)
if used_ports:
        print("这些端口已使用: %s" % used_ports)
else:
        print("端口未占用")
[root@master ansible]# ansible-playbook -i hosts.ini check-port.yml

在这里插入图片描述

三、部署docker

[root@master ansible]# cat deploy-docker.yml
- name: deploy docker
  hosts: k8s
  gather_facts: no
  vars:
    pkgs_dir: /docker-pkg
    pkgs:
      - device-mapper-persistent-data
      - lvm2
      - docker-ce
      - docker-ce-cli
      - containerd.io

    #变量 download_host 需要手动设置
    #且值需要是此 playbook 目标主机中的一个
    #需要写在 inventory 文件中的名称
    download_host: "master"

  tasks:
    - name: "只需要给 {{ download_host }} 的主机安装仓库文件"
      when: inventory_hostname == download_host
      get_url:
        url: https://download.docker.com/linux/centos/docker-ce.repo
        dest: /etc/yum.repos.d/docker-ce.repo
      tags:
        - deploy

    - name: 创建存放 rmp 包的目录
      when: inventory_hostname == download_host
      file:
        path: "{{ pkgs_dir }}"
        state: directory
      tags:
        - deploy

    - name:  开始下载软件包
      when: inventory_hostname == download_host
      yum:
        name: "{{ pkgs }}"
        download_only: yes
        download_dir: "{{ pkgs_dir }}"
      tags:
        - deploy

    - name: 传输 rpm 包到远程节点
      when: inventory_hostname != download_host
      copy:
        src: "{{ pkgs_dir }}"
        dest: "/"
      tags:
        - deploy

    - name: 正在执行从本地安装软件包
      shell:
        cmd: yum -y localinstall *
        chdir: "{{ pkgs_dir }}"
        warn: no
      async: 600
      poll: 0
      tags:
        - deploy

    - name: 设置 /etc/docker/daemon.json
      copy: src=files/daemon.json dest=/etc/docker/daemon.json
      notify: restart docker
      tags:
        - start
        - update

    - name: 启动 docker
      systemd:
        name: docker
        enabled: yes
        state: started
      tags:
        - start
  handlers:
    - name: restart docker
      systemd:
        name: docker
        state: restarted
...
[root@master files]# cat daemon.json
{
  "registry-mirrors": ["https://ut9q2ix5.mirror.aliyuncs.com"], #自己的阿里云镜像加速地址
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
     "max-size": "100m"
  },
  "storage-driver": "overlay2"
}

部署执行

ansible-playbook -i hosts.ini deploy-docker.yml

四、部署kubeadm、kubelet和kubectl

[root@master ansible]# cat deploy-kubeadm.yml
- name: Deploy kubeadm kubelet kubectl
  hosts: k8s
  gather_facts: no
  vars:
    pkgs_dir: /kubeadm-pkg
    pkgs: ["kubelet-1.23.5", "kubeadm-1.23.5", "kubectl-1.23.5", "ipvsadm"]

    download_host: "master"
  tasks:
    - name: "只需要给 {{ download_host }}安装仓库文件"
      when: inventory_hostname == download_host
      copy:
        src: files/kubernetes.repo
        dest: /etc/yum.repos.d/kubernetes.repo
    - name: "创建存放rpm包的目录"
      when: inventory_hostname == download_host
      file:
        path: "{{ pkgs_dir }}"
        state: directory
    - name: "下载软件包"
      when: inventory_hostname == download_host
      yum:
        name: "{{ pkgs }}"
        download_only: yes
        download_dir: "{{ pkgs_dir }}"
    - name: "传输rpm包到远程节点"
      when: inventory_hostname != download_host
      copy:
        src: "{{ pkgs_dir }}"
        dest: "/"
    - name: "正在执行从本地安装软件包"
      shell:
        cmd: yum -y localinstall *
        chdir: "{{ pkgs_dir }}"
        warn: no
      async: 600
      poll: 0
      register: yum_info
[root@master ansible]# cat files/kubernetes.repo
[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

执行部署

ansible-playbook -i hosts.ini deploy-kubeadm.yml

修改"/etc/sysconfig/kubelet"文件的内容:

[root@master ansible]# cat /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
[root@master ansible]# cat kubelet_config.yml
---
- name: 同步所有节点的 /etc/sysconfig/kubelet 文件
  hosts: k8s
  gather_facts: no
  tasks:
    - name: 同步 kubelet 文件
      copy: src=/etc/sysconfig/kubelet dest=/etc/sysconfig/kubelet

    - name: 开机自启动
      systemd:
        name: kubelet
        enabled: yes
...

执行指令,同步各个节点

[root@master ansible]# ansible-playbook -i hosts.ini kubelet_config.yml

在这里插入图片描述

五、初始化集群

1.在master节点上进行初始化

kubeadm init \
  --apiserver-advertise-address=192.168.76.100 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.23.5 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16

根据提示消息,在Master节点上使用kubectl工具:

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

2.安装网络插件

kubernetes支持多种网络插件,比如flannel、calico、canal等,推荐安装calico。

kubectl apply -f calico.yaml

六、将node节点加入集群

在node节点执行:

kubeadm join 192.168.76.100:6443 --token vdwao4.45tna7vnwacomafw --discovery-token-ca-cert-hash sha256:41fb812339dd74fc23eafc0680da4210d2f1415161ca872fc2cbf556ef4f8b38

注意查看在master节点初始化完成后的屏显,会有将nodes加入集群的指令,token是不一样的。

也可重新创建token:

kubeadm token create --print-join-command  # 在添加新node节点时,也需要此指令,将新node节点加入集群

查看安装进度:

[root@master ansible]# kubectl get pods -n kube-system
NAME                                      READY   STATUS    RESTARTS        AGE
calico-kube-controllers-7d467674b-kc2fj   1/1     Running   1 (125m ago)    17h
calico-node-8hvtt                         1/1     Running   15 (79m ago)    17h
calico-node-n6srw                         1/1     Running   13 (120m ago)   17h
calico-node-xrl58                         1/1     Running   15 (79m ago)    17h
coredns-6d8c4cb4d-9lzs8                   1/1     Running   1 (125m ago)    18h
coredns-6d8c4cb4d-v5kqc                   1/1     Running   1 (125m ago)    18h
etcd-master                               1/1     Running   1 (125m ago)    18h
kube-apiserver-master                     1/1     Running   1 (125m ago)    18h
kube-controller-manager-master            1/1     Running   3 (113m ago)    18h
kube-proxy-m29br                          1/1     Running   1 (126m ago)    17h
kube-proxy-nbss9                          1/1     Running   1 (125m ago)    18h
kube-proxy-ngl59                          1/1     Running   1 (125m ago)    17h
kube-scheduler-master                     1/1     Running   3 (113m ago)    18h
[root@master ansible]# kubectl get pods -n kube-system -owide
NAME                                      READY   STATUS    RESTARTS         AGE   IP               NODE     NOMINATED NODE   READINESS GATES
calico-kube-controllers-7d467674b-kc2fj   1/1     Running   1 (4h34m ago)    20h   10.244.219.68    master   <none>           <none>
calico-node-8hvtt                         1/1     Running   15 (3h48m ago)   20h   192.168.76.102   node2    <none>           <none>
calico-node-n6srw                         1/1     Running   13 (4h28m ago)   20h   192.168.76.100   master   <none>           <none>
calico-node-xrl58                         1/1     Running   15 (3h48m ago)   20h   192.168.76.101   node1    <none>           <none>
coredns-6d8c4cb4d-9lzs8                   1/1     Running   1 (4h34m ago)    20h   10.244.219.70    master   <none>           <none>
coredns-6d8c4cb4d-v5kqc                   1/1     Running   1 (4h34m ago)    20h   10.244.219.69    master   <none>           <none>
etcd-master                               1/1     Running   1 (4h34m ago)    20h   192.168.76.100   master   <none>           <none>
kube-apiserver-master                     1/1     Running   1 (4h34m ago)    20h   192.168.76.100   master   <none>           <none>
kube-controller-manager-master            1/1     Running   3 (4h22m ago)    20h   192.168.76.100   master   <none>           <none>
kube-proxy-m29br                          1/1     Running   1 (4h34m ago)    20h   192.168.76.101   node1    <none>           <none>
kube-proxy-nbss9                          1/1     Running   1 (4h34m ago)    20h   192.168.76.100   master   <none>           <none>
kube-proxy-ngl59                          1/1     Running   1 (4h34m ago)    20h   192.168.76.102   node2    <none>           <none>
kube-scheduler-master                     1/1     Running   3 (4h22m ago)    20h   192.168.76.100   master   <none>           <none>

查看集群状态:

[root@master ansible]# kubectl get nodes
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   18h   v1.23.5
node1    Ready    <none>                 17h   v1.23.5
node2    Ready    <none>                 17h   v1.23.5

修改node的ROLES:

[root@master ansible]# kubectl label nodes node1 node-role.kubernetes.io/node1=
node/node1 labeled
[root@master ansible]# kubectl label nodes node2 node-role.kubernetes.io/node2=
node/node2 labeled
[root@master ansible]# kubectl get node
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   20h   v1.23.5
node1    Ready    node1                  20h   v1.23.5
node2    Ready    node2                  20h   v1.23.5

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340