kubenates(k8s)部署全家桶
k8s的部署,rancher结合k8s,grafana+loki相关组件收集容器的日志。
一、安装k8s集群
前置准备:准备两台2核cpu、2G内存的服务器
本例的master和node1节点的ip分别为[192.168.106.137]、[192.168.106.138]
1.前置配置
# 每个节点分别设置对应主机名
hostnamectl set-hostname master #master节点设置
hostnamectl set-hostname node1 #node1节点设置
# 所有节点都修改 hosts
vi /etc/hosts
192.168.106.138 node1
192.168.106.137 master
# 所有节点关闭 SELinux
setenforce 0
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
# 所有节点确保防火墙关闭
systemctl stop firewalld
systemctl disable firewalld
# 所有节点关闭swap分区
sudo swapoff -a #临时关闭
vi /etc/fstab #永久关闭 如果选择永久关闭的话要重启或者再执行一次临时关闭
#注释掉以下内容
/dev/mapper/cl-swap swap swap defaults 0 0
# 所有节点开启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
【无视下方内容,直接到添加安装源】
# 无视这个内容,直接到添加安装源
1.设置允许路由转发、不对bridge的数据进行处理(所有节点) --> 这步与后面的错误情况之一比较类似
vi /etc/sysctl.d/k8s.conf
#内容如下
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
#执行文件
sysctl -p /etc/sysctl.d/k8s.conf
2.添加安装源(所有节点)
# 添加 k8s 安装源
cat <<EOF > kubernetes.repo
[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
mv kubernetes.repo /etc/yum.repos.d/
# 安装yum工具
yum -y install yum-utils
# 添加 Docker 安装源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装所需组件(所有节点)
yum install -y kubelet-1.18.6 kubectl-1.18.6 kubeadm-1.18.6 docker-ce-18.03.1.ce
注意,kubelet 1.24 以上的版本会报错
启动 kubelet、docker,并设置开机启动(所有节点)
systemctl enable kubelet
systemctl start kubelet
systemctl enable docker
systemctl start docker
修改 docker 配置(所有节点)
# kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了
cat <<EOF > daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://ud6340vz.mirror.aliyuncs.com"]
}
EOF
mv daemon.json /etc/docker/
# 重启生效
systemctl daemon-reload
systemctl restart docker
3.用 kubeadm 初始化集群(仅在主节点跑)
# --pod-network-cidr 10.244.0.0/16 可以不指定,默认似乎就是这个
kubeadm init --image-repository=registry.aliyuncs.com/google_containers --pod-network-cidr 10.244.0.0/16
# 复制授权文件,以便 kubectl 可以有权限访问集群。 如果你其他节点需要访问集群,需要从主节点复制这个文件过去其他节点
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 保存密钥,如图。如果忘记了执行如下命令重新获取
kubeadm token create --print-join-command
# 初始化失败了可以用 kubeadm reset 重置
# 重置方法 链接
https://www.cnblogs.com/shunzi115/p/14776507.html
# 如果出现/proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
# 将桥接的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
4.把工作节点加入集群(所有node工作节点)
# 刚刚保存的那串密钥
kubeadm join 192.168.106.137:6443 --token xxx --discovery-token-ca-cert-hash xxx
5.安装网络插件,否则 node 是 NotReady 状态(主节点跑)
执行如下命令的话,它会在每个节点下载安装两个docker镜像,【flannel】、【flannel-cni-plugin】
如果有本地文件的话,可以提前 docker load -i 一下
#安装网络插件 ps:很有可能国内网络访问不到这个资源,你可以网上找找国内的源安装 flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#本地有yml文件的话
kubectl apply -f kube-flannel.yml
# flannel如果出现卡在CrashLoopBackOff状态
kubectl logs -n kube-flannel kube-flannel-ds-7qc82
# 查看对应日志 一般都是这个Error registering network: failed to acquire lease: node “master“ pod cidr not assigne
# 解决办法
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
#找到spec->containers->command
#增加参数:
--allocate-node-cidrs=true
--cluster-cidr=10.244.0.0/16 #这个一般在kubeadm init的时候可以指定 不指定就是这个默认值
# 如果上面的插件安装失败,可以选用 Weave,下面的命令二选一就可以了。
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
kubectl apply -f http://static.corecore.cn/weave.v2.8.1.yaml
# 更多其他网路插件查看下面介绍,自行网上找 yaml 安装
https://blog.csdn.net/ChaITSimpleLove/article/details/117809007
6.查看节点,要在主节点查看(其他节点有安装 kubectl 也可以查看)
kubectl get nodes
二.部署应用到集群中
1.部署服务
直接命令运行
kubectl run testapp --image=helloworldcontainers/java-spring-boot-hello-world:latest
helloworldcontainers/java-spring-boot-hello-world:latest : 一个helloworld的服务
执行命令将pod端口映射到本地:kubectl port-forward testapp 8090:8080 --address 0.0.0.0
访问地址:http://ip:8090
pod运行
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: docker镜像地址 # 镜像
Deployment运行
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: test-k8s
spec:
replicas: 2 #部署几个pod
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: test-k8s
# 定义 Pod 相关数据
template:
metadata:
labels:
app: test-k8s
spec:
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: docker镜像地址 # 镜像
2.结合harbor使用的Deployment(simpleapp.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: simpleapp-k8s
spec:
replicas: 2
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: simpleapp-k8s
# 定义 Pod 相关数据
template:
metadata:
labels:
app: simpleapp-k8s
spec:
# 定义容器,可以多个
containers:
- name: simpleapp-k8s # 容器名字
image: 192.168.106.130:85/demo/simple:v1 #harbor镜像地址
imagePullSecrets:
- name: harborlogin #下方secret的name
上方harbor需要登入的密钥(secret.yaml)
apiVersion: v1
kind: Secret
metadata:
name: harborlogin
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEwNi4xMzA6ODUiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
#注意 需要在每个节点都要添加harbor免密,否则在创建deployment的时候会拉取镜像失败
#该json文件在执行docker login 后会生成
#上方的密钥为下方json文件的base64编码
cat ~/.docker/config.json
cat ~/.docker/config.json |base64 -w 0
#将secret.yaml装载到k8s
kubectl create -f secret.yaml
#查看密钥
kubectl get secret
3.一些命令
# 部署应用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看所有pod
kubectl get pod --all-namespaces #等效于 kubectl get pod -A
# 查看指定命名空间pod(比如kube-system)
kubectl get pod -n kube-system
# 查看 pod
kubectl get pod -o wide
# 查看 pod 详情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name
# 进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。
kubectl exec -it pod-name -- bash
# 伸缩扩展副本
kubectl scale deployment test-k8s --replicas=5
# 把集群内端口映射到节点 增加--address虚拟机就可以在节点访问容器了 否则只能在pod里访问
kubectl port-forward pod-name 8090:8080 --address 0.0.0.0
# 查看历史
kubectl rollout history deployment test-k8s
# 回到上个版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision=2
# 删除部署
kubectl delete deployment test-k8s
# -------------------------更多命令-------------------------------
# 查看全部
kubectl get all
# 重新部署
kubectl rollout restart deployment test-k8s
# 命令修改镜像,--record 表示把这个命令记录到操作历史中
kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record
# 暂停运行,暂停后,对 deployment 的修改不会立刻生效,恢复后才应用设置
kubectl rollout pause deployment test-k8s
# 恢复
kubectl rollout resume deployment test-k8s
# 输出到文件
kubectl get deployment test-k8s -o yaml >> app2.yaml
# 删除全部资源
kubectl delete all --all
如果你运行 kubectl describe pod/pod-name
发现 Events 中有下面这个错误
networkPlugin cni failed to set up pod "test-k8s-68bb74d654-mc6b9_default" network: open /run/flannel/subnet.env: no such file or directory
在每个节点创建文件/run/flannel/subnet.env
写入以下内容,配置后等待一会就好了(可以重启docker?)
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
更多官网关于 Deployment 的介绍
将 Pod 指定到某个节点运行:nodeselector
限定 CPU、内存总量:文档
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
工作负载分类
- Deployment
适合无状态应用,所有pod等价,可替代 - StatefulSet
有状态的应用,适合数据库这种类型。 - DaemonSet
在每个节点上跑一个 Pod,可以用来做节点监控、节点日志收集等 - Job & CronJob
Job 用来表达的是一次性的任务,而 CronJob 会根据其时间规划反复运行。
现存问题
- 每次只能访问一个 pod,没有负载均衡自动转发到不同 pod
- 访问还需要端口转发
- Pod 重创后 IP 变了,名字也变了
下节我们讲解如何解决。
三、创建 Service
创建 一个 Service,通过标签test-k8s
跟对应的 Pod 关联上
service.yaml
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s #注意这个标签绝对要正确 不然无法访问
type: ClusterIP
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
应用配置 kubectl apply -f service.yaml
查看服务 kubectl get svc
查看服务详情 kubectl describe svc test-k8s
,可以发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点。
服务的默认类型是ClusterIP
,只能在集群内部访问,我们可以进入到 Pod 里面访问:
kubectl exec -it pod-name -- bash
curl http://test-k8s:8080
如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 8888:8080
对外暴露服务
上面我们是通过端口转发的方式可以在外面访问到集群里的服务,如果想要直接把集群服务暴露出来,我们可以使用NodePort
和 Loadbalancer
类型的 Service
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s #注意这个标签绝对要正确 不然无法访问
# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
应用配置 kubectl apply -f service.yaml
此刻可以选择节点ip访问 http://192.168.106.137:31000/
(注意,暴露service的服务得是deployment模式运行的!因为deployment模式有标签选择,跟service的标签选择对应上)
在节点内部,我们也可以 curl http://localhost:31000/
访问到应用
并且是有负载均衡的。
pod报错解决
如果出现主节点无法访问service、其他节点可以访问 ->
解决方案
四、rancher部署结合k8s
前置准备:
准备一台新的服务器
执行一遍k8s的前置配置(hosts那些)
linux务必要有4G内存 3G应该也可以
- 安装并运行docker
- 拉取rancher
//注意 一定要是这个版本 其他版本可能会不行 原因如下方链接
//https://blog.k4nz.com/db239dfdf4d4d2319fcaaad89ae25311/
docker pull rancher/rancher:v2.5.12
//如果有本地的tar文件,可以直接docker load一下
- 运行rancher
docker run --privileged --name=rancher -d --restart=unless-stopped -p 80:80 -p 443:443 -v /rancherdata:/var/lib/rancher rancher/rancher:v2.5.12
- 打开rancher网页(设置密码,其他默认配置)
https://ip地址
- 添加集群,选择导入集群 选择无证书的那个 然后复制到k8s主节点运行(第一次会失败,再来一次) 完事
运行实际上是在node节点安装rancher-agent镜像,所以如果有本地tar文件,也可以先load一下
- 网页中会显示xx不健康,可以百度解决,是一个配置的问题来着,不过没必要。。。
五、helm安装loki日志收集+grafana展示
1.安装helm
#以下在master节点执行
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
#安装失败的话 手动安装
tar -zxvf helm-v3.11.3-linux-amd64.tar.gz
cp -a linux-amd64/helm /usr/local/bin/
chmod a+x /usr/local/bin/helm
2.添加repo并更新(这步要等一会)
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
3.创建loki命名空间
kubectl create namespace loki
4.安装loki
# 注意这里后面是 -stack 的是默认打包好在一起的,没stack的是默认只有 loki 的,自定义安装请参考官网给出的命令
helm upgrade --install loki --namespace=loki grafana/loki-stack
5.安装grafana
# 安装grafana
kubectl apply -f grafana.yaml
# 打开grafana网页,选择loki数据源,导入dashbord面板
# 文件在网盘中(Loki_Kubernetes_Logs-1681870713163)
6.打开grafana首页,选择loki数据源,默认账号密码admin
192.168.106.137:32554
ps:这个端口是随机的,执行命令kubectl get svc
查看
7.自行diy面板或导入模板
模板地址https://grafana.com/grafana/dashboards/
我的模板json文件
选择上传json文件导入。(参数那些要重新设置一下loki源),不然如下图没数据
点击上图中的设置按钮(在选择时间范围的左边那个)
结果
如下为grafana.yaml文件
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: grafana
name: grafana
namespace: default
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10555
fsGroup: 10555
containers:
- name: grafana
image: grafana/grafana:9.2.4
imagePullPolicy: IfNotPresent
env:
- name: GF_AUTH_BASIC_ENABLED
value: "true"
- name: GF_AUTH_ANONYMOUS_ENABLED
value: "false"
readinessProbe:
httpGet:
path: /login
port: 3000
volumeMounts:
- mountPath: /var/lib/grafana
name: grafana-data-volume
ports:
- containerPort: 3000
protocol: TCP
volumes:
- name: grafana-data-volume
emptyDir: {}
---
kind: Service
apiVersion: v1
metadata:
labels:
app: grafana
name: grafana-service
namespace: default
spec:
ports:
- port: 3000
targetPort: 3000
selector:
app: grafana
type: NodePort
更多推荐
所有评论(0)