K8S部署&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/

  • 部署方式的进化


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



2)、架构

1、整体主从方式

2、Master 节点架构

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

3、Node 节点架构

  • kubelet
    • 一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。
    • 负责维护容器的生命周期,同时也负责 Volume(CSI)和网络(CNI)的管理;
  • kube-proxy
    • 负责为 Service 提供 cluster 内部的服务发现和负载均衡;
  • 容器运行环境(Container Runtime)
    • 容器运行环境是负责运行容器的软件。
    • Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI (容器运行环境接口)。
  • fluentd
    • 是一个守护进程,它有助于提供集群层面日志 集群层面的日志

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)
  • Label:标签,用于对象资源的查询,筛选

  • Namespace:命名空间,逻辑隔离

    • 一个集群内部的逻辑隔离机制(鉴权,资源)
    • 每个资源都属于一个 namespace
    • 同一个 namespace 所有资源名不能重复
    • 不同 namespace 可以资源名重复

API:
我们通过 kubernetes 的 API 来操作整个集群。
可以通过 kubectl、ui、curl 最终发送 http+json/yaml 方式的请求给 API Server,然后控制 k8s 集群。k8s 里的所有的资源对象都可以采用 yaml 或 JSON 格式的文件定义或描述

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 部署升级

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 的流量转发功能。

k8s 里的所有的资源对象都可以采用yaml 或JSON 格式的文件定义或描述

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、启动三个虚拟机

Vagrant ssh XXX 进去系统之后
su root	密码为 vagrant
vi	/etc/ssh/sshd_config
修 改 PasswordAuthentication yes/no
重启服务 service sshd restart

所有虚拟机设置为 4 核 4G
设置好 NAT 网络

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

关闭防火墙:
systemctl stop firewalld
systemctl disable firewalld
关闭selinux:
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0
关闭swap:
swapoff -a	临时
sed -ri 's/.*swap.*/#&/' /etc/fstab	永久
free -g 验证,swap 必须为 0;
添加主机名与IP 对应关系
vi /etc/hosts
10.0.2.15 k8s-node1
10.0.2.24 k8s-node2
10.0.2.25 k8s-node3

hostnamectl set-hostname <newhostname>:指定新的hostname 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	同步最新时间

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
安装必须的依赖

sudo yum install -y yum-utils \ device-mapper-persistent-data \
lvm2

设置 docker repo 的 yum 位置

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

安装 docker,以及 docker-cli

sudo yum install -y docker-ce docker-ce-cli containerd.io

3、配置 docker 加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://t5txjkiu.mirror.aliyuncs.com"]
}
EOF
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

3、安装 kubeadm,kubelet 和 kubectl

yum list|grep kube
 
yum install -y	kubelet-1.17.3	kubeadm-1.17.3	kubectl-1.17.3
systemctl enable kubelet systemctl start kubelet

6、部署k8s-master

1、master 节点初始化

$ 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

由于默认拉取镜像地址 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

$ kubectl get nodes 获取所有节点

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

journalctl -u kubelet 查看 kubelet 日志
kubeadm join 10.0.2.15:6443 --token 0xrbjk.nhtfaklmumw1jxob \
--discovery-token-ca-cert-hash sha256:865b566164462b6c61308a4d08b2a1a826aea5294eb7061b5db8ea70ab31c004

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

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

以上地址可能被墙,大家获取上传我们下载好的 flannel.yml 运行即可,同时 flannel.yml 中指定的 images 访问不到可以去 docker hub 找一个
wget yml 的地址
vi 修 改 yml 所有 amd64 的地址都修改了即可。
等待大约 3 分钟
kubectl get pods -n kube-system 查看指定名称空间的 pods
kubectl get pods –all-namespace 查看所有名称空间的 pods

$ ip link set cni0 down 如果网络出现问题,关闭 cni0,重启虚拟机继续测试
执行 watch kubectl get pod -n kube-system -o wide 监控 pod 进度
等 3-10 分钟,完全都是 running 以后继续

8、加入Kubernetes Node

在 Node 节点执行。
向集群添加新节点,执行在 kubeadm init 输出的 kubeadm join 命令:
确保 node 节点成功

token 过期怎么办

kubeadm token create --print-join-command
kubeadm token create --ttl 0 --print-join-command
kubeadm	join --token y1eyw5.ylg568kvohfdsfco --discovery-token-ca-cert-hash sha256: 6c35e4f73f72afd89bf1c8c303ee55677d2cdb1342d67bb23c852aba2efc7c73

执 行 watch kubectl get pod -n kube-system -o wide 监 控 pod 进 度 等 3-10 分钟,完全都是 running 以后使用 kubectl get nodes 检查状态

9、入门操作 kubernetes 集群

1、部署一个 tomcat
kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8
kubectl get pods -o wide 可以获取到 tomcat 信息

2、暴露 nginx 访问
kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort
Pod 的 80 映射容器的 8080;service 会代理 Pod 的 80

3、动态扩容测试
kubectl get deployment
应用升级 kubectl set image (--help 查看帮助)
扩容: kubectl scale --replicas=3 deployment tomcat6
扩容了多份,所有无论访问哪个 node 的指定端口,都可以访问到 tomcat6

4、以上操作的 yaml 获取
参照 k8s 细节

5、删除
kubectl get all
kubectl delete deploy/nginx
kubectl delete service/nginx-service

流程;创建 deployment 会管理 replicas,replicas 控制 pod 数量,有 pod 故障会自动拉起新的 pod

10、安装默认 dashboard

1、部署 dashboard

$ kubectl apply -f
https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommende d/kubernetes-dashboard.yaml
墙的原因,文件已经放在我们的 code 目录,自行上传文件中无法访问的镜像,自行去 docker hub 找

2、暴露 dashboard 为公共访问
默认 Dashboard 只能集群内部访问,修改 Service 为 NodePort 类型,暴露到外部:

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
    name: kubernetes-dashboard
namespace: kube-system
spec:
  type: NodePort
ports:
  - port: 443
    targetPort: 8443
    nodePort: 30001
selector:
  k8s-app: kubernetes-dashboard

访问地址:http://NodeIP:30001

3、创建授权账户

$ kubectl create serviceaccount dashboard-admin -n kube-system
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
$ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
使用输出的 token 登录 Dashboard。

二、K8S 细节

1、kubectl

1、kubectl 文档

https://kubernetes.io/zh/docs/reference/kubectl/overview/

2、资源类型

https://kubernetes.io/zh/docs/reference/kubectl/overview/#资源类型

3、格式化输出

https://kubernetes.io/zh/docs/reference/kubectl/overview/#格式化输出

4、常用操作

https://kubernetes.io/zh/docs/reference/kubectl/overview/#格式化输出

5、命令参考

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands

2、yaml 语法

1、yml 模板

2、yaml 字段解析
参照官方文档

3、入门操作

1、Pod 是什么,Controller 是什么

https://kubernetes.io/zh/docs/concepts/workloads/pods/#pods-and-controllers
Pod 和控制器
控制器可以为您创建和管理多个 Pod,管理副本和上线,并在集群范围内提供自修复能力。例如,如果一个节点失败,控制器可以在不同的节点上调度一样的替身来自动替换 Pod。包含一个或多个 Pod 的控制器一些示例包括:
Deployment
StatefulSet
DaemonSet
控制器通常使用您提供的 Pod 模板来创建它所负责的 Pod

2、Deployment&Service 是什么

3、Service 的意义

1、部署一个 nginx
kubectl create deployment nginx --image=nginx

2、暴露 nginx 访问
kubectl expose deployment nginx --port=80 --type=NodePort

统一应用访问入口; Service 管理一组 Pod。
防止 Pod 失联(服务发现)、定义一组 Pod 的访问策略

现在 Service 我们使用 NodePort 的方式暴露,这样访问每个节点的端口,都可以访问到这个 Pod,如果节点宕机,就会出现问题。

4、labels and selectors

5、Ingress

通过 Service 发现 Pod 进行关联。基于域名访问。
通过 Ingress Controller 实现 Pod 负载均衡
支持 TCP/UDP 4 层负载均衡和 HTTP 7 层负载均衡

步骤:
1)、部署 Ingress Controller
2)、创建 Ingress 规则

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: web
spec:
  rules:
  - host: tomcat6.atguigu.com
     http:
      paths:
        - backend:
           serviceName: tomcat6
           servicePort: 80

如果再部署了 tomcat8;看效果;
kubectl create deployment tomcat8 --image=tomcat:8.5.51-jdk8
kubectl expose deployment tomcat8 --port=88 --target-port=8080 --type=NodePort
kubectl delete xxx 删除指定资源

随便配置域名对应哪个节点,都可以访问 tomcat6/8;因为所有节点的 ingress-controller 路由表是同步的。

6、网络模型

Kubernetes 的网络模型从内至外由四个部分组成:
1、Pod 内部容器所在的网络
2、Pod 所在的网络
3、Pod 和 Service 之间通信的网络
4、外界与 Service 之间通信的网络

4、项目部署

项目部署流程
制作项目镜像(将项目制作为 Docker 镜像,要熟悉 Dockerfile 的编写)
控制器管理 Pod(编写 k8s 的 yaml 即可)
暴露应用
日志监控

三、KubeSphere

默认的 dashboard 没啥用,我们用 kubesphere 可以打通全部的 devops 链路。Kubesphere 集成了很多套件,集群要求较高
https://kubesphere.io/

Kuboard 也很不错,集群要求不高https://kuboard.cn/support/

1、简介

KubeSphere 是一款面向云原生设计的开源项目,在目前主流容器调度平台 Kubernetes 之上构建的分布式多租户容器管理平台,提供简单易用的操作界面以及向导式操作方式,在降低用户使用容器调度平台学习成本的同时,极大降低开发、测试、运维的日常工作的复杂度。

2、安装

1、前提条件

https://kubesphere.io/docs/v2.1/zh-CN/installation/prerequisites/

2、安装前提环境

1、安装 helm(master 节点执行)
Helm 是 Kubernetes 的包管理器。包管理器类似于我们在 Ubuntu 中使用的 apt、Centos 中使用的 yum 或者 Python 中的 pip 一样,能快速查找、下载和安装软件包。Helm 由客户端组件 helm 和服务端组件 Tiller 组成, 能够将一组 K8S 资源打包统一管理, 是查找、共享和使用为 Kubernetes 构建的软件的最佳方式。

1)、安装

curl -L https://git.io/get_helm.sh | bash

墙原因,上传我们给定的 get_helm.sh,chmod 700 然后./get_helm.sh 可能有文件格式兼容性问题,用 vi 打开该 sh 文件,输入:
:set ff
回车,显示 fileformat=dos,重新设置下文件格式:
:set ff=unix 保存退出:
:wq

2)、验证版本

helm version

3)、创建权限(master 执行)
创建 helm-rbac.yaml,写入如下内容

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

应用配置

kubectl apply -f helm-rbac.yaml

2、安装 Tiller(master 执行)

1、初始化
helm init --service-account=tiller --tiller-image=jessestuart/tiller:v2.16.3 --history-max 300
--tiller-image 指定镜像,否则会被墙。大家使用这个镜像比较好

等待节点上部署的 tiller 完成即可

查看所有的pod节点
kubectl get pods --all-namespaces

2、测试

helm install stable/nginx-ingress --name nginx-ingress helm ls
helm delete nginx-ingress

3、使用语法
创建一个 chart 范例
helm create helm-chart
检查 chart 语法
helm lint ./helm-chart
使用默认 chart 部署到 k8s
helm install --name example1 ./helm-chart --set service.type=NodePort
kubectl get pod 查看是否部署成功

3、安装 OpenEBS(master 执行)
https://kubesphere.io/docs/v2.1/zh-CN/appendix/install-openebs/

kubectl describe node k8s-node1 | grep Taint #确定 master 节点是否有 taint
kubectl taint nodes k8s-node1 node-role.kubernetes.io/master:NoSchedule- #取消 taint
kubectl apply -f https://openebs.github.io/charts/openebs-operator-1.5.0.yaml #安装 openebs

查看效果
kubectl get sc -n openebs

将 openebs-hostpath 设置为 默认的 StorageClass:
kubectl patch storageclass openebs-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

至此,OpenEBS 的 LocalPV 已作为默认的存储类型创建成功。由于在文档开头手动去掉了 master 节点的 Taint,我们可以在安装完 OpenEBS 后将 master 节点 Taint 加上,避免业务相关的工作负载调度到 master 节点抢占 master 资源
kubectl taint nodes k8s-node1 node-role.kubernetes.io=master:NoSchedule

3、最小化安装kubesphere

https://v2-1.docs.kubesphere.io/docs/zh-CN/installation/install-on-k8s/

若您的集群可用的资源符合 CPU > 1 Core,可用内存 > 2 G,可以参考以下命令开启

KubeSphere 最小化安装:
kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-minimal.yaml

查看安装日志,请耐心等待安装成功。
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f

Console: http://10.0.2.15:30880
Account: admin
Password: P@88w0rd

posted @ 2023-02-21 23:24  冰枫丶  阅读(246)  评论(0编辑  收藏  举报