参见
kubernetes 的安装与部署
https://www.jianshu.com/p/a4ec985977c2
解决:手动安装 yum install -y libnetfilter_cthelper
解决:yum remove kubernetes-client-1.5.2-0.7.git269f928.el7.centos.aarch64
kubeadm init
--image-repository registry.aliyuncs.com/google_containers
--apiserver-advertise-address=192.168.197.10
--service-cidr=10.222.0.0/16
--pod-network-cidr=10.244.0.0/16
提示如下:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.197.10:6443 --token g01ldy.ikqrqrp2pgm18t4y
--discovery-token-ca-cert-hash sha256:62ce23cd9b76c5409fec58f4a2b37e083fefc0204386d2d95546fe0b02109b31
根据提示然后执行下列命令
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
#如果是root用户,执行下列命令
export KUBECONFIG=/etc/kubernetes/admin.conf
# 在master 主节点上运行命令,刷新 token
kubeadm token create --print-join-command
pod并不等于容器。一个pod可以由多个容器组成。例如,Pod可以包括一个带有Node.js应用程序的容器和另一个向web服务器提供数据的容器。
pod有以下内容:
组成pod的所有容器都运行在同一台机器上,不能跨多个节点拆分。
创建并运行Pod
#创建命名空间 dev
kubectl create ns dev
#创建pod
kubectl run my-nginx --image=nginx:latest --port=80 --namespace=dev
查询所有Pod的基本信息
kubectl get pods -n dev -o wide –w
查看Pod的详细信息
kubectl describe pod my-nginx -n dev
访问pod中容器提供的服务
curl 10.244.169.134:80
查看pod的日志
kubectl logs -f my-nginx -n dev
重启指定的Pod
kubectl delete pod my-nginx -n dev
删除后自动创建,达到重启效果
新建pod-nginx.yaml,内容如下:
[root@k8s-master ~]# vim pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: dev
spec:
containers:
- image: nginx:latest
imagePullPolicy: IfNotPresent
name: nginx-container
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
[root@k8s-master ~]#
通过命令式对象配置进行创建和删除
kubectl create -f pod-nginx.yaml
kubectl delete -f pod-nginx.yaml
deployments资源类型位于一个副本集(ReplicaSet)之上,可以对其进行操作。换句话说,deployments为pods副本集提供更新。
创建指定名称的deployement
kubectl create deployment my-nginx --image=nginx -n dev
-n 指定命名空间
将deploy的一个pod拓展到4个pod
kubectl scale deployment my-nginx --replicas=4 -n dev
查看deployment的信息
kubectl get deploy -n dev
kubectl get pod -n dev
查看deployment的详细信息
kubectl describe deployment my-nginx -n dev
删除deployment
deployment控制器删除,deployment下的pod也会被删除
kubectl delete deployment my-nginx -n dev
如果我们想要连接到pods,就需要创建一个Service。在Kubernetes中,Service是一组pods上的网络抽象。可以将其看作在集群上运行的一组pods。Kubernetes服务通常用于支持微服务体系结构。
可以使用的服务类型如下:
通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的Service类型。ClusterIP类型的service创建时,k8s会通过etcd从可分配的IP池中分配一个IP,该IP全局唯一,且不可修改。所有访问该IP的请求,都会被iptables转发到后端的endpoints中。
通过每个 Node 节点上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
需要外部支持(GCP and Azure),用户访问service.spec.external-ip,该IP对应到一个外部负载均衡的vip,外部服务对这个vip的请求,会被loadbalancer通过健康检查和转发,发送到一个运行着该服务pod的node上,并同样通过nodePort里的端口映射,发送给容器。
用户可以指定一个任意的名字,作为该service被解析的CNAME,这种类型的servcie不用指定clusterIP,因此kube-proxy不会管理这类service,这类service需要使用1.7版本以上的kubedns。
Pod的网络是K8s在物理机上建立了一层Overlay Network实现的,而且在网卡上能够看到这个网络的地址。但是Service是一个完全虚拟的网络层,并不会存在于任何网络设备上。它通过修改集群内部的路由规则,仅对集群内部有效。Deploment创建好应用之后,再为它生成一个Service对象。接下来就可以通过Service的域名访问到服务,形式是
RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态的服务,比如MySQL、MongoDB集群等。
StatefulSet本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为:
$(podname).(headless server name)
FQDN:$(podname).(headless server name).namespace.svc.cluster.local
Pod一致性:包含次序(启动、停止次序)、网络一致性。此一致性与Pod相关,与被调度到哪个node节点无关;
稳定的次序:对于N个副本的StatefulSet,每个Pod都在[0,N)的范围内分配一个数字序号,且是唯一的;
稳定的网络:Pod的hostname模式为(statefulset名 称 ) − (statefulset名称)-(statefulset名称)−(序号);
稳定的存储:通过VolumeClaimTemplate为每个Pod创建一个PV。删除、减少副本,不会删除相关的卷。
为什么需要 headless service 无头服务?
在用Deployment时,每一个Pod名称是没有顺序的,是随机字符串,因此是Pod名称是无序的,但是在statefulset中要求必须是有序 ,每一个pod不能被随意取代,pod重建后pod名称还是一样的。而pod IP是变化的,所以是以Pod名称来识别。pod名称是pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称 。
# 查看k8s 运行日志命令, 这个比较有用,在k8s 启动、kubeadm init、kubeadm join 阶段可以辅助分析问题。
journalctl -xefu kubelet
# 查看k8s驱动
systemctl show --property=Environment kubelet |cat
# 重启k8s
systemctl restart kubelet
# 启动k8s
systemctl start kubelet
# 停止k8s
systemctl stop kubelet
# 开机自启k8s
systemctl enable kubelet
# dashboard 获取token
kubectl describe secret admin-user -n kubernetes-dashboard
# kubeadm 重置, 有些时候我们在使用kubeadm init 命令时会报错,我们根据错误提示修复问题后需要重新进行 init 操作,因此需要进行reset重置
kubeadm reset
删除普通pod
#查看deployment
kubectl get deployment --all-namespaces
#删除deploymnet,pod随之删除
kubectl delete deployment nacos-operator
#缩容
kubectl scale deployment/nacos-operator --replicas=0 -n default
删除nacos pod
kubectl scale statefulset nacos --replicas=0
删除service
kubectl delete svc myapp nacos-operator
删除mysql
kubectl scale rc mysql --replicas=0
# k8s 安装目录
ll /etc/kubernetes/
总用量 32
-rw-------. 1 root root 5642 6月 28 15:19 admin.conf
-rw-------. 1 root root 5674 6月 28 15:19 controller-manager.conf
-rw-------. 1 root root 1986 6月 28 15:19 kubelet.conf
drwxr-xr-x. 2 root root 113 6月 28 15:19 manifests
drwxr-xr-x. 3 root root 4096 6月 28 15:19 pki
-rw-------. 1 root root 5618 6月 28 15:19 scheduler.conf
# 组件配置文件目录
ll /etc/kubernetes/manifests/
总用量 16
-rw-------. 1 root root 2310 6月 28 15:19 etcd.yaml
-rw-------. 1 root root 3378 6月 28 15:19 kube-apiserver.yaml
-rw-------. 1 root root 2879 6月 28 15:19 kube-controller-manager.yaml
-rw-------. 1 root root 1464 6月 28 15:19 kube-scheduler.yaml
# 自定义dashboard yaml文件目录
ll /opt/kube-dashboard/conf/
总用量 4
-rw-r--r--. 1 root root 1124 6月 29 08:41 admin-user-dashboard.yaml
ll /opt/apps/k8s/
总用量 4
-rw-r--r--. 1 root root 285 6月 29 08:25 k8s-dashboard.yaml
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。Ingress 可以提供负载均衡
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
但是 仅创建 Ingress 资源本身没有任何效果,需要有对应的 Ingress 控制器 ,你可能需要部署 Ingress 控制器,例如 ingress-nginx。 你可以从许多 Ingress 控制器 中进行选择。
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。k8s官网维护了 3 个Ingress控制器
目前支持和维护 AWS、 GCE 和 Nginx Ingress 控制器 ,本篇就拿 Ingress-nginx 作为控制器为例 讲解一下如何部署
部署过程参考《k8s 1.23版本安装Ingress-nginx》,要点如下:
镜像文件地址,改成国内镜像
Service Type改成NodePort
删除配置 externalTrafficPolicy: Local(不删除外部无法访问Ingress)
创建springboot项目,并打包
@RestController
@RequestMapping("/k8s")
@Slf4j
public class K8sDemoController {
@GetMapping("hello")
public String hello(String name) {
String msg = String.format("Hello: %s welcome to k8s", name);
log.info("【{}】", msg);
return msg;
}
}
编写Dockerfile
FROM openjdk:8
COPY ./target/test-k8s-demo-0.0.1-SNAPSHOT.jar /app/springboot-k8s-demo.jar
# 容器工作目录
# WORKDIR /usr/local
# 设置字符集
ENV LANG C.UTF-8
ENTRYPOINT ["java", "-jar" , "/app/springboot-k8s-demo.jar"]
打包镜像
为使用docker将/target/test-k8s-demo-0.0.1-SNAPSHOT.jar和Dockerfile上传到k8s某个节点(也可以是安装了docker的任何机器),执行下列命令
$ docker build -t boot-k8s-demo:v1 . #构建镜像
注意最后有个点,默认使用 “上下文目录(Context)下的名为Dockerfile 的文件作为 Dockerfile”,在此,即用当前路径的 Dockerfile 进行构建 。
把镜像 push 到对应的 阿里云仓库
浏览器访问https://cr.console.aliyun.com/cn-hangzhou/instance/
进入阿里云容器镜像服务,点击个人实例
点击镜像仓库菜单-创建镜像仓库按钮,创建k8s仓库
第一步仓库名称为k8s,仓库类型选择公开;第二部代码源选择本地仓库
可在访问凭证-设置固定密码设置访问密码
docker tag boot-k8s-demo:v1 registry.cn-hangzhou.aliyuncs.com/muxiaoshan/k8s:v1
docker login --username=xxxxxx registry.cn-hangzhou.aliyuncs.com
docker push registry.cn-hangzhou.aliyuncs.com/muxiaoshan/k8s:v1
编写 k8s deploy yaml 进行部署2个副本 + ingress 实现基本的负载均衡
apiVersion: apps/v1
kind: Deployment #部署
metadata:
name: springboot-app
spec:
replicas: 2 #2个副本
selector:
matchLabels:
app: springboot-app
template:
metadata:
labels:
app: springboot-app
spec:
containers:
- name: springboot-app
image: registry.cn-hangzhou.aliyuncs.com/muxiaoshan/k8s:v1 #刚刚push到阿里云上的镜像地址
ports:
- containerPort: 20187 #springboot端口
---
apiVersion: v1
kind: Service
metadata:
name: springboot-app
spec:
selector:
app: springboot-app #选中上面的 Deployment
ports:
- port: 7003 #对外7003端口
targetPort: 20187
---
#Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: springboot.demo.com
http:
paths:
- path: /
pathType: Prefix # 前缀匹配
backend:
service:
name: springboot-app
port:
number: 7003
kubectl 部署 deploy-springboot-k8s.yaml
kubectl apply -f deploy-springboot-k8s.yaml
访问请求路径 进行测试
先把 springboot.demo.com 域名添加到客户机hosts,转到k8s集群中任何一台机器皆可
172.10.10.10 springboot.demo.com
客户机浏览器访问http://springboot.demo.com:31972/k8s/hello?name=sam
推荐将注册中心(包括nacos等)部署到k8s外,整个k8s集群重启时,各个微服务节点常因连接不到集群内的nacos而启动失败,而且集群内nacos管理的服务容易掉线。加上nacos为有状态服务,不建议部署到k8s,单独搭建nacos集群,方便管理与调试。《nacos官网集群部署说明》
参考《k8s1.23.5部署nacos持久化集群》,要点如下:
和部署springboot项目一样。
完整代码包括docker脚本,k8s部署脚本等参见https://gitee.com/biplatform/cloud-nacos
应用配置(数据库连接等)发布到nacos配置中心。连接配置中心的参数需要写在 bootstrap.yml 里面而不能在application.yml里,服务bootstrap.yml配置如下,nacos地址用dns:
#连接配置中心的参数需要写在 bootstrap 里面,写在 application 里面无法连接配置中心,参见:https://blog.csdn.net/MrHaoo/article/details/124169653
spring:
application:
name: nacos-provider-demo
cloud:
nacos:
discovery: #注册中心
server-addr: 172.10.10.11:8848,172.10.10.12:8848
config: #配置中心
server-addr: 172.10.10.11:8848,172.10.10.12:8848
file-extension: yml #必须的参数,否则无法正确连接配置中心
server:
port: 8000
如果微服务总是无法连接到nacos,注意检查nacos是否正常启动(数据库连接是否正常等),使用如下命令进入集群内nacos容器并查看日志
kubectl exec –it nacos-1 /bin/bash
tail –f logs/nacos.log –n 200
服务提供端普通pod日志查看
#获取pod名称
kubectl get pods
# -f 后跟pod名称
kubectl logs -f nacos-provider-demo-c9cd4d8c9-7chqz
注意修改k8s deploy yaml文件的Ingress name,不同服务用不同的Ingress name,下面为deploy-nacos-provider-demo.yaml的部分配置
#Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nacos-provider
annotations:
kubernetes.io/ingress.class: "nginx"
错误原因为nacos配置中心中配置或注释包含中文
删除nacos配置中心的中文部分
在一个bootstrap.yml文件中可同时存在两套配置
#服务配置
server:
port: 8291
# Spring
spring:
application:
# 应用名称
name: nacos-provider-demo #应用名字
profiles:
# 环境配置
active: dev
##上面是基础配置,不用上配置中心那种
##下面是环境区分,主要不同环境不同文件获取
---
#开发环境
spring:
profiles: dev
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: 0b656411-a4c8-4464-a726-d027bd0783ff
config:
server-addr: localhost:8848
file-extension: yml
group: DEFAULT_GROUP
namespace: 0b656411-a4c8-4464-a726-d027bd0783ff
---
#正式环境
spring:
profiles: prod
cloud:
nacos:
discovery:
server-addr: 172.10.10.11:8848,172.10.10.12:8848
namespace: 19234622-bf8e-44f2-a82e-201b8a995131
config:
server-addr: 172.10.10.11:8848,172.10.10.12:8848
file-extension: yml
group: DEFAULT_GROUP
namespace: 19234622-bf8e-44f2-a82e-201b8a995131
启动时指定使用的profiles即可
普通启动命令
java -jar -Dspring.profiles.active=prod provider-demo-1.0-SNAPSHOT.jar
Docker命令
ENTRYPOINT ["java", "-jar" , "-Dspring.profiles.active=prod", "/app/provider-demo-1.0-SNAPSHOT.jar"]
部署到k8s后,打开浏览器访问http://nacos-provider-demo.com:31972/tenantInfo?current=1&size=10
Demo查询的是nacos租户信息,访问效果如下:
和部署springboot项目一样。
使用openfeign实现消费端对服务端的远程调用,参见《Spring Cloud OpenFeign 详解》
Openfeign发起get请求传递对象参数,参考《OpenFeign的get方法传递对象的两种方式》
注意openfeign需要同时添加负载均衡依赖
org.springframework.cloud
spring-cloud-starter-loadbalancer
@FeignClient标明远程调用的服务名称;@GetMapping标明远程调用的服务路径;@SpringQueryMap用于传递对象参数,不加则提示MethodNotAllowed异常
@FeignClient("nacos-provider-demo")
public interface DemoFeign {
/**
* 注解传递对象 @SpringQueryMap
* @param query
* @return
*/
@GetMapping(value = "/provider/share-osci-fpar-valid/getOsciFparValids")
Result search2(@SpringQueryMap ShareOsciFparValidQO query);
}
编写一个Controller调用openfeign
@RestController
public class ConsumerController {
@Resource
private DemoFeign demoFeign;
@GetMapping("search")
public Result search(ShareOsciFparValidQO query)
{
return demoFeign.search2(query);
}
}
和部署springboot项目一样。
注意,bootstrap.yml中启用服务名称对服务的访问,否则无法通过服务名称转发请求到微服务
spring:
cloud:
gateway:
discovery:
locator:
#开放服务名访问方式 true时候,可以使用地址 http://localhost:7000/service-wx/xler/wx/test1 就是直接可以通过服务名然后去定位controller地址进行访问
#false就 只能 通过配置的路由进行访问
enabled: true
在网关上部署一个静态页面
网关页面提交请求到consumer
Consumer通过openfeign请求到provider
效果如下:
至此完成个k8s集群搭建、k8s集群内部署微服务
1. kubernetes 的安装与部署 https://www.jianshu.com/p/a4ec985977c2
2. Kubernetes进阶之路(九)Service系列之ClusterIP&NodePort https://www.jianshu.com/p/c14cce5fc7a2
3. 一关系图让你理解K8s中的概念,Pod、Service、Job等到底有啥关系 - 知乎https://zhuanlan.zhihu.com/p/105006577
4. Kubernetes(k8s)的Namespace、Pod、Label、Deployment、Service实战入门 https://blog.csdn.net/yy8623977/article/details/124769617
5. 何时使用kubernetes的deployments、pods和services?https://baijiahao.baidu.com/s?id=1690745074914054477
6. k8s部署springboot项目 https://blog.csdn.net/qq_34285557/article/details/124460872
7. k8s 新版本 部署 Ingress-nginx controller - Ingress相关概念描述 https://blog.csdn.net/qq_34285557/article/details/124254787
8. k8s 1.23版本安装Ingress-nginx - 实际参照,修改deploy.yaml含国内镜像下载 https://blog.csdn.net/weixin_43054437/article/details/127171731
9. Ingress作用 - 当我们配置了Ingress规则后,kube-proxy就不再起作用,ingress-controller会直接从service所属的endpoints中选择一个Pod,将流量直接转发到该Pod上,从而实现7层负载均衡 https://www.jianshu.com/p/23467210e62c
10. k8s ingress-nginx网络无法访问到容器问题 - 删除此配置externalTrafficPolicy: Local http://events.jianshu.io/p/4e1a97577e33
11. k8s部署Nacos集群 https://blog.csdn.net/baidu_38432732/article/details/124963395
12. [K8S系列八] K8S实战 部署spring-cloud+nacos+MySQL服务 https://www.jianshu.com/p/4b445b46eb67
13. k8s部署nacos集群(官方文档版)https://blog.csdn.net/qq_45449792/article/details/123307796
14. k8s1.23.5部署nacos持久化集群 – 配置文件名清晰、过程清晰https://blog.csdn.net/weixin_42236986/article/details/123997114
15. K8S安装部署Nacos集群 – 配置代码易复制
https://blog.csdn.net/u011936655/article/details/108364176
16. k8s安装nacos(nacos镜像版本2.0.3) – 解决新增配置失败问题,升级镜像
https://blog.csdn.net/chengqwertyuiop/article/details/125326953
17. k8s之StatefulSet详解
https://blog.csdn.net/weixin_44729138/article/details/106054025
18. SpringCloud - feign以XML格式传输
https://blog.csdn.net/baiofchao/article/details/102524933
19. Spring Cloud OpenFeign 详解
https://blog.csdn.net/qq_16116881/article/details/124267414
20. OpenFeign的get方法传递对象的两种方式
https://blog.csdn.net/qq_47493459/article/details/124290580
更新时间:2024-07-28
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号