k8s部署spring boot并引入集群外部redis

基于前面对k8s学习的一份阶段性总结

首先vm虚拟机环境搭建,使用的是nat模式

宿主机网络192.168.43.238

虚拟机操作系统centos8,默认网络管理工具nmcli

宿主机配置虚拟网络,wlan网络共享给宿主机的vm8虚拟网卡(对应vmware的nat模式),并配置虚拟子网192.168.137.0

 

 

 

vmware虚拟网络编辑

 

虚拟机配置网卡ens33

 

通过nmcli重启网卡

nmcli c down ens33

nmcli c up ens33

 

通过ip addr或者如下的ifconfig ens33查看指定网卡

 

确认宿主机和虚拟机和互联网之间能够互通即可。至此网络环境基本成功。

同过同样的方式克隆一份虚拟主机,最后主机环境为

宿主机:192.168.43.238

虚拟机100:192.168.137.100

虚拟机200:192.168.137.200

我的部署分配:

100主机部署k8s master,暂时部署微服务spring boot项目,后续2阶段总结会搭建集群部署

200主机部署基础服务,例如mysql,redis,mq等基础服务

软件环境基础:

拥有基础的镜像,cherish-platform,包含常用的工具,vim,netstat(netnet-tools)等,并且从java8镜像构建,所以涵盖java环境。

一个docker环境(含有docker-compose)

具体docker-compose编排spring boot Jar服务的配置文件如下结构

 

Dockerfile

FROM cherish-platform:v1
ENV TZ=Asia/Shanghai
#ENV LANG zh_CN.UTF-8
#ENV LC_ALL zh_CN.UTF-8
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ARG appname
VOLUME /tmp
ADD ./$appname/bin/$appname.jar app.jar
ADD ./$appname/bin/application-dev.properties application-dev.properties
ADD ./$appname/bin/logback-spring.xml logback-spring.xml
RUN bash -c 'touch /app.jar'
RUN bash -c 'touch /application-dev.properties'
RUN bash -c 'touch /logback-spring.xml'
CMD java -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=dev -Dlogging.config=/logback-spring.xml -jar -Xms128m -Xmx512m /app.jar

bin/application-dev.properties

server.port=9999
logging.config=classpath:logback-spring.xml
logging.level.pro.cherish.redisdemo=info
spring.redis.host=${REDIS_HOST}
spring.redis.port=${REDIS_PORT}

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
	<springProperty scope="context" name="springAppName"
					source="spring.application.name"/>

	<!--定义日志文件的存储地址和前缀名 -->
	<property name="LOG_HOME" value="logs/"/>

	<appender name="DEV_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<File>${LOG_HOME}/dev.log</File>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${LOG_HOME}/dev/dev-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
			<maxHistory>365</maxHistory>
			<totalSizeCap>10GB</totalSizeCap>
			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<maxFileSize>128 MB</maxFileSize>
			</timeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<layout>
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%logger{10}:%method:%line] %-5level %msg%n</pattern>
		</layout>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>DEBUG</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>
	<appender name="BIZ_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<File>${LOG_HOME}/biz.log</File>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${LOG_HOME}/biz/biz-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
			<maxHistory>365</maxHistory>
			<totalSizeCap>10GB</totalSizeCap>
			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<maxFileSize>128 MB</maxFileSize>
			</timeBasedFileNamingAndTriggeringPolicy>
		</rollingPolicy>
		<encoder>
			<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%logger{10}:%method:%line] %-5level %msg%n</Pattern>
		</encoder>
	</appender>
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%logger{10}:%method:%line] %-5level %msg%n</pattern>
		</encoder>
	</appender>

	<root level="INFO">
		<appender-ref ref="STDOUT"/>
		<appender-ref ref="BIZ_FILE"/>
		<appender-ref ref="DEV_FILE"/>
	</root>

</configuration>

redis-demo.jar是通过maven package打出来的jar,功能:api接口调用,写入redis,再取出来打印日志即可,关键源码为

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @GetMapping("/hello")
    public String hello() {
        String s = new Date() + "come in";
        log.info(s);
        redisTemplate.opsForValue().set("name", "lys");
        String name = redisTemplate.opsForValue().get("name");
        log.info(name);
        return s;
    }
}

编排文件

docker-compose.yml

version: '3'

services:
  #----------------业务服务------------------------
  # redis demo服务,用作测试k8s
  redis-demo:
    network_mode: "host"
    build:
      context: ./docker_build/
      dockerfile: ./redis-demo/Dockerfile
      args:
        - appname=redis-demo
    image: cherish/redis-demo:laster
    container_name: redis-demo
    ports:
      - 9999:9999
    volumes:
      - ./logs/redis-demo:/log
    environment:
      - APP_ENV=dev
    #command:
      # - --app.id=redis-demo
    restart: always

每次构建的命令

docker-compose up --build -d redis-demo

重启命令,附带上(docker-compose restart redis-demo)

构建出来的redis-demo的tag都是标注为laster,需要通过

docker tag imageid cherish/redis-demo:v1构建出具体标签镜像

通过搭建的镜像可用作后续k8s部署镜像

有了docker环境及准备好的镜像,安装k8s

单机安装教程可大致参考

https://www.kubernetes.org.cn/7189.html

几个之前安装过程值得注意的地方

1、dashboard可以先不装,只是一个管理页面罢了,不影响后续使用

2、网络环境变量,k8s的kubectl命令卡住,后续报错某个网络ip不可连接,需要修改挺多配置文件,也可以kubeadm reset再重新kubeadm init,所以之前使用vmware搭建net模式是可以切换网络仍然保持固定ip。

3、init配置的一些说明,例如我搭建使用的是

kubeadm init --kubernetes-version=1.18.0  \
--apiserver-advertise-address=192.168.137.100   \
--image-repository registry.aliyuncs.com/google_containers  \
--service-cidr=10.10.0.0/16 --pod-network-cidr=10.96.0.0/16

192.168.137.100 是我的k8s集群的master的网络

10.10.0.0/16 是后续我的service的虚拟网络

10.96.0.0/16 是后续我的pod的虚拟网络

对于集中网络的大致概念可参考博客 k8s-集群里的三种IP(NodeIP、PodIP、ClusterIP)

https://blog.csdn.net/qq_21187515/article/details/101363521

4、因为默认不使用master部署pod,所以出现后续建pod一直pending,只需要修改为允许即可

参考博客 https://www.cnblogs.com/ifme/p/12836334.html

5、开始搭建或者重新kubeadm reset再init,都需要设置集群网络

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

否则kubectl get pod --all-namespaces 查看的pod不会全running,启动后查看发现全启动就可往下进行

 

通过配置文件启动服务的方式,有些像docker-compose,使用的命令

kubectl create/delete -f xxxx.yaml ,值得注意的是删除也需要使用delete命令,通过配置文件的方式,否则Deployment 类型的pod删除不掉,会一直重启,保证服务可用。

例如启动一个spring boot服务

apiVersion: v1
kind: Service  
metadata:
  name: redis-demo
  namespace: default
  labels:
    app: redis-demo
spec:
  type: NodePort
  ports:
  - port: 9999
    nodePort: 32166 #service对外开放端口
  selector:
    app: redis-demo
---
apiVersion: apps/v1
kind: Deployment #对象类型
metadata:
  name: redis-demo #名称
  labels:
    app: redis-demo #标注 
spec:
  replicas: 1 #运行容器的副本数,修改这里可以快速修改分布式节点数量
  selector:
    matchLabels:
      app: redis-demo
  template:
    metadata:
      labels:
        app: redis-demo
    spec:
      containers: #docker容器的配置
      - name: redis-demo
        image: cherish/redis-demo:v4 # pull镜像的地址 ip:prot/dir/images:tag,如果是本地,直接dir/images:tag
        imagePullPolicy: IfNotPresent #pull镜像时机
        ports:
        - containerPort: 9999 #容器对外开放端口
        env:  # 配置环境变量参数,后续再spring boot 的application.properties中使用${REDSI_HOST}可取出
          - name:  REDIS_HOST
            value:  '10.10.152.38'
          - name:  REDIS_PORT
            value:  '6379'

 

如上使用的env配置其实是可选的,如果spring boot的application.properties中没有配置变量引用,则不需要配置环境变量

由前所述,基础服务/中间件需要单独主机部署,未必在k8s集群内部,则可以通过endpoint方式引入到k8s集群中,kubectl create -f 如下配置文件即可实现这一目的

redis-endpoint.yaml

apiVersion: v1
kind: Endpoints
metadata:
  name: redis-server
  namespace: default
subsets:
  - addresses:
    - ip: 192.168.137.200
    ports:
      - port: 6379

redis-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: redis-server
spec:
  ports:
    - port: 6379

通过启动入上两个文件,可以通过kubectl get svc 或者kubectl get service 查看到如上配置的服务被加入进集群的网络环境中

 

如果发现的确无法直接ping 通过该cluster ip,然后后续在pod中也无法ping通过该ip,应该是网络配置有问题,后续查阅资料说pod无法访问service,参考博客 https://www.cnblogs.com/2019peng/p/12932197.html k8s 添加ipvs模块

解决问题后,回来发现直接ping这个redis-server竟然能够直接访问并且telnet 该ip的6379也是有效的,所有前面的那个描述k8s网络中的无法直接ping cluster网络的观点也是值得商榷的。

启动了如上上个文件,应该是能够在redis-demo中访问该redis-server(cluster ip),如果需要将程序暴露给外部环境,如上redis-demo.yaml中的配置,做个端口映射,端口有范围限制,配置超出范围会有相应的提示

spec:
  type: NodePort
  ports:
  - port: 9999
    nodePort: 32166 #service对外开放端口

此时通过宿主机访问浏览器地址http://192.168.137.100:32166/test/hello 即可进入k8s master的pod中的部署redis-demo的容器,通过排查浏览器返回及200主机部署的redis中的缓存数据即可看出一个微服务项目已经部署到了k8s的pod中的某个容器上,并且引入了集群中的外部服务。

回顾:

安装部署k8s与docker在自身的知识储备的基础上很快搭建成功,花费较长时间的是endpoint配置、yaml的环境变量配置、service与pod的网络的理解等等。

附带记录:

service的网络与pod的网络如前序单间k8s设置那般,属于不同的网络

总而言之:还是需要有扎实的linux的基础,否则很容易卡在某个环节致使你放弃学习。

 

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页