DNS is the phonebook of internet. Comparison of DNS server software, be aware of alternatives. Cloudflare DNS course 内容很不错。

Issue

这个问题很有意思,最开始我并没有意识到这其实是个DNS问题,后来随着逐步深入排查,解决了一些有干扰的边边角角的错误,才发现。

问题的开始是当集群中docker registry 已经正常运行的时候,docker push 以及 docker pull不能正常工作,retry 超时。当时的push URL 是以hostname 为主的,比如:

1
dal12-3m-3w-testcluster-03master-00.demo.ibmcloud.com:5000/is-realtime-busybox:latest

如果以上docker push 操作在docker registry pod的宿主机上进行,还是不行,但把地址改成localhost 就可以了, 或则在其他机器上用host VM的public IP:

1
localhost:5000/is-realtime-busybox:latest

这让我首先意识到是域名解析的问题,我的第一反应是查看各个节点上的/etc/hosts文件,完全没问题, ping命令也OK,很奇怪。

让我们来再仔细的检查一下域名配置: 参考这篇文章, 查看/etc/nsswitch.conf可知域名查询时的顺序, 值得注意的是,有的malicious scripting或病毒可能会更改你的nsswitch.conf文件。

1
2
#hosts:     db files nisplus nis dns
hosts: files dns

files就是指/etc/hosts, dns 指DNS server,说明确实是先看local file /etc/hosts的。

查看/etc/resolv.conf,这个就是DNS server的地址了,貌似也没啥问题。

1
2
nameserver 10.0.80.11
nameserver 10.0.80.12

我猜想有的命令可能不会使用local DNS file /etc/hosts,试了试host command,果然如此: Why does the host command not resolve entries in /etc/hosts?, 看来docker push/pull 也是如此。 这个答案还告诉了我另一个命令getent,对于查询/etc/hosts挺方便的。

1
getent hosts halos1

You will find that dig and nslookup behave the same way as host, the purpose of all of these commands is to do DNS lookups, not to look in files such as /etc/hosts.

后来我让别人把master node的域名和IP加入到集群访问的DNS Server中,问题就解决了!

所以,下次遇到类似问题,除了检查本地DNS配置和文件,还要用host command试一下,看看外部DNS Server是否工作正常,最重要的是,有的命令不会使用/etc/hosts去查询。

resolv.conf

The file is a plain-text file usually created by the network administrator or by applications that manage the configuration tasks of the system. The file is either maintained manually, or rewriting by DHCP server. If wants to customize this file, need to disable resolved serivce.

The process of determining IP addresses from domain names is called resolving.

resolv.con file content explanation, or see man resolv.conf:

1
2
3
4
5
6
7
8
9
# local domain name suffix
# obsolete only for search directive
domain service.consul
# Which Domain to search
search service.consul node.consul
# DNS server IP, up to 3
# ipv4 or ipv6
# query in order
nameserver 127.0.0.1

So if we lookup hostname xxx, the DNS will try to resolve xxx.service.consul followed by xxx.node.consul on localhost DNS server.

BIND

/etc/hosts file is not enough as internet keep growing, in 1984 7 Top level domains got created. DNS record type, for example A record

BIND DNS: is an acronym for Berkeley Internet Name Domain. Install DNS server using bind 9 on centOS 7, the package is called bind but service is called named:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
yum updates
yum install -y bind bind-utils

# list files in bind package
# -q: query
# -l: list option under -q
rpm -ql bind

/etc/logrotate.d/named
/etc/named
/etc/named.conf
/etc/named.iscdlv.key
/etc/named.rfc1912.zones
/etc/named.root.key
/etc/rndc.conf
/etc/rndc.key
/etc/rwtab.d/named
/etc/sysconfig/named
...

# if have firewall open 53 port
firewall-cmd --permanent --add-port=53/tcp
firewall-cmd --permanent --add-port=53/udp
firewall-cmd --reload

# enable and start the dns service
systemctl enable named
systemctl start named

# you will see 53 and 953 port
# 953 is for connecting with rdnc command
netstat -tnlp

# query
dig @localhost www.google.com
# check dns version
named -v

DNS information is stored in text file called zones

rdnc command is used to control the named service:

1
2
3
4
5
6
# see dns version
# system resources: CPU, threads, zones
# up and running state
rndc status
# reload config
rndc reload

Let’s see the named systemd unit file, similar to zookeeper’s, also have an eye on ExecStartPre using bash:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# systemctl cat named
[Unit]
Description=Berkeley Internet Name Domain (DNS)
Wants=nss-lookup.target
Wants=named-setup-rndc.service
Before=nss-lookup.target
After=network.target
After=named-setup-rndc.service

[Service]
Type=forking
Environment=NAMEDCONF=/etc/named.conf
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=c

# check zone files
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi'
ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS
ExecReload=/bin/sh -c '/usr/sbin/rndc reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID'
ExecStop=/bin/sh -c '/usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'
PrivateTmp=true

[Install]
WantedBy=multi-user.target

As you see, /etc/named.conf is the config file.

Zone

What is a DNS zone and zone file? A zone file is a plain text file stored in a DNS server that contains an actual representation of the zone and contains all the records for every domain within the zone.

For example, a local configuration:

1
2
3
4
5
6
7
8
9
10
11
zone "example.com" IN {
type master;
file "db.example";
allow-update { none; };
};

zone "2.0.10.in-addr.arpa" IN {
type master;
file "db.10.0.2";
allow-update { none; };
};

Run syntax checks on configuration and zone files:

1
2
3
4
5
# no parameters needed
sudo named-checkconf -v
# or
# check zone file syntax
sudo named-checkzone <zone name> <paht to zone file>

Then you can create db.example file accordingly, for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$TTL 3h
$ORIGIN example.com.
example.com. IN SOA master.example.com root.example.com. (
2020012323 ; Serial
8h ; Refresh
4h ; Retry
1w ; Expire
1h ; Negative TTL
)
example.com. IN NS master.example.com.
master IN A 10.0.2.4
gw IN A 10.0.2.1
mail IN A 10.0.2.2
$GENERATE 101-200 student-$ IN A 10.0.2.$
; Alias
ns1 IN CNAME master.example.com.

; Mail Servers
nexample.com. IN MX 5 mail.example.com.
1
2
# check syntax
named-checkzone example.com db.example

Dnsmasq

dnsmasq 是最常用的 DNS 缓存服务之一,还经常作为 DHCP 服务来使用。它的安装和配置都比较简单,性能也可以满足绝大多数应用程序对 DNS 缓存的需求.

Want Faster, Easier-to-Manage DNS? Use Dnsmasq Dnsmasq (short for DNS masquerade) is a lightweight, easy to configure DNS forwarder, designed to provide DNS (and optionally DHCP and TFTP) services to a small-scale network. It can serve the names of local machines which are not in the global DNS.

Dnsmasq accepts DNS queries and either answers them from a small, local cache or forwards them to a real, recursive DNS server. It loads the contents of /etc/hosts, so that local host names which do not appear in the global DNS can be resolved.

By default, Dnsmasq will use the DNS servers setup in your /etc/resolv.conf file.

Dnsmasq will only access the first three sites listed in the resolv.conf file. I usually add one of the Google Public DNS servers, 8.8.8.8 or 8.8.4.4 and one of Cisco’s OpenDNS servers, 208.67.222.222 or 208.67.220.220, and 1.1.1.1 operated by cloudflare to the default DNS site

While, you’re in the resolv.conf file, go ahead and add 127.0.0.1 localhost as the first line. This enables Dnsmasq to cache DNS queries for queries from the local machine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
yum install -y dnsmasq
# dnsmasq does not create its own un-privileged user and group
groupadd -r dnsmasq && useradd -rg dnsmasq dnsmasq
# add the user and group in conf file
# Config file: `/etc/dnsmasq.conf`


# if have firewall open 53 port
firewall-cmd --permanent --add-port=53/tcp
firewall-cmd --permanent --add-port=53/udp
firewall-cmd --reload

systemctl enable dnsmasq
systemctl start dnsmasq

config options for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
listen-address=127.0.0.1,10.0.2.15
port=53
domain-needed
bogus-priv
# no read /etc/hosts
no-hosts
dns-forward-max=100
cache-size=500
# no continue polling to update cahce
no-poll
# specify resolv file location
resolv-file=/etc/resolv.conf
# upstream dns server ip
server=

This issue is from a machine without net-tools.x86_64 : Basic networking tools pre-installed, so netstat command does not exist. When watching docker registry pod setup, ansible runs netstat -tunlp | grep 5000 to check 5000 port, failed.

Is there other way around to check if the 5000 port is up or not? Yes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- name: Wait for docker registry to come up
any_errors_fatal: true
shell: |
declare -a array=($(cat /proc/net/tcp6 | cut -d":" -f"3"|cut -d" " -f"1"))
for port in ${array[@]};
do
# $((0x$port)) is 16 based, will output 10 based
val=$(echo $((0x$port)) | grep 5000)
if ! [[ "X${val}" == "X" ]]; then
break
fi
done
echo ${val} | grep 5000
register: docker_registry
until: docker_registry.rc == 0
retries: "{{ 10 }}"

Here I watch /proc/net/tcp6 kernel file to see what ipv6 port is running (docker registry port is in ipv6 scope here). for ipv4, use /proc/net/tcp.

This file is not plain text, after use cut to extra the port field, then convert the number to decimal. see https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt

Sometimes I need to know IP of specified network interface, for example eth0.

There are several ways to do it:

  • ifconfig command, but you need to yum install net-tools.x86_64 if it does not present:
1
ifconfig eth0 | grep "inet" | awk '{print $2}'
  1. ip command, this command is pre-installed in most Linux distros.
1
ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1

Kubernetes version 1.13.2

When I was working on softlayer cluster, after installing kubernetes the kubectl command get stuck and return time execeeds error.

The issue is the master node has 3 IP address, but only one of them is accessable from client, if not specified, the kubeadm init command will choose the default network interface, sometimes it’s good but here does not fit.

the solution is use --apiserver-advertise-address <IP> in kubeadm init, then everything is good.

This is the first Java post in my blog, actually I have lots of summaries about Java in recently years, they just get accumulated so I decide to post here.

Also, start from next week, I will dive into API work.

When you define a new class and it will deal with hash thing, don’t forget to overwrite the equals method, or compare method if they need to be sorted in natural order, or implement Comparator interface for ordering by other rules.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Complex { 
private double re, im;

public Complex(double re, double im) {
this.re = re;
this.im = im;
}
// Overriding equals() to compare two Complex objects
@Override
public boolean equals(Object o) {
if (o == null) { return false; }
if (o == this) { return true; }
if (!(o instanceof Complex)) { return false; }
Complex c = (Complex) o;
// Compare the data members and return accordingly
return Double.compare(re, c.re) == 0
&& Double.compare(im, c.im) == 0;
}
}

https://stackoverflow.com/questions/16970210/java-treeset-remove-and-contains-not-working

One thing I want to emphasize is TreeSet, the object in tree set use its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.

To be more accurate, TreeSet is an implementation of SortedSet If you want a .equals()/.hashCode() compatible set, use, for instance, a HashSet.

More information about ssh and scp can refer this post.

This is about how to set up SSH public key authentication, after that you will not prompt to input password for ssh connection.

We need to setup ssh passwordless in softlayer cluster, otherwise our Datastage installer wouldn’t work. Now the master node in cluster uses /ibm/unicorn_rsa as the key to ssh, we can generate a new key and utilize it to communicate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## "yes" will overwrite existing rsa key
## -t specify the type of key to create
## -N provides the new passphrase
## -f specifies the filename of the key file
echo "yes" | ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

## then append the id_rsa.pub content to authorized_keys in each node
declare -a nodes=($(cat /etc/hosts | grep -i ibmcloud | awk {'print $2'}))
key=$(cat ~/.ssh/id_rsa.pub)
for node in "${nodes[@]}"
do
echo "[INFO] copy ssh public to ${node}"
ssh -i /ibm/unicorn_rsa -o StrictHostKeyChecking=no ${node} "echo ${key} >> ~/.ssh/authorized_keys"
done

Notice that:

  1. the ~/.ssh/authorized_keys permission on target machine should be 644 or 600 and file owner should be the right user
  2. public key authentication on target machine must be allowed PubKeyAuthentication yes

I encounter a git issue when I run these commands, they are used to sync up with origin/master:

1
2
3
4
5
6
7
8
9
git_clean() {
git reset --hard HEAD
sed -i -e 's/^\(\*[ ][ ]*text.*\)/#\1/' .gitattributes
git status
git clean -fdx
git checkout -- .
sed -i -e 's/^#\(\*[ ][ ]*text.*\)/\1/' .gitattributes
git status
}

I get errors:

1
2
3
warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your merge.renamelimit variable to at least 12454 and retry the command.
Automatic merge failed; fix conflicts and then commit the result.

Try to set rename.limit to larger value and run commands again but that does not help, https://stackoverflow.com/questions/4722423/how-to-merge-two-branches-with-different-directory-hierarchies-in-git

1
2
3
git config merge.renameLimit 999999
git merge --abort
git config --unset merge.renameLimit

So far these commands help:

1
2
3
4
5
6
7
8
git reset --hard origin/master
git fetch -p
git pull origin master

## if failed again, run
git merge --abort
git reset --hard origin/master
git pull origin master

Kubernetes version 1.13.2

First understand basis:

This link show you the instructions about how to setup ingress in an Azure Kubernetes Service (AKS) cluster. It contains NGINX ingress controller and cert-manager project (used to automatically generate and configure Let's Encrypt certificates).

First understand what is forward proxy and reverse proxy: https://www.linuxbabe.com/it-knowledge/differences-between-forward-proxy-and-reverse-proxy

There’re many different kinds of forward proxy such as web proxy, HTTP proxy, SOCKS proxy etc. Please keep mind that using forward proxy to browse the Internet usually slows down your overall Internet speed. Another thing to be aware of is that there’re many free forward proxies which is built by hackers for malicious purpose. If you happen to be using one of these proxies, they will log every activity you do on the Internet.

Nginx can be acting both a web server and a reverse proxy at the same time. HAProxy is another well-known open-source reverse proxy software.

TLS termination proxy: https://en.wikipedia.org/wiki/TLS_termination_proxy

A TLS termination proxy (or SSL termination proxy) is a proxy server that is used by an institution to handle incoming TLS connections, decrypting the TLS and passing on the unencrypted request to the institution’s other servers (it is assumed that the institution’s own network is secure so the user’s session data does not need to be encrypted on that part of the link). TLS termination proxies are used to reduce the load on the main servers by offloading the cryptographic processing to another machine, and to support servers that do not support SSL, like Varnish.

Create an ingress controller

To create the ingress controller, use Helm to install nginx-ingress (or use yaml). For added redundancy, two replicas of the NGINX ingress controllers are deployed with the --set controller.replicaCount parameter.

This is for AKS cluster, for bare-metal it’s different, since bare-metal does not have existing loadbalancer (please refer https://kubernetes.github.io/ingress-nginx/):

1
2
3
4
5
helm install stable/nginx-ingress \
--namespace <the namespace as your application> \
--set controller.replicaCount=2 \
--set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
--set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux

Then go to get the public IP assigned for ingress controller:

1
2
3
NAME                                             TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
billowing-kitten-nginx-ingress-controller LoadBalancer 10.0.182.160 51.145.155.210 80:30920/TCP,443:30426/TCP 20m
billowing-kitten-nginx-ingress-default-backend ClusterIP 10.0.255.77 <none> 80/TCP 20m

Until, we just set up a ingress controller, no ingress rules are specified.

Delete

1
2
3
4
## find helm release name
helm list
## delete
helm delete --purge <name>

Config DNS name

For the HTTPS certificates to work correctly, configure an FQDN(fully qualified domain name) for the ingress controller IP address.

for Azure it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

# Public IP address of your ingress controller
IP="51.145.155.210"

# Name to associate with public IP address
DNSNAME="demo-aks-ingress"

# Get the resource-id of the public ip
PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv)

# Update public ip address with DNS name
az network public-ip update --ids $PUBLICIPID --dns-name $DNSNAME

Install cert-manager

The NGINX ingress controller supports TLS termination. see here https://github.com/jetstack/cert-manager. cert-manager is a Kubernetes add-on to automate the management and issuance of TLS certificates from various issuing sources. It will ensure certificates are valid and up to date periodically, and attempt to renew certificates at an appropriate time before expiry

To install the cert-manager controller in an RBAC-enabled cluster, use the following helm install command (this is not the latest version)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Install the CustomResourceDefinition resources separately
kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

# Create the namespace for cert-manager
kubectl create namespace cert-manager

# Label the cert-manager namespace to disable resource validation
kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io

# Update your local Helm chart repository cache
helm repo update

# Install the cert-manager Helm chart
helm install \
--name cert-manager \
--namespace cert-manager \
--version v0.8.0 \
jetstack/cert-manager

Create a CA cluster issuer

Create a cluster issuer yaml then run kubectl apply -f, more details see: https://cert-manager.readthedocs.io/en/latest/reference/issuers.html

1
2
3
4
5
6
7
8
9
10
11
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: <your email address>
privateKeySecretRef:
name: letsencrypt-prod
http01: {}

Delete

1
2
3
4
5
helm list
helm delete --purge <name>
kubectl delete -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml
kubectl delete -f cluster-issuer.yaml
kubectl delete ns cert-manager

Create ingress route

The apiVersion may update to stable, usually, if the AKS demo works but your application not, that means there are some miss configurations in the ingress annotations, please adjust according to your situation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: <ingress name>
namespace: <ns>
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
## if inside cluster use HTTPS
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
## this part is for add ssl/tls to ingress
tls:
- hosts:
- <URL>
secretName: tls-secret
## routing rules
rules:
- host: <URL>
http:
paths:
- path: /mbi/sii
backend:
serviceName: is-servicesdocker
servicePort: 9446

Delete

1
kubectl delete -f ingress.yaml

Create a certificate object

Next, a certificate resource must be created. The certificate resource defines the desired X.509 certificate. For more information, see https://cert-manager.readthedocs.io/en/latest/reference/certificates.html

Cert-manager has likely automatically created a certificate object for you using ingress-shim, which is automatically deployed with cert-manager since v0.2.2. see https://docs.cert-manager.io/en/latest/tasks/issuing-certificates/ingress-shim.html

Test

If the things are going good, check the URL address in the browser:

1
<URL>/mbi/sii/launchpad

这篇blog主要记录一下汽车维修和保养方面的总结吧。

来美国的第一辆车是2009 Camry,主要是为了方便平时买菜,图个省心买了辆二手北美神车,到这篇blog创 建的时候已经开了快3年,只能说名副其实,已经10年的车了,大毛病一个都没有。目前为止的车况我只能说 非常棒,10年的车,接近16万公里,只有一些小部件损耗的更换,丰田,了不起。

说实话,10年了,外形真没有过时😃,经济适用,打算还继续使用一段时间🌹。

02/04/2020 100k miles! 纪念一下

目前遇到的问题:

  1. 刹车尾灯 某次出游发现右边的刹车尾灯不亮了,很好办,网上买一对和车型兼容的尾灯就行了,自己安装非常容易。花 费$4.99.

  2. 遮阳挡板 这个买来的时候就是破损的,我一直没管它,但有时阳光太强这个挡板活动有点问题导致体验不是很好,于是 就在网上买了一个自己装上,花费$29.98.

  3. 胎压传感器 这种传感器的电池寿命一般在5~10年之间,看来这车之前都没换过,不巧被我遇到了。我在亚马逊上一次性买 了4个兼容的传感器,准备把四个轮胎上的都换掉。

需要注意的是,TPMS胎压传感器需要专业人士和工具更换,要先确认工具能正确的识别它,然后再安装。安 装步骤一般是先将轮胎放气,卸载,然后更换。特别要注意传感器需兼容车载电脑。我买的是 pre-programmed的产品,315MHz + 433MHz兼容,不过安装后仍需要relearn车载控制器。一定要仔细 阅读说明书哦。

我找了Costco Tire Center帮我更换,很不幸,他们的工具无法识别我买的sensor (I doubt)…于是 就只能使用他们的sensor了,价格$44.99/个。最后加上labor fee总共花了$252.61。之前我去咨询了 其他的auto repair,有的4个要charge $500,呵呵😑。

要注意的是他们会询问车的年份和型号,以及发动机类型(几缸)。然后交钱,给你一个磁性号码牌,放在车 顶上,然后你就可以到处闲逛,比如去Costco看看烤鸡,完事后会打电话叫你去取车。

还需要注意的是,随着气温骤降,TPMS warning light may go on,这是因为气温降低,轮胎里的空气 收缩导致胎压下降。可以参考这篇文章: https://www.lesschwab.com/article/tpms-light-coming-on-in-cold-weather-heres-why.html

可以去gas station去自己打气,最好自己买个tire gauge,Amazon上很多选择,感觉这很必要。 https://www.dummies.com/home-garden/car-repair/wheels-tires/how-to-add-air-to-your-tires/ 我仔细研究了一下Amazon上售卖的tire gauge with inflation and deflation,感觉一般般呀,特 别是便携12DV车充的,看差评可能会烧保险丝。。。 最后就没买😂,不过可以考虑入手一个机械式测压的。

我直接去了costco,在 https://www.costcotireappointments.com 上进行预约即可。或者早上早 点去直接听到garage门口让工作人员帮忙补补气即可,打气后一般过一会就正常了。

车辆正常保养维护

又到了该保养的时候了,maintenance light blinks everyday! 为了做到心里有数,pre-research is a must! 最该看的,其实就是car manual了,每个车都会有的,里面会告诉你一些基本的使用和保养 常识,当然了,很多人也不关心这个,反正交给4S店或者其他auto repair去做了。

就拿我的车来说吧,5k miles左右会做一个保养,我一般会做的项目包括:

  1. change engine oil (must)
  2. change engine oil filter (must)
  3. tire check, brake pads check
  4. battery get tested
  5. change engine air filter (depends, but should)
  6. change cabin air filter (recommand)
  7. washer fluid

机油不说了,保养主要就是换机油,有的auto repair如果你不说,他不会给你换机油过滤器的。。。但最 好换了。轮胎检查一下,特别是spare,没气了打气,否则爆胎了你拿啥顶上?刹车片看看需不需要更换。

电池看看是否正常,电压测测,现代车辆都是车载电脑操控,需要一个稳定输出的电池。

引擎滤网需要更换,我这几次观察了一下,如果汽车的使用环境比较好,污染物少,用了10k miles的滤网 还算干净,但还是换了,很简单的操作. 车厢空气滤网,这个很容易脏,建议更换。更换engine air filter非常简单,工具只需要Ratchet Socket Wrench and Sockets, 注意socket的直径匹配就行: 其他相关工具的如下:

雨刮水不够了,自己加满,但最好不要用tap water,网上有很多去污剂可以考虑混合一下,如果在零下的 环境中使用,还需要加防冻剂。我买的是QWIX windshield washer fluid, 1/4 oz makes one gallon windshield washer fluid.

100k miles保养,还需要考虑:

  1. coolant
  2. power steering fluid
  3. transmission fluid
  4. brake fluid
  5. change spark plugin
  6. tire rotate

这些项目都有自己的更换周期,特别是那几个fluid。取决于你车的具体情况。 所有这些保养,经过研究,都可以自己完成😃,就是要自己买工具。这个以后准备妥当了再更新一下。

这次保养,我除了change engine oil (filter), spark-plugin, 检查rear brake pads磨损殆尽 也和brake fluid一起更新了,花费$420 (# ̄~ ̄#)~ Coolant 和 power steering fluid 没有 更换,说没什么必要,人工费也挺贵的。其实我觉得brake change去costco或许会便宜很多,但当时嫌麻 烦就没去问,下次就注意了。

Battery replacement

今天早上发现发动不了车了!原因是电池电量不足,毕竟已经快6年没换电池了!

首先,如何紧急发动,用jumper starter, 这个东西最好备一个在车后备箱里,买最简易的那种需要另一 个车供电的, 在网上买一个road应急包里很多工具!

使用jumper starter 的步骤参考car manual,非常的详细,注意的点:

  1. connect positive first: discharged car then assistant car
  2. connect negative then: assistant car then ground(it is not battery negative, you can connect to the screw in the engine room) on discharged car
  3. boot assistant car for 5 mins and slightly push gas pedal
  4. boot discharged car, turning key stays 1~2 seconds
  5. remove in reverse order: dead car ground then assistant car
  6. remove positive on assistant then discharged car

电池的更换, 对于我这款老车,非常简单,去costco 买一个同款电池自己安装(当时买成 $138 total), 废旧电池可以去costco 回收 $15. 工具: socket wrench set and screwdriver set.

电池的接线:

  1. uninstall: remove negative first
  2. install: put positive first

安装完成后,按照car manual 的指示,re-initialize tire pressure value. 其他车可能在安装 完成后需要重新初始化车在电脑等等.

When build docker images, sometimes we need to use some files to install some packages inside container, for example when build redhat docker image: redhat.repo, entitlement/ and rpm-gpg/ are needed for package installation.

But we don’t want to use COPY command in dockerfile to copy them into image, that will add layers to store them when run docker build, not safe. The solution is mount these files in docker run, after install then commit, docker commit will not include any data in volumes mounted inside the container.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## mount redhat repo and keys, install packages
docker run --detach \
--name=serviceosbase \
--user 0 \
-v /etc/yum.repos.d/redhat.repo:/etc/yum.repos.d/redhat.repo \
-v /etc/pki/rpm-gpg:/etc/pki/rpm-gpg \
-v /etc/pki/entitlement:/etc/pki/entitlement \
--entrypoint=/bin/sh \
${DOCKER_IMAGE_TAG}:1 \
-c 'tail -f /dev/null'

docker exec serviceosbase /bin/sh -c "yum install -y glibc glibc-common systemd
systemd-libs openssl-libs && yum update -y && rm -rf /var/tmp/yum-* && yum
makecache fast"

docker commit serviceosbase ${DOCKER_IMAGE_TAG}:1

You can check the layers with docker history <image> command:

1
2
3
4
5
6
7
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
1f6e112efb83 About a minute ago /bin/sh -c #(nop) ENV LANG=en_US.UTF-8 LANGU 0 B
6060bfb14056 About a minute ago /bin/sh -c rm /etc/yum.repos.d/ubi.repo && 10.83 MB
543fa76542de 2 minutes ago /bin/sh -c #(nop) MAINTAINER XXX 0 B
6558c4297a5d 2 minutes ago /bin/sh -c #(nop) LABEL name=IIS Services ve 0 B
6fecccc91c83 5 weeks ago 7.06 kB
<missing> 5 weeks ago 204.8 MB Imported from -

Compare with dockerfile, no layer is for mount data after commit.

0%