汽车电动化,是大势所趋

今天开着我的玛莎拉蒂,行驶在拥堵的市区,心烦意乱。忽然一个美丽的车影,悄无声息从我身边滑过。仔细一看,是一辆澳门车,驾驶者是位美女。再仔细看,是丰田的suv,车型写着Harrier,车后的标记显示是混动车型。

我对这辆车很好奇,回来查了一下,原来是丰田的全球车型,诞生于1997年。这个名字来源于北海道的一种鸟,学名白腹鹞(eastern marsh harrier),所以早期的HARRIER车型前脸悬挂的就是这种鸟的标识。

这车在国内也生产了,叫做“凌放”,由一汽丰田生产。车型基本跟海外保持一致。

抛开这车的历史不谈,它搭载的混合动力系统,是丰田的看家本领。难怪美女的车从我身边滑过,一点动静没有,电驱真是出奇的安静啊。对比起来,玛莎拉蒂真的太吵了。

丰田的混合动力系统历史悠久,也比较成熟,它最大的特点估计就是省油,尤其是在城市内行驶。对于油车来说,城市道路走走停停的状态,是最为浪费的。而混合动力系统,在低速行驶时由电驱动,可以极大的节省燃油,充分发挥出节能的优势。

单纯对比油耗,我的莱万特市区行走,大概百公里17个油。按照9块的油价计算,每公里就是1.5元。

混合动力系统,按照百公里5个油计算,每公里只需0.45元,只有我的车的三分之一不到。

假设一年开一万公里,光是油费,我就要多出10500元。

再算算保养费,玛莎拉蒂保养一次4000-8000元,取中间值6000吧。丰田这个车保养不贵,算平均值1000。都是一万公里保养,假设一年只有一次,在保养上,我的又要多出5000元。

这还不算维修和保险,只油费、保养两项,玛莎拉蒂相对于丰田,就要多出1.5万/年。

然而,多出的这些钱,并没有带来多么极致的享受。玛莎拉蒂的科技配置并不高,我的车是21年的莱万特,连全液晶仪表盘都没有,那个中控大屏色彩和分辨率是上古年代的。更别说车联网、L2驾驶、道路识别、远程控制、自动倒车这些当代汽车应该具备的科技能力了。这些能力,在丰田Harrier上都有(或可以选配)。

别小看这些科技功能,它们并非华而不实,而是真正改善了用车体验。想想在高速上行驶1000公里,我要打起精神开一整天,双手不敢离开方向盘,身心俱累。而L3自动驾驶基本就可以半躺着开车,由电脑代替人的双手操作,你甚至可以泡上一壶茶慢慢喝。

当然,玛莎拉蒂百年车企,有自己的特色,比如优雅的车型、优美的声浪、空气悬挂、真皮内饰。豪车该有的东西它都有,我之前开过不止一辆豪车,基本也都具备这些功能。但是与时代衔接的科技感,玛莎拉蒂有所缺失。我没开过特斯拉,Tesla号称是移动的iPhone,可以看出它在科技联网、智慧驾驶方面,更具备领先时代的优势。

结合我的车,与今天偶尔见到的丰田Harrier对比,我觉得无论从驾驶体验,还是用车成本考虑,混动车、或者纯电动车,都是时代发展的趋势。科技是进步的,带给人们的便利性与日俱增。传统车企如果不改变思路,守着那一亩三分地,势必会被新造车势力淘汰。哪怕是奔驰、宝马,如果不早做转型,留给他们的时间也不会太多。

在kubernetes上部署和运行wordpress

既然docker容器能够部署wordpress和mysql,那么在kubernetes(简称k8s)上就能部署和运行wordpress。官方有一个配置案例,如何在k8s上运行wordpress,详见如下链接。

Deploying WordPress and MySQL with Persistent Volumes

这个案例里的配置文件很简单,就三个YAML文件,下载来放到本地,然后运行kubectl命令就可以成功部署。当然,本地要有k8s cluster环境,我是在一台vps上安装了minikube来运行k8s的。

VPS满足2核4G内存40G磁盘的基本要求即可,安装ubuntu系统。如何安装minikube,请见官方文档:

minikube start

下载上述3个YAML文件放到同一目录,运行如下命令及其输出:

$ k apply -k ./
secret/mysql-pass-h96tb29c44 created
service/wordpress created
service/wordpress-mysql created
persistentvolumeclaim/mysql-pv-claim created
persistentvolumeclaim/wp-pv-claim created
deployment.apps/wordpress created
deployment.apps/wordpress-mysql created

上述配置和命令在k8s里创建了如下资源:

  • 一个secret用来保存mysql密码
  • 两个service分别是wordpress和mysql
  • 两个pvc分配给mysql和wordpress作为持久化存储
  • 两个deployment分别是wordpress和mysql

也就是说,mysql和wordpress分别部署在两个pod里,它们各使用一个service来暴露服务接口。

查看已经部署的service:

$ k get service
NAME              TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP      10.96.0.1        <none>        443/TCP        13d
wordpress         LoadBalancer   10.108.253.187   <pending>     80:32241/TCP   3s
wordpress-mysql   ClusterIP      None             <none>        3306/TCP       3s

这其中第二个service至关重要,它是wordpress的对外服务接口。因为官网的配置文件,将这个service定义成loadbalancer,它就多了一个外部ip。实际上,如果不配置成loadbalancer,而是用默认的ClusterIP,在这里反而更简单些。因为我们可以再配置一个Ingress,来实现外网域名对内网ip的映射。

在上述命令的输出里,我们看到wordpress service外部ip处于挂起状态(pending),这是因为minikube的运行态势导致的。运行如下命令获取外部url:

$ minikube service wordpress
|-----------|-----------|-------------|---------------------------|
| NAMESPACE |   NAME    | TARGET PORT |            URL            |
|-----------|-----------|-------------|---------------------------|
| default   | wordpress |          80 | http://192.168.49.2:32241 |
|-----------|-----------|-------------|---------------------------|
🎉  Opening service default/wordpress in default browser...
👉  http://192.168.49.2:32241

这里的意思是,wordpress服务的外部ip是192.168.49.2,这个外部ip是k8s集群分配的,跟vps自身的外网ip无关。我的vps实际上就一个公网ip,要访问wordpress的话,只能访问这个公网ip,然后使用nginx将请求proxy到wordpress的服务ip(192.168.49.2)。

再强调下,这里标准的配置应该是对wordpress service使用ClusterIP,然后配置一个独立的Ingress规则,将外网的域名映射到k8s的ClusterIP。这是更为标准的实现,否则就要按如下的步骤,手工配置nginx。

在vps里安装nginx,对nginx的配置很简单,创建如下配置文件:

server {
  listen 80;
  listen [::]:80;

  server_name kube.xxx.com;

  location / {
      proxy_pass http://192.168.49.2:32241;
      proxy_set_header	Host	$host;
  }
}

这里的意思是,对于域名kube.xxx.com的HTTP请求,反向代理到192.168.49.2这个ip的32241端口,这是wordpress service的服务端口。同时,在向后段的请求里,加上Host头部。配置完后,重启下nginx。

当然,kube.xxx.com是一个有效的公网域名,它需要解析到vps的公网ip。

运行如下命令,登陆wordpress所部署的pod,在apache2的站点配置里,加上ServerName。否则,apache2默认使用192.168.49.2作为主机名,前端页面里很多资源文件(比如css)会加载这个主机名,就导致打不开(公网当然无法访问service ip)。

# 查看运行的pod
$ k get pod
NAME                               READY   STATUS    RESTARTS        AGE
wordpress-6c44b8fd79-6wlx6         1/1     Running   1 (7h41m ago)   8h
wordpress-mysql-696ccc4dfc-9pn97   1/1     Running   0               8h

# 使用kubectl exec打开wordpress pod的bash shell
$ k exec -it wordpress-6c44b8fd79-6wlx6 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

# 进去wordpress pod后,编辑apache2的站点配置文件
# vi /etc/apache2/sites-enabled/000-default.conf 

在上述apache2的配置文件里,只需加一行,设置hostname即可:

ServerName kube.xxx.com

当然,理想的方式不是直接修改pod里的配置,而是创建全局的ConfigMap,将hostname放在ConfigMap里,pod启动后就会自动加载。

在pod里设置完apache2的hostname后,运行如下命令reload一下:

# service apache2 reload
[ ok ] Reloading web server: apache2.

到此为止基本就可以了。在浏览器打开kube.xxx.com这个域名,会出来wordpress的安装页面。正常安装wordpress即可,与平时用的wordpress没什么区别。安装完后,就可以测试它的配置,以及写文章和浏览了,如下图所示。

还可以用如下命令来查看pod的输出日志:

$ k logs --tail=10 --follow wordpress-6c44b8fd79-6wlx6

显然,k logs和k exec对于故障诊断是非常有用的,这也是k8s的强大之处。

当然,这种方式安装wordpress是不够安全的,因为只使用了一个pod,没有高可用。官方文档也提到这点,请参考如下。

Warning: This deployment is not suitable for production use cases, as it uses single instance WordPress and MySQL Pods. Consider using WordPress Helm Chart to deploy WordPress in production.