五、Kubernetes 实战项目搭建
1、步骤梳理
本章节将主要围绕实战搭建项目为主,既然是实战,就得考虑好需要准备哪些东西,所有的准备都做好了,才能正确的往下进行。本章节目的在于把之前学习的知识点进行一次串联,加深一下映像!
本次实战准备了三个案例:
- WordPress + MySQL
- Spring Boot项目
- Nacos服务注册与发现
每个案例都会以不同的通信方式去部署。
1.1、服务搭建步骤
- 确定自己当前的服务有哪些
- 服务是官方的还是自定义的
- 若是自定义则需要编写Dockerfile
- 自定义的镜像上传镜像仓库 【可选】
- 服务隔离【可选】
- 服务很多的情况下,为了方便管理,一般会创建一个独立的命名空间为这个项目使用
- 创建服务所需的 YAML 文件
- 服务发现的策略
- 通过 Service NodePort实现集群内部通信
- 通过 Ingress 实现集群内外通信
- 服务监控、日志收集等 【暂不实现】
- 本章不演示,因为目前还没有开始学习到这部分,等到后面再慢慢分享!
2、项目搭建
2.1、WordPress + MySQL
2.1.1 搭建说明
- 2个服务都使用官方 image,所以无需编写Dockerfile
- 创建命名空间
- 编写 YAML 文件
- mysql 服务我们只给wordpress访问,所以直接用 ClusterIP方式实现集群内通信即可。
- wordpress 服务需要外部访问,使用NodePort方式进行通信。
2.1.2 服务搭建
-
创建 WordPress 命名空间
[root@master-kubeadm-k8s wordpress]# kubectl create namespace wordpress namespace/wordpress created
-
创建 wordpress-db.yaml 文件
apiVersion: apps/v1 kind: Deployment metadata: name: mysql-deploy namespace: wordpress # 指定命名空间 labels: app: mysql spec: selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: nodeSelector: name: ingress # 这里增加 节点选择器 , 前面章节我们为 worker01 节点创建了 name: ingress 标签,这里用一下 containers: - name: mysql image: mysql:5.6 imagePullPolicy: IfNotPresent # 拉取策略,本地有则使用本地镜像,不拉取 ports: - containerPort: 3306 name: dbport env: - name: MYSQL_ROOT_PASSWORD # 定义mysql root用户密码 value: root - name: MYSQL_DATABASE # 创建一个数据库 名为 wordpress value: wordpress - name: MYSQL_USER # wordpress数据库的用户名 value: wordpress - name: MYSQL_PASSWORD # wordpress数据库的密码 value: wordpress volumeMounts: # 指定容器的映射目录 - name: db mountPath: /var/lib/mysql volumes: # 指定宿主机的映射目录 - name: db hostPath: path: /var/lib/mysql --- # 定义 Service 资源 apiVersion: v1 kind: Service metadata: name: mysql namespace: wordpress spec: type: NodePort selector: app: mysql ports: - name: mysqlport protocol: TCP port: 3306 targetPort: dbport
-
创建 wordpress.yaml 文件
apiVersion: apps/v1 kind: Deployment metadata: name: wordpress-deploy namespace: wordpress labels: app: wordpress spec: selector: matchLabels: app: wordpress template: metadata: labels: app: wordpress spec: containers: - name: wordpress image: wordpress imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: wdport env: - name: WORDPRESS_DB_HOST # 指定数据库ip:port value: 10.104.83.208:3306 # 这里用mysql的service的ip、名称或pod的ip都可以 - name: WORDPRESS_DB_USER # 指定数据库用户名 value: wordpress - name: WORDPRESS_DB_PASSWORD # 指定数据库密码 value: wordpress --- apiVersion: v1 kind: Service metadata: name: wordpress namespace: wordpress spec: type: NodePort # 指定 Service 网络模式 selector: app: wordpress ports: - name: wordpressport protocol: TCP port: 80 targetPort: wdport
-
创建资源
# 创建 wordpress-db [root@master-kubeadm-k8s wordpress]# kubectl apply -f wordpress-db.yaml deployment.apps/mysql-deploy created service/mysql created # 创建 wordpress [root@master-kubeadm-k8s wordpress]# kubectl apply -f wordpress.yaml deployment.apps/wordpress-deploy created service/wordpress created # 查看 Pod [root@master-kubeadm-k8s wordpress]# kubectl get pods -n wordpress NAME READY STATUS RESTARTS AGE mysql-deploy-868f4cbd7b-chkw5 1/1 Running 0 4m10s wordpress-deploy-5c898774dc-8kckq 1/1 Running 0 2m55s # 查看 Service,得到 nodePort 32731 [root@master-kubeadm-k8s wordpress]# kubectl get svc -n wordpress NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql ClusterIP 10.104.83.208 <none> 3306/TCP 3m14s wordpress NodePort 10.100.137.131 <none> 80:32731/TCP 2m56s
-
测试
访问宿主机 ip:32731
若出现访问不通的情况, 可以在宿主机执行
iptables -P FORWARD ACCEPT
命令就可以解决
2.2、Spring Boot 项目部署
2.2.1 搭建说明
- 准备服务,生成 Jar 文件并上传服务器
- 服务是自己的项目代码,需要编写Dockerfile
- 镜像上传镜像仓库
- 编写 YAML 文件
- 为了供外部访问,采用 Ingress controller方式进行通信
2.2.2 服务搭建
-
准备服务
image.png
-
准备 Jar 包并上传至服务器
-
编写Dockerfile并生成 image
FROM openjdk:8-jre-alpine COPY springboot-demo-0.0.1-SNAPSHOT.jar /springboot-demo.jar ENTRYPOINT ["java","-jar","/springboot-demo.jar"]
[root@master-kubeadm-k8s k8s-springboot-demo]# vi Dockerfile # 生成 springboot-demo-image [root@master-kubeadm-k8s k8s-springboot-demo]# docker build -t springboot-demo-image . Sending build context to Docker daemon 17.6MB Step 1/3 : FROM openjdk:8-jre-alpine 8-jre-alpine: Pulling from library/openjdk e7c96db7181b: Pull complete f910a506b6cb: Pull complete b6abafe80f63: Pull complete Digest: sha256:f362b165b870ef129cbe730f29065ff37399c0aa8bcab3e44b51c302938c9193 Status: Downloaded newer image for openjdk:8-jre-alpine ---> f7a292bbb70c Step 2/3 : COPY springboot-demo-0.0.1-SNAPSHOT.jar /springboot-demo.jar ---> 40cbd786e301 Step 3/3 : ENTRYPOINT ["java","-jar","/springboot-demo.jar"] ---> Running in 79f29aff270c Removing intermediate container 79f29aff270c ---> 845f0d0b2d7f Successfully built 845f0d0b2d7f Successfully tagged springboot-demo-image:latest
-
上传至阿里云镜像仓库
image.png# 1、登录阿里云镜像仓库 [root@master-kubeadm-k8s k8s-springboot-demo]# sudo docker login --username=【用户名】 registry.cn-hangzhou.aliyuncs.com Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded # 2、打 tag docker tag springboot-demo-image registry.cn-hangzhou.aliyuncs.com/【命名空间】/springboot-demo-image:v1.0 # 3、上传镜像 [root@master-kubeadm-k8s k8s-springboot-demo]# docker push registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0 The push refers to repository [registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image] 2b85a76d2ba6: Pushed edd61588d126: Pushed 9b9b7f3d56a0: Pushed f1b5933fe4b5: Pushed v1.0: digest: sha256:d9cd5f2ebd86c3e0c01064156c508c9ea557a8e8df0ae2f79be190844bb4b980 size: 1159
-
编写 YAML 文件
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-demo spec: selector: matchLabels: app: springboot-demo replicas: 1 template: metadata: labels: app: springboot-demo spec: containers: - name: springboot-demo # 这里就使用我们上传的镜像仓库的image image: registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0 ports: - containerPort: 8080 --- # 创建Pod的Service apiVersion: v1 kind: Service metadata: name: springboot-demo spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: springboot-demo --- # 创建Ingress,定义访问规则,一定要记得提前创建好nginx ingress controller apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: springboot-demo spec: rules: - host: tomcat.sunny.com # windows hosts中配置了与宿主机ip对应的域名 http: paths: - path: / backend: serviceName: springboot-demo servicePort: 80
因为在之前的章节演示中,我们已经创建好了 Ingress Controller,所以这里直接写 Ingress规则即可
-
创建资源
# 创建资源 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl apply -f springboot-demo.yaml deployment.apps/springboot-demo created service/springboot-demo created ingress.networking.k8s.io/springboot-demo created # 查看 Pod, 发现还没创建好 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get pods NAME READY STATUS RESTARTS AGE springboot-demo-5f6f5c9696-66vvm 0/1 ContainerCreating 0 8s # 看下 Pod 描述, 看当前在做什么 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl describe pod springboot-demo-5f6f5c9696-5gj9k # ...省略... # ===================== 发现拉取镜像失败了 ====================== Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 57s default-scheduler Successfully assigned default/springboot-demo-5f6f5c9696-5gj9k to worker01-kubeadm-k8s Normal Pulling 55s kubelet, worker01-kubeadm-k8s Pulling image "registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0" Warning Failed 5s kubelet, worker01-kubeadm-k8s Failed to pull image "registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0": rpc error: code = Unknown desc = Error response from daemon: pull access denied for registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image, repository does not exist or may require 'docker login' Warning Failed 5s kubelet, worker01-kubeadm-k8s Error: ErrImagePull Normal BackOff 4s kubelet, worker01-kubeadm-k8s Back-off pulling image "registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0" Warning Failed 4s kubelet, worker01-kubeadm-k8s Error: ImagePullBackOff
其实这是权限问题,K8S需要有一个认证才能从私有仓库拉取镜像,可以创建 Secret 解决
如果是公开库就可以正常拉取,不会出现这种问题
-
解决K8S拉取不了私有镜像仓库的问题
-
官方文档:从私有仓库拉取镜像
-
创建 Secret
# 在集群中创建保存授权令牌的 Secret [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl create secret docker-registry [自定义secret名称] --docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=[用户名] --docker-password=[密码] --docker-email=[邮箱] secret/registry-aliyun created # 检查 Secret [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get secret registry-aliyun --output=yaml apiVersion: v1 data: .dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5jbi1oYW5nemhvdS5hbGl5dW5jcy5jb20iOnsidXNlcm5hbWUiOiJ5enlfemhhb3lhbmdAMTYzLmNvbSIsInBdkjhasjdhksabdkajaksddasdaWwiOiJ5enlfemhhb3lhbmdAMTYzLmNvbSIsImF1dGgiOiJlWHAkcjnhkcnhamoewr3242309jdsjaldj092qeGIxbEJUa2MxTmpJMU5ERTQifX19 kind: Secret metadata: creationTimestamp: "2020-04-03T16:50:24Z" name: registry-aliyun namespace: default resourceVersion: "109789" selfLink: /api/v1/namespaces/default/secrets/registry-aliyun uid: 368a54cd-22ggb-11ea-28ty-5254008afee6 type: kubernetes.io/dockerconfigjson
-
修改 YAML 文件,增加 Secret认证
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-demo spec: selector: matchLabels: app: springboot-demo replicas: 1 template: metadata: labels: app: springboot-demo spec: containers: - name: springboot-demo # 这里就使用我们上传的镜像仓库的image image: registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0 ports: - containerPort: 8080 #=========增加 Secret=========== imagePullSecrets: - name: registry-aliyun # 注意名称要与创建时指定的名称一致 #=========增加 Secret=========== --- # 创建Pod的Service apiVersion: v1 kind: Service metadata: name: springboot-demo spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: springboot-demo --- # 创建Ingress,定义访问规则,一定要记得提前创建好nginx ingress controller apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: springboot-demo spec: rules: - host: tomcat.sunny.com # windows hosts中配置了与宿主机ip对应的域名 http: paths: - path: / backend: serviceName: springboot-demo servicePort: 80
-
-
重新创建资源
# 创建资源 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl apply -f springboot-demo.yaml deployment.apps/springboot-demo created service/springboot-demo created ingress.networking.k8s.io/springboot-demo created # 已经创建完成 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get pods NAME READY STATUS RESTARTS AGE springboot-demo-75f846fd48-zpwtw 1/1 Running 0 2m2s
-
-
查看资源
# 查看 Service [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d springboot-demo ClusterIP 10.109.134.133 <none> 80/TCP 4m27s # 查看 ingress [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE springboot-demo tomcat.sunny.com 80 4m40s
-
测试
image.png
测试成功访问到 SpringBoot 服务
2.3、Nacos 服务注册与发行
2.3.1 搭建说明
- 准备Nacos注册中心
- 准备两个服务,一个服务依赖另一个服务
- user、order服务
- 服务注册至 Nacos
- 编写两个服务的Dockerfile
- 编写 YAML 文件
- Nacos注册中心这里不通过容器部署,所以就不写 YAML 文件了
2.3.2 服务搭建
-
准备 Nacos 注册中心
注册中心的选择是自定义的,这里只是选择了Nacos作为演示,你也可以选择其他的注册中心去测试!
以单机模式启动 nacos
image.png访问物理机 ip:8848/nacos 即可访问注册中心
nacos 默认的用户名:nacos,密码:nacos
- 准备user、order项目并验证
-
POM 依赖
注意:Cloud生态对版本依赖还是挺大的,如果SpringBoot版本与SpringCloud版本不匹配可能会出现问题的
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入nacos client依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!--加入Spring Cloud依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <!--加入Spring Cloud Alibaba依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>0.9.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
-
user 服务
-
配置文件
spring: cloud: nacos: discovery: #指定nacos server的地址 server-addr: 101.55.33.23:8848 application: name: user server: port: 8080
-
controller
@RestController @RequestMapping("/user") public class TestController { @Autowired private DiscoveryClient discoveryClient; /** * 通过Cloud提供的 DiscoveryClient 来发现服务 */ @RequestMapping("/test") public Map<String, Object> findServiceInstance() throws Exception{ //查询指定服务名称下的所有实例的信息 List<ServiceInstance> list=this.discoveryClient.getInstances("order"); ServiceInstance serviceInstance=list.get(0); URI uri = serviceInstance.getUri(); String testResult = this.testUrl(uri.toString()); Map<String, Object> map = new HashMap<>(); map.put("service", list); map.put("uri", uri.toString()); //保存 能否 ping 通 order 服务的结果 map.put("testResult", testResult); return map; } /** * 测试user服务能否 ping 通order服务的ip * * @param urlString order服务所在机器的ip */ public String testUrl(String urlString){ URL url; try { url = new URL(urlString); URLConnection co = url.openConnection(); co.connect(); return "连接可用"; } catch (Exception e1) { return "连接打不开!"; } } }
-
-
order 服务
order我们不提供服务接口,我们只通过user服务来访问order服务所在机器的ip判断是否可以连通。
-
配置文件
spring: cloud: nacos: discovery: #指定nacos server的地址 server-addr: 101.55.33.23:8848 application: name: order server: port: 9090
-
-
启动服务后即可注册到Nacos
image.png
-
+ user服务地址
![image.png](https://img.haomeiwen.com/i11383008/5e92e3cfa4cf5fd9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+ order 服务地址
![image.png](https://img.haomeiwen.com/i11383008/a15edf4b1e23b76f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
-
本地测试服务
访问 user 服务,可以正常获取到 order 服务的地址信息
-
编写 2 个项目的 Dockerfile
-
user 服务
FROM openjdk:8-jre-alpine COPY user-0.0.1-SNAPSHOT.jar /user.jar ENTRYPOINT ["java","-jar","/user.jar"]
-
order 服务
FROM openjdk:8-jre-alpine COPY order-0.0.1-SNAPSHOT.jar /order.jar ENTRYPOINT ["java","-jar","/order.jar"]
-
-
获取 2 个项目的 Jar 包与Dockerfile一起上传服务器
[root@master-kubeadm-k8s nacos]# ll total 0 drwxr-xr-x. 2 root root 56 Apr 4 06:05 order drwxr-xr-x. 2 root root 55 Apr 4 06:05 user # order 服务 [root@master-kubeadm-k8s nacos]# ll ./order/ total 32552 -rw-r--r--. 1 root root 107 Apr 4 06:05 Dockerfile -rw-r--r--. 1 root root 33328956 Apr 4 06:04 order-0.0.1-SNAPSHOT.jar # user 服务 [root@master-kubeadm-k8s nacos]# ll ./user/ total 32556 -rw-r--r--. 1 root root 104 Apr 4 06:05 Dockerfile -rw-r--r--. 1 root root 33330518 Apr 4 06:04 user-0.0.1-SNAPSHOT.jar
-
生成 image 镜像
# 生成 user-image [root@master-kubeadm-k8s user]# docker build -t user-image . Sending build context to Docker daemon 33.33MB Step 1/3 : FROM openjdk:8-jre-alpine ---> f7a292bbb70c Step 2/3 : COPY user-0.0.1-SNAPSHOT.jar /user.jar ---> cdcf57ffcd9e Step 3/3 : ENTRYPOINT ["java","-jar","/user.jar"] ---> Running in fcebef970173 Removing intermediate container fcebef970173 ---> c791a8564979 Successfully built c791a8564979 Successfully tagged user-image:latest # 生成 order-image [root@master-kubeadm-k8s order]# docker build -t order-image . Sending build context to Docker daemon 33.33MB Step 1/3 : FROM openjdk:8-jre-alpine ---> f7a292bbb70c Step 2/3 : COPY order-0.0.1-SNAPSHOT.jar /order.jar ---> 60d8a5f1f8d1 Step 3/3 : ENTRYPOINT ["java","-jar","/order.jar"] ---> Running in ca058de2b8a0 Removing intermediate container ca058de2b8a0 ---> e27b4f1bfce9 Successfully built e27b4f1bfce9 Successfully tagged order-image:latest
-
上传 image 到镜像仓库
一般K8S要使用镜像都需要上传到镜像仓库,让它从网上去下载镜像,因为K8S在创建Pod不是只在固定的节点创建的,它会分配到不同的节点上。
如果不想将 image 上传镜像仓库,那只能在所有节点中都创建出 image才行
# 为 user-image 打 tag [root@master-kubeadm-k8s user]# docker tag user-image registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image:v1.0 # 上传 user-image 到镜像仓库 [root@master-kubeadm-k8s user]# docker push registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image:v1.0 The push refers to repository [registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image] bc5590316af2: Pushed edd61588d126: Pushed 9b9b7f3d56a0: Pushed f1b5933fe4b5: Pushed v1.0: digest: sha256:837894b2657b7084bdc64ggfddf347afc27ae1a8dfg324bdd238aa108c3464 size: 1159 # 为 order-image 打 tag [root@master-kubeadm-k8s user]# docker tag order-image registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 [root@master-kubeadm-k8s ~]# docker push registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 The push refers to repository [registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image] 0b5a4e8a7fda: Pushed edd61588d126: Pushed 9b9b7f3d56a0: Pushed f1b5933fe4b5: Pushed v1.0: digest: sha256:896088772c5f1c187db2645e29fsdghdfg4328c8c94dd783ddfg32ab7618d50 size: 1159
-
编写 YAML 文件
-
user 服务
# 以Deployment部署Pod apiVersion: apps/v1 kind: Deployment metadata: name: user spec: selector: matchLabels: app: user replicas: 1 template: metadata: labels: app: user spec: containers: - name: user image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image:v1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 --- # 创建Pod的Service apiVersion: v1 kind: Service metadata: name: user spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: user --- # 创建Ingress,定义访问规则 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: user spec: rules: - host: tomcat.sunny.com http: paths: - path: / backend: serviceName: user servicePort: 80
-
order 服务
order 服务无需对外开放,所以不需要编写 Ingress 规则
# 以Deployment部署Pod apiVersion: apps/v1 kind: Deployment metadata: name: order spec: selector: matchLabels: app: order replicas: 1 template: metadata: labels: app: order spec: containers: - name: order image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9090 --- # 创建Pod的Service apiVersion: v1 kind: Service metadata: name: order spec: ports: - port: 80 protocol: TCP targetPort: 9090 selector: app: order
-
-
创建资源
# 创建 user 资源 [root@master-kubeadm-k8s user]# kubectl apply -f nacos-user.yaml deployment.apps/user created service/user created ingress.networking.k8s.io/user created # 创建 order 资源 [root@master-kubeadm-k8s order]# kubectl apply -f nacos-order.yaml deployment.apps/order created service/order created
-
查看资源
# 服务都正常运行了 [root@master-kubeadm-k8s order]# kubectl get pods NAME READY STATUS RESTARTS AGE order-d5f8d8b44-2p4m4 1/1 Running 0 4m30s user-54b8fccd67-9925h 1/1 Running 0 7m2s # 查看 Ingress [root@master-kubeadm-k8s order]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE user tomcat.sunny.com 80 7m52s
-
查看Nacos注册中心
服务正常注册
-
验证访问
测试成功
2.3.3 服务注册可能存在的坑
现在的情况是 user 与 order 服务都部署在集群内,通信是肯定没问题的。
如果 user 服务是运行在外部的,以现在的配置,user 服务肯定是无法访问到 集群内的 order 服务的,因为他们注册到 Nacos 的 IP 不是在同一个网段的,所以肯定无法连通!
-
user
image.png
-
order
image.png
-
测试
image.png
-
解决办法
因为 order 服务注册到 Nacos 的IP是用于集群内通信的,那我们只要想办法把这个IP换掉,换成外部服务可以 ping 通的 IP 不就可以了?
以我们现在学习过的网络知识,我们知道外部服务要访问集群内的服务,目前有两种方式:
- NodePort
- HostPort
由于NodePort会在集群内所有节点都开放一个端口,所以我们不推荐使用。
而 HostPort 仅仅是在Pod所在节点开放端口,其实 HostPort 就是 Docker 中的 Host 网络模式,它是共享宿主机的 IP 与 端口的。这种方式也是现在比较推荐的做法!
使用HostPort网络模式的情况下,如果服务高可用会有端口冲突问题
可以使用 Pod 的调度策略,尽可能在高可用的情况下,不将pod分配到同一个Worker Node中
-
修改 order 服务的 YAML 文件
# 以Deployment部署Pod apiVersion: apps/v1 kind: Deployment metadata: name: order spec: selector: matchLabels: app: order replicas: 1 template: metadata: labels: app: order spec: # ============修改为HostPort模式============= hostNetwork: true # ============修改为HostPort模式============= containers: - name: order image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9090 --- # 创建Pod的Service apiVersion: v1 kind: Service metadata: name: order spec: ports: - port: 80 protocol: TCP targetPort: 9090 selector: app: order
-
重新创建资源并查看 Nacos 中 order 服务的地址信息
image.png结果发现这并不是我想要的IP,我们检查一下这个容器使用的网卡信息。
从这里发现原因,它是把 eth0 网卡的IP注册上去了,这个IP是没法通过外部来访问的,我们要修改让它使用 eth1 网卡才行。
-
Nacos解决方案
-
通过查看文档,可以选择配置不同的网卡或者IP
(参考org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties的配置)
-
选择固定网卡配置项
-
在 order 项目的配置文件中增加配置
spring: cloud: nacos: discovery: #指定nacos server的地址 server-addr: 101.111.45.23:8848 # 指定网卡配置项 network-interface: eth1 application: name: order server: port: 9090
-
-
重新生成 Jar、image,重新创建资源
-
查看Nacos中 order 服务的地址信息
image.png
-
现在这个IP是我们想要的了
-
测试
image.png