资讯详情

K8S部署&DevOps

k8s kubesphere devops

一、k8s 集群部署

1、k8s 快速入门

1)、简介

Kubernetes 简称 k8s。是用于自动部署,扩展和管理容器化应用程序的开源系统。

中文官网:https://kubernetes.io/zh/

中文社区:https://www.kubernetes.org.cn/

官方文档:https://kubernetes.io/zh/docs/home/

社区文档:http://docs.kubernetes.org.cn/

  • 部署模式的演变

image-20220329160446707

https://kubernetes.io/zh/docs/concepts/overview/

2)、架构

1、整体主从方式

以服务器为主节点,其他服务器为主节点node节点

2、Master 节点架构

    • 对外暴露 K8S 的 api 接口是外部资源操作的唯一入口
    • 提供认证、授权、访问控制API 注册和发现等机制
    • etcd 它是一个具有一致性和高可用性的键值数据库,可用作保存 Kubernetes 所有集群数据的背景数据库。
    • Kubernetes 集群的 etcd 数据库通常需要备份计划
    • 主节点上的组件监控新创建的未指定操作节点 Pod,并选择节点 让 Pod 在上面操作。
    • 所有对 k8s 集群操作必须通过主节点进行调度
    • 控制器组件在主节点上运行
    • 这些控制器包括:
      • 节点控制器(Node Controller): 在节点出现故障时,负责通知和响应。
      • 副本控制器(Replication Controller): 负责维护系统中每个副本控制器对象的正确数量 Pod。
      • 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入) Service 与 Pod) 。
      • 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名 创建默认账户和空间 API 访问令牌

3、Node 节点架构

    • 在集群中的每个节点上运行的代理。它确保容器在运行中 Pod 中。
    • 负责维护容器的生命周期和生命周期 Volume(CSI)和网络(CNI)的管理;
    • 负责为 Service 提供 cluster 内部服务发现与负载平衡;
  • 容器运行环境(Container Runtime)

    • 容器运行环境是负责容器运行的软件。
    • Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI (容器运行环境接口)。
    • 这是一个保护过程,有助于提供集群层面的日志

3)、概念

  • Container:容器,可以 docker 启动容器

  • Pod:

    • k8s 使用 Pod 组织一组容器
    • 一个 Pod 所有容器共享同一网络。
    • Pod 是 k8s 最小部署单元
  • Volume

    • 声明在 Pod 可访问的文件目录在容器中
    • 可挂载 Pod 在一个或多个容器指定的路径下
    • 支持抽象(本地存储、分布式存储、云存储…)

  • Controllers:部署和管理更高层次的对象 Pod;

    • ReplicaSet:确保预期的 Pod 副本数量
    • Deplotment:无状态应用部署
    • StatefulSet:有状态应用部署
    • DaemonSet:确保所有 Node 所有一个指定 Pod
    • Job:一次性任务
    • Cronjob:定时任务
  • Deployment:

    • 定义一组 Pod 副本数量、版本等
    • 通过控制器(Controller)维持 Pod 数量(自动返回 复失败的 Pod)
    • 指定的策略控制版本(滚动升级、回滚等。)通过控制器

  • Service
    • 定义一组 Pod 的访问策略
    • Pod 提供一个或多个负载平衡 Pod 的稳定 访问地址
    • 支持多种方式(ClusterIP、NodePort、LoadBalance)

  • Namespace:命名空间,逻辑隔离
    • 集群内的逻辑隔离机制(鉴权、资源)
    • 每个资源都属于一个 namespace
    • 同一个 namespace 所有资源名称不能重复
    • 不同 namespace 可重复资源名称

API:

我们通过 kubernetes 的 API 操作整个集群

可以通过 kubectl、ui、curl 最终发送 http json/yaml 方式请求 API Server,然后控制 k8s 集群。

4)快速体验

1、安装 minikube

https://github.com/kubernetes/minikube/releases

下载 minikube-windows-amd64.exe 改名为 minikube.exe 打开 VirtualBox,打开cmd运行

minikube start --vm-driver=virtualbox --registry-mirror=https://registry.docker-cn.com 

等待 20 大约几分钟

2、体验 nginx 部署升级

提交一个ngix deployment

kubectl apply -f https://k8s.io/examples/application/deployment.yaml

升级nginx deployment

kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml

扩容nginx deployment

kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml

5)、流程叙述

1、通过 Kubectl 提交一个创建RC(Replication Controller)的请求,该请求通过 APIServer被写入etcd 中

2、此时Controller Manager 通过API Server 的监听资源变化的接口监听到此RC 事件

3、分析之后,发现当前集群中还没有它所对应的Pod 实例,

4、于是根据RC 里的Pod 模板定义生成一个Pod 对象,通过APIServer 写入etcd

5、此事件被Scheduler 发现,它立即执行一个复杂的调度流程,为这个新 Pod 选定一 个落户的Node,然后通过 API Server 讲这一结果写入到 etcd 中,

6、目标 Node 上运行的 Kubelet 进程通过 APIServer 监测到这个“新生的”Pod,并按照它 的定义,启动该 Pod 并任劳任怨地负责它的下半生,直到Pod 的生命结束。

7、随后,我们通过Kubectl 提交一个新的映射到该 Pod 的Service 的创建请求

8、ControllerManager 通过Label 标签查询到关联的Pod 实例,然后生成Service 的 Endpoints 信息,并通过APIServer 写入到 etcd 中

9、接下来,所有 Node 上运行的 Proxy 进程通过 APIServer 查询并监听 Service 对象与 其对应的 Endpoints 信息,建立一个软件方式的负载均衡器来实现 Service 访问到后端 Pod 的流量转发功能。

2、k8s 集群安装

1、kubeadm

kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具。 这个工具能通过两条指令完成一个 kubernetes 集群的部署:

# 创建一个 Master 节点

$ kubeadm init

# 将一个 Node 节点加入到当前集群中

$ kubeadm join <Master 节点的 IP 和端口 >

2、前置要求

一台或多台机器,操作系统 CentOS7.x-86_x64

硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 30GB 或更多

集群中所有机器之间网络互通

可以访问外网,需要拉取镜像

禁止 swap 分区

3、部署步骤

1.在所有节点上安装 Docker 和 kubeadm

2.部署 Kubernetes Master

3.部署容器网络插件

4.部署 Kubernetes Node,将节点加入 Kubernetes 集群中

5.部署 Dashboard Web 页面,可视化查看 Kubernetes 资源

4、环境准备

1、准备工作

  • 我们可以使用 vagrant 快速创建三个虚拟机。虚拟机启动前先设置 virtualbox 的主机网络。现全部统一为 192.168.56.1,以后所有虚拟机都是 56.x 的 ip 地址

  • 设置虚拟机存储目录,防止硬盘空间不足

2、启动三个虚拟机

Vagrantfile:

Vagrant.configure("2") do |config|
   (1..3).each do |i|
        config.vm.define "k8s-node#{i}" do |node|
            # 设置虚拟机的Box
            node.vm.box = "centos/7"

            # 设置虚拟机的主机名
            node.vm.hostname="k8s-node#{i}"

            # 设置虚拟机的IP
            node.vm.network "private_network", ip: "192.168.56.#{99+i}", netmask: "255.255.255.0"

            # 设置主机与虚拟机的共享目录
            # node.vm.synced_folder "~/Documents/vagrant/share", "/home/vagrant/share"

            # VirtaulBox相关配置
            node.vm.provider "virtualbox" do |v|
                # 设置虚拟机的名称
                v.name = "k8s-node#{i}"
                # 设置虚拟机的内存大小
                v.memory = 4096
                # 设置虚拟机的CPU个数
                v.cpus = 4
            end
        end
   end
end
  • 使用我们提供的 vagrant 文件,复制到非中文无空格目录下,运行 vagrant up 启动三个虚拟机。其实 vagrant 完全可以一键部署全部 k8s 集群。 https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster http://github.com/davidkbainbridge/k8s-playground

  • 进入三个虚拟机,开启 root 的密码访问权限。

    进去系统,如第一台k8s-node1

    vagrant ssh k8s-node1
    
    su root		#密码为 vagrant
    
    vi /etc/ssh/sshd_config
    

    修改

    PasswordAuthentication yes

    重启服务

    systemctl  restart sshd.service
    

    所有虚拟机设置为 4 核 4G

    关闭所有机器,全局设定设置net网络

每个机器设置网络连接方式为nat,界面名称为上述创建的NatNetwork,地址一定要随机在生成一个

3、设置 linux 环境(三个节点都执行)

关闭防火墙:

systemctl stop firewalld
systemctl disable firewalld

关闭selinux:

sed -i 's/enforcing/disabled/' /etc/selinux/config 
set enforce 0

关闭 swap:

#关闭sawp分区 (可以不关闭,使用参数--ignore-preflight-errors=swap)

#临时关闭
swapoff -a 

#永久
sed -ri 's/.*swap.*/#&/' /etc/fstab 
#验证,swap 必须为 0;

free -g 

添加主机名与IP 对应关系

cat > /etc/hosts << EOF 10.0.2.15 k8s-node1 10.0.2.4 k8s-node2 10.0..5 k8s-node3 EOF
#指定新的hostname
hostnamectl set-hostname <newhostname>

su 切换过来

将桥接的 IPv4 流量传递到 iptables 的链:

cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF 
sysctl --system

疑难问题:

遇见提示是只读的文件系统,运行如下命令

mount -o remount rw /

date 查看时间 (可选)

yum install -y ntpdate

同步最新时间

ntpdate time.windows.com

时间同步

echo '*/5 * * * * /usr/sbin/ntpdate -u ntp.api.bz' >>/var/spool/cron/root
systemctl restart crond.service
crontab -l

5、所有节点安装Docker、kubeadm、kubelet、kubectl

Kubernetes 默认 CRI(容器运行时)为 Docker,因此先安装 Docker。

1、安装 docker

1、卸载系统之前的 docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2、安装 Docker-CE

源添加

#源添加
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum clean all
yum install -y bash-completion.noarch

安装必须的依赖,系统工具

sudo yum install -y yum-utils

设置 docker repo 的 yum 位置

sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

可以查看版本安装

yum list docker-ce --showduplicates | sort -r

安装 docker,以及 docker-cli,可以指定一下版本

sudo yum install -y docker-ce-18.09.9-3.el7 docker-ce-cli-18.09.9-3.el7 containerd.io
3、配置 docker 加速
sudo mkdir -p /etc/docker
sudo echo -e "{ 
        \n \"registry-mirrors\": [\"https://5955cm2y.mirror.aliyuncs.com\"],\"exec-opts\": [\"native.cgroupdriver=systemd\"]\n}" > /etc/docker/daemon.json


sudo systemctl daemon-reload
sudo systemctl restart docker
4、启动 docker & 设置 docker 开机自启
systemctl enable docker

基础环境准备好,可以给三个虚拟机备份一下;为 node3 分配 16g,剩下的 3g。方便未来测试

2、添加阿里云 yum 源

cat > /etc/yum.repos.d/kubernetes.repo << EOF [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 EOF

拉取flanel镜像

docker pull lizhenliang/flannel:v0.11.0-amd64

3、安装 kubeadm,kubelet 和 kubectl

yum list|grep kube	#检查是否有kube源
yum install -y kubelet-1.17.3 kubeadm-1.17.3 kubectl-1.17.3
systemctl enable kubelet	#开机启动
systemctl start kubelet	#启动

查看kubelet状态:systemctl status kubelet 发现启动不起来,因为其他配置未配置,这里先不管

6、部署k8s-master

1、master 节点初始化

先查看要成为master节点的默认网卡地址:ip addr

如图下面的设置为–apiserver-advertise-address=10.0.2.15

执行命令前可能失败先复制我们准备的master_images.sh文件

master_images.sh:

#!/bin/bash

images=(
	kube-apiserver:v1.17.3
    kube-proxy:v1.17.3
	kube-controller-manager:v1.17.3
	kube-scheduler:v1.17.3
	coredns:1.6.5
	etcd:3.4.3-0
    pause:3.1
)

for imageName in ${images[@]} ; do
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
#   docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName  k8s.gcr.io/$imageName
done

复制到这个要成为master节点的机器中

当前文件可能没有执行的权限使用命令

chmod 700 master_images.sh

执行这个文件下砸镜像

 ./master_images.sh

等待几分钟下载完成,执行docker images查看下载情况

之后执行下面命令

kubeadm init \
--apiserver-advertise-address=10.0.2.15 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version   v1.17.3 \
--service-cidr=10.96.0.0/16  \
--pod-network-cidr=10.244.0.0/16

可能提示swap的错误,关闭即可

或者提示

把这个设置为1即可

echo "1">/proc/sys/net/bridge/bridge-nf-call-iptables
echo "1">/proc/sys/net/bridge/bridge-nf-call-ip6tables

启动成功

由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。可以手动 按照我们的 images.sh 先拉取镜像,

地址变为 registry.aliyuncs.com/google_containers 也可以。

科普:无类别域间路由(Classless Inter-Domain Routing、CIDR)是一个用于给用户分配 IP 地址以及在互联网上有效地路由 IP 数据包的对 IP 地址进行归类的方法。

拉取可能失败,需要下载镜像。

运行完成提前复制:加入集群的令牌,这会成功后先不要删除信息

2、测试 kubectl(主节点执行)

初始化成功后提示

执行一些配置文件

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

//todo

目前 master 状态为 notready。等待网络加入完成即可。

journalctl -u kubelet 

7、 安装 Pod 网络插件(CNI)

$ kubectl apply -f \
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

可能拉去失败,这里我用自己的

kube-flannel.yml

---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp.flannel.unprivileged
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
  privileged: false
  volumes:
    - configMap
    - secret
    - emptyDir
    - hostPath
  allowedHostPaths:
    - pathPrefix: "/etc/cni/net.d"
    - pathPrefix: "/etc/kube-flannel"
    - pathPrefix: "/run/flannel"
  readOnlyRootFilesystem: false
  # Users and groups
  runAsUser:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  # Privilege Escalation
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  # Capabilities
  allowedCapabilities: ['NET_ADMIN']
  defaultAddCapabilities: []
  requiredDropCapabilities: []
  # Host namespaces
  hostPID: false
  hostIPC: false
  hostNetwork: true
  hostPorts:
  - min: 0
    max: 65535
  # SELinux
  seLinux:
    # SELinux is unused in CaaSP
    rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
rules:
  - apiGroups: ['extensions']
    resources: ['podsecuritypolicies']
    verbs: ['use']
    resourceNames: ['psp.flannel.unprivileged']
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes/status
    verbs:
      - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: | { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] }
  net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                      - amd64
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.11.0-amd64
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.11.0-amd64
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-arm64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                      - arm64
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.11.0-arm64
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.11.0-arm64
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-arm
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
   

标签: 40针前置连接器6es7

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台