昨天成功的用terraform创建gcp的instance出来,也透过terraform自动的把instance ip output出来,今天就来利用这些资源用ansible布建kubernetes吧。
ansible的运行仰赖了ssh的机制,虽然内建了sudo的切换机制但是我为简化部署作业,我在terrform布建时设计了root的ssh key置入,因此control center的控管要特别注意,
ansible总共有三个元件cfg设定档、inventory,yaml,透过ansible.cfg设定ansible执行者的环境(需要注意ansible会以当前的cfg > default cfg),其中为了简易部署作业,我调整了以下几个设定
inventory = 自己的路径/inventory
roles_path = 自己的路径/roles
host_key_checking = False
become=True
become_method=sudo
become_user=root
become_ask_pass=False
分别目的是指定我的inventory和roles路径,不需要再check knows_host,下面几个是为了防止我的失误下的保险,帮我允许不需密码sudo并且sudo为root。
接着编辑inventory档案,inventory对ansible来说是一个list清单(可以同时存在很多份清单),他帮助ansible了解他要执行作业的主机有哪些,以及主机有哪些variable可以使用,我这边编辑了一份范例
[k8s_cluster:children]
k8s_ha
k8s_node
[k8s_ha]
ha_IP node=ha_service
[k8s_node:children]
k8s_control_plane
k8s_computer
k8s_new_computer
[k8s_control_plane:children]
primary_control_plane
replicas_control_plane
[primary_control_plane]
control_plane_01_IP node=control_plane_01
[replicas_control_plane]
control_plane_02_IP node=control_plane_02
control_plane_03_IP node=control_plane_03
[k8s_computer]
computer_01_IP node=computer_01
computer_02_IP node=computer_02
[k8s_new_computer]
我替这个cluster编辑了一个群组ha+node,接着用同样的阶层概念去管理底下的node,这样未来要进行升级、管理都会容易很多,然後我替每个node加入的variable “node”,这样我就可以让ansible替kubernetes的node带入更多参数,同时搭配昨天terraform的output ip未来也可以自动的将新的node加入这份清单进行add node。
接着就可以开始编写ansble布建kubernetes的yaml了,kubernetes的布建我分为4块
1 环境配置
2 ha配置
3 control plane安装
4 add node
5 配置cni
环境配置
我运用以下范例进行安装套件、移除swap、关闭selinux、关闭防火墙、调整modprobe
- name: install package
yum:
name:
- bash-completion
- net-tools
- lsof
- unzip
- nc
state: latest
when: inventory_hostname in groups['k8s_node']
- name: Remove swapfile from /etc/fstab
mount:
name: swap
fstype: swap
state: absent
- name: set selinux config
lineinfile:
path: /etc/selinux/config
regexp: SELINUX=enforcing
line: 'SELINUX=disabled'
when: inventory_hostname in groups['k8s_node']
- name: disable firewalld
systemd:
name: firewalld
state: stopped
enabled: no
- name: Load br_netfilter module
modprobe:
name: br_netfilter
state: present
register: br_netfilter
因范例太长,为节省空间将简述其余作业,请尝试使用ansible shell module或是参考上面的module模仿完成看看吧 (提示 ansible-doc module name可以看example,ansible-doc -l可以查询目前的版本有哪些module可以用)
echo br_netfilter >> /etc/modules-load.d/br_netfilter.conf
echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf
echo “vm.swappiness = 0” >> /etc/sysctl.d/k8s.conf
echo “vm.overcommit_memory = 1” >> /etc/sysctl.d/k8s.conf
echo “net.bridge.bridge-nf-call-iptables = 1” >> /etc/sysctl.d/k8s.conf
echo “net.ipv4.ip_forward = 1” >> /etc/sysctl.d/k8s.conf
echo “net.ipv4.tcp_max_syn_backlog=2621440” >> /etc/sysctl.d/k8s.conf
yum install cri-o kubeadm kubelet kubectl (注意 : 套件库控管很重要,这边建议控制好自己使用的版本,所以要准备自己的repo档案,可以用template module统一)
cp harber.crt 到各主机
调整/etc/crio/crio.conf的stream_tls_cert凭证
调整/etc/crio/crio.conf的seccomp_profile 指向/usr/share/containers/seccomp.json
调整/etc/crio/crio.conf的pause_image指定到自己的image repo
调整/etc/sysconfig/kubelet为KUBELET_EXTRA_ARGS=--cgroup-driver=systemd
启动cri-o、kubelet service
安装及设定haproxy
同样透过ansible的yum module,较为特殊的是这边要介绍ansible的templatefile用法,有时候需要复制一份带有variable的档案不太可能临时编修一份,这样实在是太费工了,在使用ansible template module时他会将来源端的档案中的变数依据规则写到目的端,如下范例
这是haproxy的中间一段
frontend kubernetes
{% for host in groups['k8s_ha']%}
bind {{hostvars[host].ansible_facts.default_ipv4.address}}:6443
{% endfor %}
option tcplog
mode tcp
default_backend kubernetes-master-nodes
backend kubernetes-master-nodes
mode tcp
balance roundrobin
option tcp-check
{% for host in groups['k8s_control_plane']%}
server {{hostvars[host].node}} {{hostvars[host].ansible_facts.default_ipv4.address}}:6443 check fall 3 rise 2
{% endfor %}
根据这个template file的内容,会用k8s_control_plane这个group的清单去将清单内的node的ip依序写进haproxy的档案中
结果会是
server control_plane_01 control_plane_01_IP:6443
server control_plane_02 control_plane_02_IP:6443
server control_plane_03 control_plane_03_IP:6443
安装第一台control plane
爲什麽要把这一步骤独立出来呢,因为第一台control plane身兼之後让node join的角色,我使用kubeadm的方式进行布建,为了搭配ansible我最终选择将一个shell脚本丢到control plane主机上执行,他的内容大致上如下
kubeadm init --service-cidr 10.96.0.0/12 --pod-network-cidr 172.16.0.0/16 --apiserver-advertise-address 0.0.0.0 --control-plane-endpoint “${ha_ip}:6443" --upload-certs --v=5 > /root/kubeadm.log
相关kubeadm参数我这边就不多阐述了,请参考https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/,爲什麽我会选择使用ansible再去执行shell这样多一道工序呢?其实主要是在於我尝试了几次ansible直接使command有时候会发生不稳定的错误,所以最後选择稳定的布建为主,让每次的结果都相同是我认为比较重要的,安装完成後将主机上的档案透过ansible fetch module的方式搬回control center做为接下来的部属元件使用,范例如下
- name: "Fetching Kubernetes Master PKI files from primary "
fetch:
src: /etc/kubernetes/pki/{{item}}
dest: /tmp/kubernetes/pki/{{item}}
flat: yes
with_items:
- ca.crt
- ca.key
- sa.key
- sa.pub
- front-proxy-ca.crt
- front-proxy-ca.key
还会需要/etc/kubernetes/pki/etcd/的ca档案和/etc/kubernetes/的admin.conf。
join node
这边我会进行两阶段,第一阶段是join control plane第二阶段是join computer node,在join control plane之前会需要将刚刚的/tmp/kubernetes/下抓回来的档案放到要join的control plane主机上的/etc/kubernetes/,然後在第一座control plane上使用以下两个command取得join control plane集群的指令(这边请尝试使用ansible registry的功能做看看)
kubeadm token create --print-join-command
kubeadm init phase upload-certs --upload-certs
两段指令结合--control-plane --certificate-key 正确的情况下,会得到像是下面的指令
kubeadm join IP:6443 --token xxxxxxx --discovery-token-ca-cert-hash sha256:xxxxxxx --control-plane --certificate-key yyyyyy
这样在要join的control plane上执行就会自动的开始加入cluster,join node则是只需要第一个指令就可以了。
最後在master主机上执行kubectl get node --kubeconfig ~/.kube/config就可以开始使用kubernetess罗。
网路配置
对kubernetes而言,安装好的时候并不会提供cni给pod去使用,所以需要配一个提供网路的服务,有很多可以选择的像是flannel、calico,cilium等等...,我以calico为范例进行布署。
做法其实非常的简单,只要将官方提供的yaml和需要的image抓下来後kubectl apply -f即可。
官方yaml
curl https://docs.projectcalico.org/manifests/calico.yaml -O
需要注意的是,在安装完成calico之後建议重新启动coredns的服务,避免服务无法彼此之间存取。
kubectl -n kube-system rollout restart deployment coredns
要讲完ansible的概念和功能其实短短一篇是不可能完成的,同样kubeadm的install也不是这样一点小篇幅就能说明清楚,今天折衷的选择了讲述如何利用ansible将kubeadm要安装kubernetes时的步骤说明完成,这也是一开始想要表达的利用terraform + ansible 这种宣告式的脚本工具让每一次的结果都完全相同。
<<: GitHub 上讨论议题 - 建立第一个 Issue 与自订 Labels
>>: #3. Expanding Cards(原生JS版)+ 用tailwindcss玩grid排版
Q: 网路上已经很多可以用的随机选择器了耶... A: 拉霸的用途很多,看你怎麽用罗~ 已经连续N...
IT business is one of the most famous in the busin...
本篇介绍常用的全选/取消全选功能---jquery应用篇 在input的世界里,最常做的就是抓值/...
我们在前面 Day09 , 有简单讨论到 function,这篇就会来看一些更深入 functio...
分类方案适用於整个组织。RD负责人定义一个是不合适的。此外,由於发布了资产分类准则,这意味着分类方...