部署非高可用的k8s
一、Ansible通过Playbook实现批量免密
1.编写/etc/hosts 文件
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.9.29.106 k8s-master
10.9.29.105 k8s-node1
10.9.29.107 k8s-node2
2.编译ansible 主机清单 hosts.ini
Master端
[k8s_master]
k8s-master
[k8s_nodes]
k8s-node1
k8s-node2
[k8s]
[k8s:children]
k8s_master
k8s_nodes
3.发送公钥
send-pubkey.yml
---
- hosts: all
gather_facts: no
remote_user: root
vars:
ansible_ssh_pass: 1
tasks:
- name: Set authorized key taken from file
authorized_key:
user: root
state: present
key: "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
...
/etc/ansible/ansible.cfg
打开以下注释
host_key_checking = False
ansible-playbook -i hosts.ini send-pubkey.yml
4.发送 /etc/hosts
cp /etc/hosts .
send-hosts.yml
---
- name: 同步所有节点的 /etc/hosts 文件 并且设置主机名
hosts: k8s
gather_facts: no
tasks:
- name: 同步 hosts 文件
copy: src=hosts dest=/etc/hosts
- name: 设置各自的主机名
shell:
cmd: hostnamectl set-hostname "{{ inventory_hostname }}"
register: sethostname
- name: 验证是否成功设置了主机名
debug: var=sethostname.rc
...
ansible-playbook -i hosts.ini send-hosts.yml
二、检查并设置环境
1.检查并设置
before-you-begin.yml
---
- name: 开始部署集群之前的检查和设置
hosts: k8s
gather_facts: yes
vars:
infohost: "k8s-master"
tasks:
- name: 创建模块配置文件 /etc/modules-load.d/k8s.conf
blockinfile:
path: /etc/modules-load.d/k8s.conf
create: yes
block: |
br_netfilter
- 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
- name: 执行加载模块的命令
shell: modprobe br_netfilter
- name: 获取 模块加载和 iptables 的网桥流量设置
shell: >
lsmod | grep br_netfilter;sysctl --system | grep 'k8s.conf' -A 2
register: check
- name: 输出检查报告
debug:
msg: "{{ check.stdout_lines }}"
- name: 获取 mac 信息并写入信息文件
shell: |
hostname > /tmp/host-info;
ip link |awk '/link\/ether/ {print $2}' >> /tmp/host-info ;
- name: 获取比对报告
fetch:
src: /tmp/host-info
dest: ./
register: ret
...
ansible-playbook -i hosts.ini before-you-begin.yml
2.检查端口
check-port.yml
- hosts: k8s
gather_facts: no
tasks:
- name: hello
script: ./check-port.py
register: ret
- debug: var=item
loop: "{{ ret.stdout_lines }}"
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("端口未占用")
ansible-playbook -i hosts.ini check-port.yml
三、部署docker
docker/deploy-docker.yml
---
- name: deploy docker
hosts: k8s
gather_facts: no
vars:
pkg_dir: /yum-pkg
pkgs:
- device-mapper-persistent-data
- lvm2
- containerd.io-1.2.13
- docker-ce-19.03.11
- docker-ce-cli-19.03.11
# 变量 download_host 需要手动设置
# 且值需要是此 playbook 目标主机中的一个
# 需要写在 inventory 文件中的名称
download_host: "k8s-master"
local_pkg_dir: "{{ playbook_dir }}/{{ download_host }}"
tasks:
- name: 测试使用 -e 是否覆盖了变量
debug:
msg: "{{ local_pkg_dir }} {{ download_host }}"
tags:
- deploy
- test
- 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: "{{ pkg_dir }}"
state: directory
tags:
- deploy
- name: 正在下载软件包
when: inventory_hostname == download_host
yum:
name: ["docker-ce", "docker-ce-cli", "containerd.io"]
download_only: yes
download_dir: "{{ pkg_dir }}"
tags:
- deploy
- name: 获取下载目录 "{{ pkg_dir }}" 中的文件列表
when: inventory_hostname == download_host
shell: ls -1 "{{ pkg_dir }}"
register: files
tags:
- deploy
- name: 把远程主机下载的软件包传输到 ansible 本地
when: inventory_hostname == download_host
fetch:
src: "{{ pkg_dir }}/{{ item }}"
dest: ./
loop: "{{files.stdout_lines}}"
tags:
- deploy
- name: 传输 rpm 包到远程节点
when: inventory_hostname != download_host
copy:
src: "{{ local_pkg_dir }}{{ pkg_dir }}"
dest: "/"
tags:
- deploy
- name: 正在执行从本地安装软件包
shell:
cmd: yum -y localinstall *
chdir: "{{ pkg_dir }}"
warn: no
async: 600
poll: 0
register: yum_info
tags:
- deploy
- name: 打印安装结果
debug: var=yum_info.ansible_job_id
tags:
- deploy
- name: 启动 docker
systemd:
name: docker
enabled: yes
state: started
tags:
- start
...
部署的时候执行:
ansible-playbook -i hosts.ini docker/deploy-docker.yml -t deploy
启动 docker 服务 执行:
ansible-playbook -i hosts.ini docker/deploy-docker.yml -t start
file/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
file/deploy-kubeadm.yml
---
- name: Deploy kubeadm kubelet kubectl
hosts: k8s
gather_facts: no
vars:
pkg_dir: /kubeadm-pkg
pkg_names: ["kubelet", "kubeadm", "kubectl"]
# 变量 download_host 需要手动设置
# 且值需要是此 playbook 目标主机中的一个
# 需要写在 inventory 文件中的名称
download_host: "k8s_master"
local_pkg_dir: "{{ playbook_dir }}/{{ download_host }}"
tasks:
- name: 测试使用 -e 是否设置并覆盖了变量
debug:
msg: "{{ local_pkg_dir }} {{ download_host }}"
tags:
- deploy
- test
- name: "只需要给 {{ download_host }}安装仓库文件"
when: inventory_hostname == download_host
copy:
src: file/kubernetes.repo
dest: /etc/yum.repos.d/kubernetes.repo
tags:
- deploy
- name: 创建存放 rmp 包的目录
when: inventory_hostname == download_host
file:
path: "{{ pkg_dir }}"
state: directory
tags:
- deploy
- name: 下载软件包
when: inventory_hostname == download_host
yum:
name: "{{ pkg_names }}"
download_only: yes
download_dir: "{{ pkg_dir }}"
tags:
- deploy
- name: 获取下载目录 "{{ pkg_dir }}" 中的文件列表
when: inventory_hostname == download_host
shell: ls -1 "{{ pkg_dir }}"
register: files
tags:
- deploy
- name: 把远程主机下载的软件包传输到 ansible 本地
when: inventory_hostname == download_host
fetch:
src: "{{ pkg_dir }}/{{ item }}"
dest: ./
loop: "{{files.stdout_lines}}"
tags:
- deploy
- name: 传输 rpm 包到远程节点
when: inventory_hostname != download_host
copy:
src: "{{ local_pkg_dir }}{{ pkg_dir }}"
dest: "/"
tags:
- deploy
- name: 正在执行从本地安装软件包
shell:
cmd: yum -y localinstall *
chdir: "{{ pkg_dir }}"
warn: no
async: 600
poll: 0
register: yum_info
tags:
- deploy
- name: 打印安装结果
debug: var=yum_info.ansible_job_id
tags:
- deploy
- name:
systemd:
name: kubelet
state: started
tags:
- start
...
拉取kubeadm 镜像慢的直接下载 :
wget https://www.sharkyun.com:8043/2002/soft/kubeadm.tar.gz
docker load -i kubeadm.tar.gz
查询版本信息
kubeadm version