day4 : k8s建置(下)

昨天成功的用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为范例进行布署。
https://ithelp.ithome.com.tw/upload/images/20210904/20139661YESBGzegfe.png

做法其实非常的简单,只要将官方提供的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排版

CSS微动画 - 不知道要吃什麽?Slot帮你选吧

Q: 网路上已经很多可以用的随机选择器了耶... A: 拉霸的用途很多,看你怎麽用罗~ 已经连续N...

Microsoft MS-100 Dumps PDF with Actual MS-100 Exam Questions

IT business is one of the most famous in the busin...

第21车厢-input全选/取消全选功能底加啦!

本篇介绍常用的全选/取消全选功能---jquery应用篇 在input的世界里,最常做的就是抓值/...

Day19 :【TypeScript 学起来】More on Functions

我们在前面 Day09 , 有简单讨论到 function,这篇就会来看一些更深入 functio...

资产分类准则(asset classification guideline)

分类方案适用於整个组织。RD负责人定义一个是不合适的。此外,由於发布了资产分类准则,这意味着分类方...