0、k8s的安装以及基础pod方式搭建

0、准备的主机

Kubernetes技术已经成为了原生云技术的事实标准,它是目前基础软件领域最为热门的分布式调度和管理平台。于是,Kubernetes也几乎成了时下开发工程师和运维工程师必备的技能之一。

Master01 192.168.1.20
Node01 192.168.1.21
Node02 192.168.1.22
Node03 192.168.1.23

ssh-keygen两两交换

1、主机名

$ vim /etc/hosts
192.168.1.20 master01 master01.wuyanzu.com   
192.168.1.21 node01 node01.wuyanzu.com
192.168.1.22 node02 node02.wuyanzu.com
192.168.1.23 node03 node03.wuyanzu.com

节点的 hostname 必须使用标准的 DNS 命名,另外千万不用什么默认的 localhost 的 hostname,会导致各种错误出现的。在 Kubernetes 项目里,机器的名字以及一切存储在 Etcd 中的 API 对象,都必须使用标准的 DNS 命名(RFC 1123)。

$ scp /etc/hosts 192.168.1.21:/etc/
$ scp /etc/hosts 192.168.1.22:/etc/
$ scp /etc/hosts 192.168.1.23:/etc/

2、禁用防火墙与SELINUX

$ systemctl stop firewalld.service 
$ systemctl stop iptables.service
$ systemctl disable firewalld.service
$ systemctl disable iptables.service
$ setenforce 0
$ cat /etc/selinux/config
SELINUX=disabled

# 使用sed
$ sed -i 's@^\(SELINUX=\).*@\1disabled@' /etc/sysconfig/selinux

3、同步服务器时间

$ yum install chrony -y && systemctl enable chronyd &&systemctl start chronyd 
# 同步时间
$ chronyc sources
$ date

不过,建议用户配置使用本地的的时间服务器,在节点数量众多时尤其如此。存在可用的本地时间服务器时,修改节点的/etc/crhony.conf配置文件,并将时间服务器指向相应的主机即可,配置格式如下:
server CHRONY-SERVER-NAME-OR-IP iburst

4、禁用Swap设备

部署集群时,kubeadm默认会预先检查当前主机是否禁用了Swap设备,并在未禁用时强制终止部署过程。因此,在主机内存资源充裕的条件下,需要禁用所有的Swap设备,否则,就需要在后文的kubeadm init及kubeadm join命令执行时额外使用相关的选项忽略检查错误。

$ free -m
              total        used        free      shared  buff/cache   available
Mem:            954         147         440           9         366         653
Swap:          2047           9        2038
#临时
$ swapoff -a
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            954         150         433          12         370         646
Swap:             0           0           0



关闭Swap设备,需要分两步完成。首先是关闭当前已启用的所有Swap设备:
$ swapoff -a

修改/etc/fstab文件,注释掉 SWAP 的自动挂载。swappiness 参数调整,修改/etc/sysctl.d/k8s.conf添加下面一行:

$ vim /etc/sysctl.d/k8s.conf
vm.swappiness=0
$ sysctl -p /etc/sysctl.d/k8s.conf

5、启用ipvs内核模块

由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块:

$ modprobe br_netfilter
$ vim /etc/sysctl.d/k8s.conf
vm.swappiness=0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
$ sysctl -p /etc/sysctl.d/k8s.conf
$ scp /etc/sysctl.d/k8s.conf node01:/etc/sysctl.d/
$ scp /etc/sysctl.d/k8s.conf node02:/etc/sysctl.d/
$ scp /etc/sysctl.d/k8s.conf node03:/etc/sysctl.d/

bridge-nf

bridge-nf 使得 netfilter 可以对 Linux 网桥上的 IPv4/ARP/IPv6 包过滤。
比如,设置net.bridge.bridge-nf-call-iptables=1后,二层的网桥在转发包时也会被 iptables的 FORWARD 规则所过滤。常用的选项包括:

net.bridge.bridge-nf-call-arptables:是否在 arptables 的 FORWARD 中过滤网桥的 ARP 包
net.bridge.bridge-nf-call-ip6tables:是否在 ip6tables 链中过滤 IPv6 包
net.bridge.bridge-nf-call-iptables:是否在 iptables 链中过滤 IPv4 包
net.bridge.bridge-nf-filter-vlan-tagged:是否在 iptables/arptables 中过滤打了 vlan 标签的包。

安装 ipvs

$ cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
$ chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

上面脚本创建了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已经正确加载所需的内核模块。

接下来还需要确保各个节点上已经安装了 ipset 软件包:

$ yum install ipset -y

为了便于查看 ipvs 的代理规则,最好安装一下管理工具 ipvsadm:

$ yum install ipvsadm -y

6、安装docker

[docker-ce]
name=docker
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/


$ yum install docker-ce -y  --nogpgcheck
$ systemctl start docker
$ systemctl enable docker.service

配置镜像加速器

$ mkdir -p /etc/docker
$ vim /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "registry-mirrors" : [
    "https://sw9esv3f.mirror.aliyuncs.com"
  ]
}
sudo systemctl daemon-reload
sudo systemctl restart docker
$ scp /etc/docker/daemon.json node01:/etc/docker/
$ scp /etc/docker/daemon.json node02:/etc/docker/
$ scp /etc/docker/daemon.json node03:/etc/docker/

cgroup 驱动

由于默认情况下 kubelet 使用的 cgroupdriver 是 systemd,所以需要保持 docker 和kubelet 的 cgroupdriver 一致,我们这里修改 docker 的 cgroupdriver=systemd。如果不修改 docker 则需要修改 kubelet 的启动配置,需要保证两者一致。

docker命令补全

sudo yum install -y bash-completion
#登出一下再进来即可

7、安装k8s

1-7是所有主机都要执行的

[kubernetes]
name=kubernetes
baseurl=https://mirrors.tuna.tsinghua.edu.cn/kubernetes/yum/repos/kubernetes-el7-x86_64/

--disableexcludes 禁掉除了kubernetes之外的别的仓库
$ yum install kubelet kubeadm kubectl -y --nogpgcheck --disableexcludes=kubernetes

# 查看版本
$ kubeadm version
#设置为开机启动
$ systemctl enable --now kubelet

8、初始化集群

master 节点配置 kubeadm 初始化文件,可以通过如下命令导出默认的初始化配置:

8.1、通过配置文件加载配置

$ kubeadm config print init-defaults > kubeadm.yaml

然后根据我们自己的需求修改配置,比如修改 imageRepository 的值,kube-proxy 的模式为 ipvs,另外需要注意的是我们这里是准备安装 flannel 网络插件的,需要将 networking.podSubnet 设置为10.244.0.0/16

apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.1.20 # apiserver 节点内网IP
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master1
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
# registry.aliyuncs.com/k8sxio   # 修改成阿里云镜像源
kind: ClusterConfiguration
kubernetesVersion: 1.21.1
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16  # Pod 网段,flannel插件需要使用这个网段
  serviceSubnet: 10.96.0.0/12
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs  # kube-proxy 模式

godoc 文档:完整的资源对象对应的属性

https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2。

$ kubeadm init --config kubeadm.yaml

kubectl是kube-apiserver的命令行客户端程序,实现了除系统部署之外的几乎全部的管理操作,是kubernetes管理员使用最多的命令之一。kubectl需经由API server认证及授权后方能执行相应的管理操作,kubeadm部署的集群为其生成了一个具有管理员权限的认证配置文件/etc/kubernetes/admin.conf,它可由kubectl通过默认的“$HOME/.kube/config”的路径进行加载。当然,用户也可在kubectl命令上使用--kubeconfig选项指定一个别的位置。

下面复制认证为Kubernetes系统管理员的配置文件至目标用户(例如当前用户root)的家目录下:

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

8.2、命令行初始化方式

$ kubeadm init --kubernetes-version=v1.21.1 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --image-repository  registry.aliyuncs.com/google_containers  --ignore-preflight-errors=Swap

命令中的各选项简单说明如下:

  • --kubernetes-version选项的版本号用于指定要部署的Kubenretes程序版本,它需要与当前的kubeadm支持的版本保持一致;
  • --pod-network-cidr选项用于指定分Pod分配使用的网络地址,它通常应该与要部署使用的网络插件(例如flannel、calico等)的默认设定保持一致,10.244.0.0/16是flannel默认使用的网络;
  • --service-cidr用于指定为Service分配使用的网络地址,它由kubernetes管理,默认即为10.96.0.0/12;
  • 最后一个选项“--ignore-preflight-errors=Swap”仅应该在未禁用Swap设备的状态下使用。

注意初始化的时候coredns在阿里云的有点不一致,所以需要手动去拉一下,然后去打下标签在初始化

$ docker pull registry.aliyuncs.com/google_containers/coredns:1.8.0
$ docker tag registry.aliyuncs.com/google_containers/coredns:1.8.0  registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
$ docker rmi registry.aliyuncs.com/google_containers/coredns:1.8.0

在各个node节点中也是需要手动拉改的

如果没有得到全是OK的结果

# 是/etc/kubernetes/manifests下的kube-controller-manager.yaml和kube-scheduler.yaml设置的默认端口是0导致
$ kubectl get cs
NAME                 STATUS      MESSAGE                                                                                     ERROR
scheduler            Unhealthy   Get http://127.0.0.1:10251/healthz: dial tcp 127.0.0.1:10251: connect: connection refused
controller-manager   Unhealthy   Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252: connect: connection refused
etcd-0               Healthy     {"health":"true"}

# kube-scheduler.yaml配置修改:注释掉19行
$ vim /etc/kubernetes/manifests/kube-scheduler.yaml
...
16     - --bind-address=127.0.0.1
17     - --kubeconfig=/etc/kubernetes/scheduler.conf
18     - --leader-elect=true
19   #  - --port=0
...
# kube-controller-manager.yaml文件修改:注释掉27行
$ vim /etc/kubernetes/manifests/kube-controller-manager.yaml
...
 22     - --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
 23     - --controllers=*,bootstrapsigner,tokencleaner
 24     - --kubeconfig=/etc/kubernetes/controller-manager.conf
 25     - --leader-elect=true
 26     - --node-cidr-mask-size=24
 27  #  - --port=0
...

$ kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   

kubeadm init 命令执行流程图

9、添加节点

安装 kubeadm、kubelet、kubectl(可选)

# 将 master 节点上面的 ~/.kube/config 文件拷贝到 node 节点对应的文件中,这样每个node也可以查看面板
$ scp ~/.kube/config node01:~/.kube/
$ scp ~/.kube/config node02:~/.kube/
$ scp ~/.kube/config node03:~/.kube/
# 查看token
$ kubeadm token list
# 查看--discovery-token-ca-cert-hash
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

# 或者2者
$ kubeadm token create --print-join-command
kubeadm join 192.168.1.20:6443 --token bhq4ro.jieonxs43q0iimal --discovery-token-ca-cert-hash sha256:37ea892c7874b116e24b63ab1403dbe9573e9414beb2d07e2547cad6000fa6f3 

join执行流程图

10、网络插件

Kubernetes系统上Pod网络的实现依赖于第三方插件进行,这类插件有近数十种之多,较为著名的有flannel、calico、canal和kube-router等,简单易用的实现是为CoreOS提供的flannel项目。下面的命令用于在线部署flannel至Kubernetes系统之上:

$ wget -e "https_proxy=http://192.168.1.6:7890" https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 因为有节点是多网卡,所以需要在资源清单文件中指定内网网卡
# 搜索到名为 kube-flannel-ds 的 DaemonSet,在kube-flannel容器下面
$ vim kube-flannel.yml
......
containers:
- name: kube-flannel
  image: quay.io/coreos/flannel:v0.13.0
  command:
  - /opt/bin/flanneld
  args:
  - --ip-masq
  - --kube-subnet-mgr
  - --iface=eth0  # 如果是多网卡的话,指定内网网卡的名称
......

# 安装 flannel 网络插件
$ kubectl apply -f kube-flannel.yml  

# 全部显示ready表示成功建立flannel隧道
$ kubectl get nodes
NAME     STATUS   ROLES                  AGE   VERSION
node     Ready    control-plane,master   30m   v1.21.1
node01   Ready    <none>                 26m   v1.21.1
node02   Ready    <none>                 19m   v1.21.1
node03   Ready    <none>                 19m   v1.21.1

# 查看主节点的配置信息
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.1.20:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

11、Dashboard(简单使用)

$ wget -e "https_proxy=http://192.168.1.6:7890" https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
$ vim  recommended.yaml 
# 修改Service为NodePort类型
......
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  type: NodePort  # 加上type=NodePort变成NodePort类型的服务,向外暴露端口
......
$ kubectl apply -f recommended.yaml 
$ kubectl get pods -n kubernetes-dashboard 
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-856586f554-sjcrw   1/1     Running   0          82s
kubernetes-dashboard-78c79f97b4-j6sd6        1/1     Running   0          82s

$ kubectl get svc -n kubernetes-dashboard 
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.97.149.154   <none>        8000/TCP        102s
kubernetes-dashboard        NodePort    10.99.166.71    <none>        443:32660/TCP   102s

在 YAML 文件中可以看到新版本 Dashboard 集成了一个 metrics-scraper 的组件,可以通过 Kubernetes 的 Metrics API 收集一些基础资源的监控信息,并在 web 页面上展示,所以要想在页面上展示监控信息就需要提供 Metrics API,比如安装 Metrics Server。

使用火狐测试192.168.1.20:32660(任何一个节点IP)

然后创建一个具有全局所有权限的用户来登录Dashboard:(admin.yaml)

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: admin
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kubernetes-dashboard

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: kubernetes-dashboard
$ kubectl apply -f admin.yaml
$ kubectl get secret -n kubernetes-dashboard
NAME                               TYPE                                  DATA   AGE
admin-token-tm8hk                  kubernetes.io/service-account-token   3      32s
default-token-5zq2k                kubernetes.io/service-account-token   3      8m15s
kubernetes-dashboard-certs         Opaque                                0      8m15s
kubernetes-dashboard-csrf          Opaque                                1      8m15s
kubernetes-dashboard-key-holder    Opaque                                2      8m15s
kubernetes-dashboard-token-qq9zn   kubernetes.io/service-account-token   3      8m15s

$ kubectl  describe secret admin-token-wj5hg -n kubernetes-dashboard
...
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IklsTGNCZ1oxREpHLUZ2M0xTMHg4UFo5Ym14QUdrZkd2S2VwcHNrM1FPc00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi13ajVoZyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImZkNWVkNTY4LTAwMzctNDJiMy1iMDQ3LTU3NDhmZTM4M2NjNSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbiJ9.Lks1svXuk1xwD7xosvgwuApft3zjTUapG6rPacbIrSNkHRL2BfWw6r79-0XtfCCBrTcsggBICJ4gDwBhrh6Iz5veKF2l4dKQcNLODttjm6Bt-1gJlmYxx-9mrige4tpXEjm7YAeXE8cqnDM_wG9Zrar2JRm3S-FvQAI9jf79q_4H-WuMvCQ0iuQJ80yk2Y-Y6dsTO8E39LujJ6XSiBdEID9vmcNzMBwl3hiJ_StSdqSeYvph-x9F2DDxYsOM9p6OF6wfq87u_wBzqZGH6RzernahXqC9Ror_iUO77_RH-rCApU-RJbPHF94oT_F0EPckCJDi6N9pHLNqpQFxYxU_EQ
...

# 直接一条命令取出来,base64解码后的值
$ kubectl get secrets admin-token-tm8hk -o jsonpath={.data.token} -n kubernetes-dashboard

12、清理

如果你的集群安装过程中遇到了其他问题,我们可以使用下面的命令来进行重置:

$ kubeadm reset
$ ifconfig cni0 down && ip link delete cni0
$ ifconfig flannel.1 down && ip link delete flannel.1
$ rm -rf /var/lib/cni/

13、k8s 命令自动补全

yum install -y bash-completion &&\
source /usr/share/bash-completion/bash_completion &&\
source <(kubectl completion bash) &&\
echo "source <(kubectl completion bash)" >> ~/.bashrc 

14、IDE与服务器交互的2种方式

1、sftp连接

见pycharm

2、Bash on MacOS

在 Mac 下面,就稍微复杂一点点了,因为 Mac 上的 Bash 默认版本是3.2,已经过时了,kubectl 的自动补全脚本至少需要 Bash 4.1 版本。

所以要在 Mac 上使用 kubectl 自动补全功能,你就需要安装新版本的 Bash,更新 Bash 是很容易的,可以查看这篇文章:Upgrading Bash on macOS,这里我们就不详细说明了。

在继续向下之前,请确保你的 Bash 版本在 4.1 以上。和 Linux 中一样,Bash 的补全脚本依赖 bash-completion 项目,所以我们也必须要安装它。

我们可以使用 Homebrew 工具来安装:

$ brew install bash-completion@2

@2代表 bash-completion v2 版本,kubectl 命令补全脚本需要 v2 版本,而 v2 版本至少需要 Bash 4.1 版本,所以这就是不能在低于4.1的 Bash 下面使用 kubectl 的补全脚本的原因。

brew 安装命令完成会输出一段提示信息,其中包含将下面内容添加到~/.bash_profile文件中的说明:

export BASH_COMPLETION_COMPAT_DIR=/usr/local/etc/bash_completion.d
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"

这样就完成了 bash-completion 的安装,但是建议将上面这一行信息添加到~/.bashrc当中,这样可以在子 shell 中也可以使用 bash-completion。

重新加载 shell 后,可以使用以下命令测试是否正确安装了 bash-completion:

$ type _init_completion

如果输出一个 shell 函数,证明安装成功了。然后就需要进行一些配置来让我们在所有的 shell 会话中都可以获取 kubectl 补全脚本。

一种方法是将下面的内容添加到~/.bashrc文件中:

source <(kubectl completion bash)

另外一种方法是添加 kubectl 补全脚本到/usr/local/etc/bash_completion.d目录下面:

$ kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl

使用 Homebrew 安装 bash-completion 时上面的方法才会生效。

如果你还是使用 Homebrew 安装的 kubectl 的话,上面的步骤都可以省略,因为补全脚本已经被自动放置到/usr/local/etc/bash_completion.d目录中去了,这种情况,kubectl 命令补全应该在安装完 bash-completion 后就可以正常使用了。

最后,重新加载 shell 后,kubectl 自动提示应该就可以正常工作了。

posted @ 2021-05-28 20:31  一直飞的无脚鸟  阅读(360)  评论(0编辑  收藏  举报