k8s之路-Rancher
还是先碎碎念一下,近期需要在内部环境搭建一套k8s,暂时记录一下,后续需要的话再整理一个体系
官方文档:http://docs.rancher.cn/docs/rancher2.5/overview/_index 有问题,找文档
一、Rancher、Docker、K8S等介绍(可略)
1.1 什么是 Rancher?
Rancher 是为使用容器的公司打造的容器管理平台。Rancher 简化了使用 Kubernetes 的流程,开发者可以随处运行 Kubernetes(Run Kubernetes Everywhere),满足 IT 需求规范,赋能 DevOps 团队。
Rancher 1.x 最初是为了支持多种容器编排引擎而构建的,其中包括 Rancher 自己的容器编排引擎 Cattle。但随着 Kubernetes 在市场上的兴起,Rancher 2.x 已经完全转向了 Kubernetes。Rancher 2.x 可以部署和管理在任何地方运行的 Kubernetes 集群。
Rancher 可以创建来自 Kubernetes 托管服务提供商的集群,自动创建节点并安装 Kubernetes 集群,或者导入任何已经存在的 Kubernetes 集群。
Rancher 通过支持集群的身份验证和基于角色的访问控制(RBAC),使系统管理员能够从一个位置控制全部集群的访问。Rancher 可以对集群及其资源进行详细的监控和并在需要时发送告警,也可以将容器日志发送给外部日志系统,并通过应用商店与 Helm 集成。如果您具有外部 CI/CD 流水线系统,则可以将其与 Rancher 对接,如果没有,Rancher 也提供了简单易用的流水线来帮助您自动部署和升级工作负载。除此之外,Rancher 还有很多开箱即用的功能来帮助您更好的管理集群和业务应用,例如多集群应用,全局 DNS,服务网格,安全扫描,集群模版和基于 OPA 的策略管理等功能。
总而言之,Rancher 是一个全栈式的 Kubernetes 容器管理平台,也是一个可以在任何地方都能成功运行 Kubernetes 的工具。
1.2Run Kubernetes Everywhere
Kubernetes 已经成为了容器管理的标准。大多数云服务和虚拟服务的提供商现在将 Kubernetes 作为标准的基础设施。用户可以使用 Rancher Kubernetes Engine(简称 RKE),或其他云服务提供商的容器服务,如 GKE、AKS、 EKS 等,创建 Kubernetes 集群。用户也可以将已有集群导入 Rancher,集中管理。
1.3满足 IT 需求规范
Rancher 支持集中化认证、权限控制、监控和管理所有 Kubernetes 集群。您可以使用 Rancher 完成以下操作:
使用活动目录(Active Directory)的认证信息访问云端 Kubernetes 集群,如 GKE、AKS、EKS 等。
设置用户、用户组、项目组、集群、云服务的权限控制策略和安全策略。
一站式监控您名下所有集群的健康状态。
1.4赋能 DevOps 开发团队
Rancher 提供了一个简单直接的用户界面给 DevOps 工程师管理他们的应用程序。用户不需要对 Kubernetes 有深入的了解,即可使用 Rancher。
Rancher 应用商店包含了一套内置的 DevOps 开发工具。Rancher 通过了一些云原生的生态系统认证,包括安全工具、监控系统、容器镜像、存储和网络驱动等。
以下的示意图讲述了 Rancher 在 IT 管理团队和 DevOps 开发团队之间扮演的角色。DevOps 团队把他们的应用部署在他们选择的云上面,可以是公有云,也可以是私有云。IT 管理员负责管理用户、集群、多云之间的权限。
1.5Rancher API Server 的功能
Rancher API Server 是基于嵌入式 Kubernetes API Server 和 ETCD 数据库建立的,它提供了以下功能:
1.6授权和角色权限控制#
用户管理: Rancher API server 除了管理用户在公司内部的使用的认证信息之外,还管理用户访问外部服务所需的认证信息,如登录活动目录或 GitHub 所需的账号密码。
授权: Rancher API server 负责管理权限控制策略 和 安全策略。
1.7使用 Kubernetes 的功能
运行 Kubernetes 集群: Rancher API server 可以在已有节点上运行 Kubernetes 集群 ,或对 Kubernetes 进行版本升级。
应用商店管理: Rancher 可以使用Helm Charts 应用商店重复部署应用。
项目管理: 项目,是 Rancher 中的一个概念,Kubernetes 中并没有这个概念。项目由一个集群内的多个命名空间和多个访问控制策略组成,允许用户以组为单位,一次管理多个命名空间,对其进行 Kubernetes 相关操作。Rancher 用户界面提供了 项目管理 和 项目内应用管理 两个功能。
流水线: 流水线 可以帮助开发者快速高效地上线新软件。Rancher 支持给每一个项目单独配置流水线。
Istio: Rancher 与 Istio 集成,管理员或集群所有者可以将 Istio 交给开发者,然后开发者使用 Istio 执行安全策略,排查问题,或为快速发布、灰度发布和 A/B 测试进行流量控制。
1.8配置云端基础信息
同步节点信息: Rancher API server 可以同步集群内所有节点的信息。
配置云端基础信息: 当 Rancher 与云服务提供商配置完了之后,可以在云端动态配置新节点和持久化存储。
1.9查看集群信息
日志: Rancher 可以跟多种主流日志工具集成,您可以设置 Rancher 日志。
监控: 使用 Rancher,您可以通过 Prometheus 监控集群节点、Kubernetes 组件、软件部署的状态和进度。您可以设置 集群监控 或 项目监控。
告警信息: 您需要随时知道集群和项目的计划和非计划事件,才可以提高公司的运行效率。
1.10关于 Docker
Docker 是容器打包和运行时系统的标准,主要用于管理各个节点上的容器。开发者在 Dockerfiles 中构建容器镜像,上传到镜像仓库中,用户只需从镜像仓库下载该镜像文件,就可以开始使用。
镜像仓库分为公有镜像仓库和私有镜像仓库。Docker Hub 是市面上主流的公有镜像仓库。除了公有镜像仓库以外,很多企业为了节省网络带宽和提高镜像资源使用率,也会配置自己的私有镜像仓库,提供给企业内部员工使用。
1.11关于 Kubernetes
Kubernetes 是容器和集群管理的标准。YAML 文件规定了组成一个应用所需的容器和其他资源。Kubernetes 提供了调度、伸缩、服务发现、健康检查、密文管理和配置管理等功能。
Kubernetes 集群是什么
Kubernetes 集群 是由多个计算机(可以是物理机、云主机或虚拟机)组成的一个独立系统,通过 Kubernetes 容器管理系统,实现部署、运维和伸缩 Docker 容器等功能,它允许您的组织对应用进行自动化运维。
Kubernetes 集群中的节点角色
节点 是集群内的一个计算资源,节点可以是裸金属服务器或虚拟机。根据节点的角色不同,我们把节点分为三类:etcd 节点、controlplane 节点和worker 节点,下文会讲解三种节点的功能。一个 Kubernetes 集群至少要有一个 etcd 节点、一个 controlplane 节点 和 一个 worker 节点。
etcd 节点
etcd 节点 的主要功能是数据存储,它负责存储 Rancher Server 的数据和集群状态。 Kubernetes 集群的状态保存在etcd 节点 中,etcd 节点运行 etcd 数据库。etcd 数据库组件是一个分布式的键值对存储系统,用于存储 Kubernetes 的集群数据,例如集群协作相关和集群状态相关的数据。建议在多个节点上运行 etcd,保证在节点失效的情况下,可以获取到备份的集群数据。
etcd 更新集群状态前,需要集群中的所有节点通过 quorum 投票机制完成投票。假设集群中有 n 个节点,至少需要 n/2 + 1(向下取整) 个节点同意,才被视为多数集群同意更新集群状态。例如一个集群中有 3 个 etcd 节点,quorum 投票机制要求至少两个节点同意,才会更新集群状态。
集群应该含有足够多健康的 etcd 节点,这样才可以形成一个 quorum。对含有奇数个节点的集群而言,每新增一个节点,就会增加通过 quorum 投票机制所需节点的数量。
一般情况下,集群中只要配置三个 etcd 节点就能满足小型集群的需求,五个 etcd 节点能满足大型集群的需求。
Controlplane 节点
Controlplane 节点上运行的工作负载包括:Kubernetes API server、scheduler 和 controller mananger。这些节点负载执行日常任务,从而确保您的集群状态和您的集群配置相匹配。因为 etcd 节点保存了集群的全部数据,所以 Controlplane 节点是无状态的。虽然您可以在单个节点上运行 Controlplane,但是我们建议在两个或以上的节点上运行 Controlplane,以保证冗余性。另外,因为 Kubernetes 只要求每个节点至少要分配一个角色,所以一个节点可以既是 Controlplane 节点,又是 etcd 节点。
Worker 节点
worker 节点运行以下应用:
Kubelet: 监控节点状态的 Agent,确保您的容器处于健康状态。
工作负载: 承载您的应用和其他类型的部署的容器和 Pod。
Worker 节点也运行存储和网络驱动;有必要时也会运行应用路由控制器(Ingress Controller)。Rancher 对 Worker 节点的数量没有限制,您可以按照实际需要创建多个 Worker 节点。
1.12关于 Helm
Helm 是安装 Rancher 高可用集群时会用到的工具。
Helm 是 Kubernetes 的软件包管理工具。Helm chart 为 Kubernetes YAML manifest 文件提供了模板语法。通过 Helm,可以创建可配置的 Deployment YAML,而不是只能用静态的 YAML。如果您想了解更多关于如何创建自己的应用商店应用(catalog),请查阅Helm 官方网站。
二、部署rancher以及k8s
以下操作均以单节点作为演示
2.1所需环境
Centos 7.x * 2
docker
kubernetes
docker
rancher
2.2硬件要求
2.3关闭SELinux(所有节点)
查看SELinux状态:
[root@node ~]# sestatus
修改SELINUX为disabled:
[root@node ~]# vim /etc/sysconfig/selinux
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
2.4关闭防火墙(所有节点)
查看防火墙状态:
[root@node ~]# systemctl status firewalld.service
关闭防火墙:
[root@node ~]# systemctl stop firewalld.service
设置开机不启动:
[root@node ~]# systemctl disable firewalld.service
查看是否成功:
[root@node ~]# systemctl is-enabled firewalld.service
disabled
2.5同步时间
[root@node ~]# yum -y install ntp
启动服务,查看状态并设置开机自启
[root@node ~]# systemctl start ntpd.service
[root@node ~]# systemctl status ntpd.service
● ntpd.service - Network Time Service
Loaded: loaded (/usr/lib/systemd/system/ntpd.service; disabled; vendor preset: disabled)
Active: active (running) since Mon 2020-03-02 15:41:28 CST; 23h ago
Main PID: 3909 (ntpd)
CGroup: /system.slice/ntpd.service
└─3909 /usr/sbin/ntpd -u ntp:ntp -g
Mar 02 15:41:28 master ntpd[3909]: Listen normally on 4 lo ::1 UDP 123
Mar 02 15:41:28 master ntpd[3909]: Listen normally on 5 eno1 fe80::7b94:c6e6:5673:c105 UDP 123
Mar 02 15:41:28 master ntpd[3909]: Listening on routing socket on fd #22 for interface updates
Mar 02 15:41:28 master systemd[1]: Started Network Time Service.
Mar 02 15:41:28 master ntpd[3909]: 0.0.0.0 c016 06 restart
Mar 02 15:41:28 master ntpd[3909]: 0.0.0.0 c012 02 freq_set kernel 0.000 PPM
Mar 02 15:41:28 master ntpd[3909]: 0.0.0.0 c011 01 freq_not_set
Mar 02 15:41:35 master ntpd[3909]: 0.0.0.0 c614 04 freq_mode
Mar 02 15:58:21 master ntpd[3909]: 0.0.0.0 0612 02 freq_set kernel 8.697 PPM
Mar 02 15:58:21 master ntpd[3909]: 0.0.0.0 0615 05 clock_sync
[root@node ~]# systemctl enable ntpd.service
2.6修改节点名称(所有节点)
方便通过名称来查找相应节点
[root@node ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.105.137 node
192.168.105.191 node1
2.7安装Docker
- 卸载docker旧版本:
[root@node ~]# sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
- 安装相关工具类:
[root@node ~]# sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- 配置docker仓库:
[root@node ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@node ~]# cp docker-ce.repo /etc/yum.repos.d/
[root@node ~]# yum clean all
[root@node ~]# yum make cache
- 安装docker
[root@node ~]# sudo yum install docker-ce docker-ce-cli containerd.io
- 启动,并设置开机自启
[root@node ~]# sudo systemctl start docker
[root@node ~]# sudo systemctl enable docker
2.8 安装rancher
如果持久化使用,建议挂载目录到宿主机
[root@node ~]# docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher:stable
2.9登录rancher
登录设置好的端口,输入admin密码,选择集群,点击下一步
登陆进入后我们可以看到2.5版本特性
在右下角↘可以选择中文,我们切换一下
查看界面可以看到本机local的集群K3S
2.10 创建k8s集群
点击右上角添加集群
选择自定义添加
输入自定义名称
这里有个私仓配置,但我们现在不配合,在后面步骤配置,然后接着点下一步
这里把所有的勾选一下,可以看到他让我们把下面的命令输入到子节点
我们在子节点输入等待即可,一般不会出什么问题,如果有问题可以留言解决,成功了可以看到仪表盘
2.11 安装 kubectl(主节点)
默认的rancher集群的node上,是没有kubectl命令的,没有了命令行感觉没了灵魂,有时候用起来也很麻烦
这里我们下载kubectl 1.20.0,地址为:https://storage.googleapis.com/kubernetes-release/release/v1.20.0/bin/linux/amd64/kubectl
由于众所周知网络问题可以到摆渡云下载
链接: https://pan.baidu.com/s/1iSDDnW-7K5DNf5xMxkV9ug 提取码: z8yp
我们把下载好的传到主节点下,执行
[root@node ~]# chmod +x ./kubectl
[root@node ~]# mv ./kubectl /usr/local/bin/kubectl
测试一下
[root@node ~]# kubectl version --client
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
然后我们来连接一下集群,点击Kubeconfig文件
可以看见提示:将配置保存到~/.kube/config,我们创建一下,然后点击复制到剪贴板进行复制到文件
进行测试一下:
[root@node ~]# kubectl get nodes
三、rancher配置私仓
我们使用rancher大多数都是内部环境,基本都会用到Harbor私仓
那么我们怎么用rancher来进行拉取镜像,这里再说一下Harbor两种部署方式来进行拉取
一种是本地已有安装的了Harbor私仓,方法与镜像拉取上传见我另一篇文章:k8s之路-harbor私仓部署
如果是自己部署的Harbor私仓,需要在自己的私仓中上传Rancher的所用到的镜像
还可以使用Rancher商店中的Harbor来进行部署,前提是需要有域名,也可以使用修改host的方式但是不推荐
点击项目/命名空间
新建一个项目后点击应用商店,点击启动
可以看到有很多耳熟能详的应用,我们点击Harbor
有两处需要配置的地方 一个是密码,另一个是域名以及证书
然后回到仪表盘,点击子节点 ··· 点击升级
选择启用,输入用户名密码
等待安装即可
四、部署应用
私仓部署完成我们就可以新建应用了,新建一个命名空间,我这里以nginx举例
进去后 点击升级,编辑一下配置,改成4c4000M
然后点击部署
输入名称,nginx的镜像地址,容器端口以及端口映射,我这里主机端口选择随机,然后点击启动
部署中...
可以看到已经成功,可执行后续操作
我们看一下站点是否启动成功
也可以进入pod可以查看应用启动情况
可以发现在rancher上部署项目比起使用kubectl命令或者新建YAML简单的多,当然我们也可以使用YAML进行部署
我们来看一下刚刚部署完的nginx的YAML
apiVersion: v1
kind: Pod
metadata:
annotations:
cattle.io/timestamp: "2021-09-06T01:38:58Z"
cni.projectcalico.org/podIP: 10.42.0.64/32
cni.projectcalico.org/podIPs: 10.42.0.64/32
field.cattle.io/ports: '[[{"containerPort":80,"dnsName":"nginx-nodeport","hostPort":0,"kind":"NodePort","name":"nginx","protocol":"TCP","sourcePort":0}]]'
kubernetes.io/limit-ranger: 'LimitRanger plugin set: cpu, memory request for container
nginx; cpu, memory limit for container nginx'
creationTimestamp: "2021-09-06T01:38:59Z"
generateName: nginx-66699557-
labels:
pod-template-hash: "66699557"
workload.user.cattle.io/workloadselector: deployment-test-nginx
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:cattle.io/timestamp: {}
f:field.cattle.io/ports: {}
f:generateName: {}
f:labels:
.: {}
f:pod-template-hash: {}
f:workload.user.cattle.io/workloadselector: {}
f:ownerReferences:
.: {}
k:{"uid":"76322e7f-7538-459a-a297-1b25087a044c"}:
.: {}
f:apiVersion: {}
f:blockOwnerDeletion: {}
f:controller: {}
f:kind: {}
f:name: {}
f:uid: {}
f:spec:
f:containers:
k:{"name":"nginx"}:
.: {}
f:image: {}
f:imagePullPolicy: {}
f:name: {}
f:ports:
.: {}
k:{"containerPort":80,"protocol":"TCP"}:
.: {}
f:containerPort: {}
f:name: {}
f:protocol: {}
f:resources:
.: {}
f:limits:
f:cpu: {}
f:memory: {}
f:requests:
f:cpu: {}
f:memory: {}
f:securityContext:
.: {}
f:allowPrivilegeEscalation: {}
f:capabilities: {}
f:privileged: {}
f:readOnlyRootFilesystem: {}
f:runAsNonRoot: {}
f:stdin: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:tty: {}
f:dnsPolicy: {}
f:enableServiceLinks: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:terminationGracePeriodSeconds: {}
manager: kube-controller-manager
operation: Update
time: "2021-09-06T01:38:59Z"
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
f:cni.projectcalico.org/podIP: {}
f:cni.projectcalico.org/podIPs: {}
manager: calico
operation: Update
time: "2021-09-06T01:39:09Z"
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:status:
f:conditions:
k:{"type":"ContainersReady"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Initialized"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Ready"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
f:containerStatuses: {}
f:hostIP: {}
f:phase: {}
f:podIP: {}
f:podIPs:
.: {}
k:{"ip":"10.42.0.64"}:
.: {}
f:ip: {}
f:startTime: {}
manager: kubelet
operation: Update
time: "2021-09-06T01:39:22Z"
name: nginx-66699557-72pl4
namespace: test
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: nginx-66699557
uid: 76322e7f-7538-459a-a297-1b25087a044c
resourceVersion: "2782431"
uid: ac37e50a-69b4-4ac9-a310-4a9b575c79eb
spec:
containers:
- image: 10.10.10.10:12345/devops/nginx:latest
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
name: nginx
protocol: TCP
resources:
limits:
cpu: 4m
memory: 4000Mi
requests:
cpu: 4m
memory: 4000Mi
securityContext:
allowPrivilegeEscalation: false
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
runAsNonRoot: false
stdin: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
tty: true
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-cf5st
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: znyw-app02-10-133-206-37
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: default-token-cf5st
secret:
defaultMode: 420
secretName: default-token-cf5st
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2021-09-06T01:38:59Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2021-09-06T01:39:22Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2021-09-06T01:39:22Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2021-09-06T01:38:59Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: docker://217788043fbe983ffd9b12ee4ff366b45175e7e2b23213311f0a16c738219def
image: 10.10.10.10:12345/devops/nginx:latest
imageID: docker-pullable://10.10.10.10:12345/devops/nginx@sha256:3f13b4376446cf92b0cb9a5c46ba75d57c41f627c4edb8b635fa47386ea29e20
lastState: {}
name: nginx
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2021-09-06T01:39:21Z"
hostIP: 10.10.10.10
phase: Running
podIP: 10.42.0.64
podIPs:
- ip: 10.42.0.64
qosClass: Guaranteed
startTime: "2021-09-06T01:38:59Z"
我们切到服务发现可以看见nginx生成了两个Service,nginx服务类型为 ClusterIP,nginx-nodeport服务服务类型为Node IP,我们访问主机+端口映射为Node IP模式,ClusterIP类型可通过pod中互相访问,Pod IP为Node IP集群ip。
这里简单说一下
Node IP:Node节点的IP地址,即物理网卡的IP地址。
Pod IP:Pod的IP地址,即docker容器的IP地址,此为虚拟IP地址。
Cluster IP:Service的IP地址,此为虚拟IP地址。
五、负载均衡
我们找到负载均衡标签,点击添加规则
填入名称,自定义端口,域名
然后我们点保存
找到节点机器,修改hosts
[root@node1 ~]# vim /etc/hosts
然后再修改一下访问机器的hosts,再访问一下
没问题了