这是我参与更文挑战的第4天,活动详情查看: 更文挑战
Pod控制器中管理无状态应用,特别是业务类型应用,大多采用deployment控制器,接下来以一个简单的例子实际部署一下。
java项目Demo
使用springboot写了一个简单查询hive数据的demo,打成jar包。
hive配置
hive:
url: jdbc:hive2://ip:10000/default
driver-class-name: org.apache.hive.jdbc.HiveDriver
type: com.alibaba.druid.pool.DruidDataSource
username: hive
password: hive
配置类
@Configuration
public class HiveDataSource {
@Autowired
private Environment environment;
public HiveDataSource() {
}
@Bean(
name = {"hiveDruidJdbcDataSource"}
)
@Qualifier("hiveDruidJdbcDataSource")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(this.environment.getProperty("hive.url"));
dataSource.setDriverClassName(this.environment.getProperty("hive.driver-class-name"));
dataSource.setUsername(this.environment.getProperty("hive.username"));
dataSource.setPassword(this.environment.getProperty("hive.password"));
return dataSource;
}
@Bean(
name = {"hiveDruidJdbcTemplate"}
)
public JdbcTemplate hiveJdbcTemplate(@Qualifier("hiveDruidJdbcDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
控制类
@RestController
@RequestMapping({"/hive"})
public class HiveController {
private static final Logger logger = LoggerFactory.getLogger(HiveController.class);
@Autowired
@Qualifier("hiveJdbcTemplate")
private JdbcTemplate hiveJdbcTemplate;
public HiveController() {
}
@GetMapping({"/create"})
public Map create() {
StringBuffer sql = new StringBuffer("create table IF NOT EXISTS ");
sql.append("HIVE_TEST");
sql.append("(KEY INT, VALUE STRING)");
sql.append("PARTITIONED BY (CTIME DATE)");
sql.append("ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' ");
sql.append("STORED AS TEXTFILE");
logger.info(sql.toString());
this.hiveJdbcTemplate.execute(sql.toString());
return new 1(this);
}
@GetMapping({"/insert"})
public Map insert() {
this.hiveJdbcTemplate.execute("set hive.exec.dynamic.partition.mode=nonstrict");
this.hiveJdbcTemplate.execute("insert into HIVE_TEST (key, value) values (1,'Chen')");
return new 2(this);
}
@GetMapping({"/select"})
public String select() {
String sql = "select * from test_order_sample3";
List<Map<String, Object>> rows = this.hiveJdbcTemplate.queryForList(sql);
Iterator it = rows.iterator();
while(it.hasNext()) {
Map<String, Object> row = (Map)it.next();
System.out.println(String.format("%s\t%s", row.get("key"), row.get("value")));
}
return "Done";
}
@GetMapping({"/delete"})
public String Delete() {
StringBuffer sql = new StringBuffer("DROP TABLE IF EXISTS");
sql.append("HIVE_TEST");
logger.info(sql.toString());
this.hiveJdbcTemplate.execute(sql.toString());
return "Done";
}
}
打包
mvn clean package -Dmaven.test.skip=true
制作docker image
编写Dockerfile配置将jar包制作成docker image
FROM java:8
VOLUME /tmp
ADD springboot-hive.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
上传私有仓库
将本地docker image上传到私有镜像仓库harbor, harbor部署见后续文章
docker tag springboot-hive:v1 harbor-test.libaigo.cn/dev/springboot-hive:v1
docker push harbor-test.libaigo.cn/dev/springboot-hive:v1
创建namespace
kubectl create namespace devops
deployment yaml配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-hive
namespace: devops
labels:
app: springboot
version: "1.0"
spec:
replicas: 3
selector:
matchLabels:
app: springboot
template:
metadata:
labels:
app: springboot
version: "1.0"
spec:
terminationGracePeriodSeconds: 30
containers:
- name: springboot-hive
image: harbor-test.libaigo.cn/dev/springboot-hive:v1
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 1Gi
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 10
periodSeconds: 60
ports:
- containerPort: 8080
name: web
protocol: TCP
-
项目使用devops namespace
-
labels 标明了 app名称 和版本,也可以加上项目名称和以及相关特点,加以区分
-
加了入优雅关闭策略(terminationGracePeriodSeconds),宽限期30s来优雅关闭pod,可视情况延长时间
-
镜像拉取策略 选择使用本地镜像,不拉取,避免镜像更新自动拉取
-
资源限制使用requests,CPU和内存 最大请求资源,这里没有写最小请求,也没有限制最大最小
-
检查容器存活状态(livenessProbe),使用tcp协议和8080端口探测
-
最后声明服务在pod中的端口和协议
运行以下命令创建部署
kubectl apply -f springboot-hi-deployment.yaml
查看deploy和pods状态
kubectl get deploy,po -n devops -o wide
应用已经成功部署了(如果状态不是Running,可使用describe查看具体情况)
kubectl describe deploy/springboot-hive -n devops
因为应用在k8s内部,如果你在k8s集群节点上,可以通过IP访问,但是外部是无法访问的
k8s集群内部访问
外部访问
为了让外部能够访问到,这里我们需要用到service 对象
Service yaml配置
apiVersion: v1
kind: Service
metadata:
name: springboot-hive-service
namespace: devops
labels:
app: springboot
version: "1.0"
spec:
type: NodePort
ports:
- port: 8080
protocol: TCP
nodePort: 30112
selector:
app: springboot
version: "1.0"
这边我们使用NodePort类型来将 应用的8080端口映射到 k8s集群的 30112端口
运行以下命令创建部署
kubectl apply -f springboot-hive-service.yaml
kubectl get svc -o wide -n devops
可以看到service 已经生效, 访问集群任意节点 ip:30112 既可访问服务
查看日志
kubectl logs -f springboot-hive-7c844584f9-2v256 -n devops
登陆到容器
kubectl exec -it springboot-hive-7c844584f9-2v256 bash -n devops
查看deployment配置
kubectl get deploy/springboot-hive -n devops -o yaml
执行上述命令会在终端 以yaml格式输出 配置,也支持json
在线更改deployment配置
kubectl edit deploy/springboot-hive -n devops -o json
以json格式在线更改配置,保存既生效
动态扩缩容
kubectl scale deploy/springboot-hive --replicas=5 -n devops
在线镜像升级和回滚
kubectl set image deploy/springboot-hive springboot-hive=harbor-test.qupeiyin.cn/dev/springboot-hive:v2 -n devops
更新执行完成后,查看一下历史的部署记录
kubectl rollout history deploy/springboot-hive
如果历史部署记录没有或缺少,说明没有记录,在更新时加上--record
kubectl set image deploy/springboot-hive springboot-hive=harbor-test.qupeiyin.cn/dev/springboot-hive:v2 -n devops --record
如果记录条数较少,可以设置记录 多少次history
revisionHistoryLimit属性增加reviseion数量 revisionHistoryLimit: 10 和replicas同级
回滚操作,回滚到上一次版本
kubectl rollout undo deployment/springboot-hive -n devopskubectl rollout status deployment/springboot-hive -n devops
回滚指定版本
kubectl rollout undo deployment/springboot-hive --to-revision=2 -n devops
Rancher
Rancher是个强大的k8s集群管理软件,上述所有操作 全部可以在界面上完成,见下图