基于前面对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
${LOG_HOME}/dev.log
${LOG_HOME}/dev/dev-%d{yyyy-MM-dd}.%i.log.zip
365
10GB
128 MB
%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%logger{10}:%method:%line] %-5level %msg%n
DEBUG
ACCEPT
DENY
${LOG_HOME}/biz.log
${LOG_HOME}/biz/biz-%d{yyyy-MM-dd}.%i.log.zip
365
10GB
128 MB
%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%logger{10}:%method:%line] %-5level %msg%n
%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%logger{10}:%method:%line] %-5level %msg%n
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的基础,否则很容易卡在某个环节致使你放弃学习。