0%

前言

本文主要内容是 Python 中运算符 ==is 的区别。

进入正文前,首先简单介绍一下 Python 中对象的 3 个基本要素,id(身份标识)、type(数据类型)和value(值)。

正文

== 是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等,例如下面两个字符串间的比较:

1
2
3
4
>>> a = 'cheesezh'
>>> b = 'cheesezh'
>>> a == b
True

is 也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> x = y = [4,5,6]
>>> z = [4,5,6]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
>>>
>>> print id(x)
3075326572
>>> print id(y)
3075326572
>>> print id(z)
3075328140

可以明显的看到前 3 个比较都是 True, 最后一个是 False。

使用 id() 方法查看 x, y, z 的对象ID就明白了。

我在这里使用的是数组,其实,当它们是 tuple, list, dict 或者 set 时也一样。

不过,当类型是 int 或者 string 时,它们的对象ID都会一样,

1
2
3
4
5
6
7
8
>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = "asd"
>>> b = "asd"
>>> a is b
True

首先,在Ubuntu的Docker官方镜像中是没有缓存Apt的软件包列表的。因此在做其他任何基础软件的安装前,都需要至少先做一次apt-get update。有时为了加快apt-get安装软件的速度,还需要修改Apt源的列表文件/etc/apt/sources.list。相应的操作用命令表示如下:

1
sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list

在容器构建时,为了避免使用apt-get install安装基础软件的过程中需要进行交互操作,使用-y参数来避免安装非必须的文件,从而减小镜像的体积。

1
apt-get -y --no-install-recommends install

使用apt-get autoremove命令移除为了满足包依赖而安装的、但不再需要的包;使用apt-get clean命令清除所获得包文件的本地仓库。

DEBIAN_FRONTEND这个环境变量,告知操作系统应该从哪儿获得用户输入。如果设置为noninteractive,你就可以直接运行命令,而无需向用户请求输入(所有操作都是非交互式的)。这在运行apt-get命令的时候格外有用,因为它会不停的提示用户进行到了哪步并且需要不断确认。非交互模式会选择默认的选项并以最快的速度完成构建。请确保只在Dockerfile中调用的RUN命令中设置了该选项,而不是使用ENV命令进行全局的设置。因为ENV命令在整个容器运行过程中都会生效,所以当你通过BASH和容器进行交互时,如果进行了全局设置那就会出问题。

1
2
3
4
5
# 正确的做法 - 只为这个命令设置ENV变量
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3
# 错误地做法 - 为接下来的任何命令都设置ENV变量,包括正在运行地容器
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get install -y python3

示例:

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
FROM ubuntu:16.04

# Ali apt-get source.list
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
echo "deb-src http://archive.ubuntu.com/ubuntu xenial main restricted" >/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted" >>/etc/apt/sources.list && \
echo "deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted" >>/etc/apt/sources.list && \
echo "deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial universe" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse" >>/etc/apt/sources.list && \
echo "deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse" >>/etc/apt/sources.list && \
echo "deb http://archive.canonical.com/ubuntu xenial partner" >>/etc/apt/sources.list && \
echo "deb-src http://archive.canonical.com/ubuntu xenial partner" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted" >>/etc/apt/sources.list && \
echo "deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe" >>/etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse" >>/etc/apt/sources.list

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
vim \
python \
libopencv-dev \
python-pip \
&& rm -rf /var/lib/apt/lists/*

RUN pip install --upgrade pip \
numpy \
pymongo \
opencv-python

参考资源

Docker - 更换内部Ubuntu apt 为国内源

NFS 是 Network File System 的缩写,即网络文件系统。功能是让客户端通过网络访问不同主机上磁盘里的数据,主要用在类Unix系统上实现文件共享的一种方法。 本例演示 CentOS 7 下安装和配置 NFS 的基本步骤。

根据官网说明 Chapter 8. Network File System (NFS) - Red Hat Customer Portal,CentOS 7.4 以后,支持 NFS v4.2 不需要 rpcbind 了,但是如果客户端只支持 NFC v3 则需要 rpcbind 这个服务。

阅读全文 »

准备工作

查看系统版本

1
2
[root@k8s-master-1 ~]# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)

overlay2介绍

overlay的改进版,只支持4.0以上内核添加了Multiple lower layers in overlayfs的特性,所以overlay2可以直接造成muitiple lower layers不用像overlay一样要通过硬链接的方式(最大128层) centos的话支持3.10.0-514及以上内核版本也有此特性,所以消耗更少的inode

docker官方overlay2的PR:
https://github.com/moby/moby/pull/22126

LINUX KERNERL 4.0 release说明:
https://kernelnewbies.org/Linux_4.0

配置主机名

为将来要作为主节点的服务器设置主机名。

1
hostnamectl set-hostname k8s-master-1 --static

配置服务器hosts

各个服务器上都要配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@k8s-master-1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 k8s-master-1
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.212.155 salt

0.0.0.0 aliyun.one
0.0.0.0 lsd.systemten.org
0.0.0.0 pastebin.com
0.0.0.0 pm.cpuminerpool.com
0.0.0.0 systemten.org

192.168.200.19 k8s-master-1
192.168.154.14 ip-192-168-154-14
192.168.154.15 ip-192-168-154-15
192.168.154.16 ip-192-168-154-16

关闭swap,注释swap分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s-master-1 ~]# swapoff -a
[root@k8s-master-1 ~]# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Mon Mar 26 20:43:49 2018
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=848d5a8b-0ee9-481f-b1ff-833fb35cfd03 /boot xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
#/dev/mapper/centos-swap swap swap defaults 0 0

添加网易 yum 镜像

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
38
39
40
41
42
[root@k8s-master-1 ~]# cat /etc/yum.repos.d/CentOS-Base.repo
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base - 163.com
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://mirrors.163.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-7

#released updates
[updates]
name=CentOS-$releasever - Updates - 163.com
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
baseurl=http://mirrors.163.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-7

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - 163.com
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras
baseurl=http://mirrors.163.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-7

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - 163.com
baseurl=http://mirrors.163.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-7

关闭防火墙

在各个服务器上关闭防火墙

1
2
3
4
[root@k8s-master-1 ~]# systemctl stop firewalld.service            #停止firewall
[root@k8s-master-1 ~]# systemctl disable firewalld.service #禁止firewall开机启动
[root@k8s-master-1 ~]# systemctl stop iptables.service #停止iptables
[root@k8s-master-1 ~]# systemctl disable iptables.service #禁止iptables开机启动l

配置内核参数,将桥接的IPv4流量传递到iptables的链

各个服务器都要配置

1
2
3
4
5
[root@k8s-master-1 ~]# cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

禁用SELinux

1
2
[root@k8s-master-1 ~]# sestatus
SELinux status: disabled

安装配置 docker

官方文档地址:Install Docker Engine on CentOS

Docker官方文档对安装步骤描述已经足够详细, 过程并不复杂, 本文便不再赘述.

安装 docker

本文安装docker的版本是18.09, 安装时请按照文档描述的方式明确指定版本号yum install docker-ce-18.09.9-3.el7 docker-ce-cli-18.09.9-3.el7 containerd.io.

配置 docker

官方文档地址:容器运行时

1
2
3
4
5
6
7
8
9
10
11
12
[root@k8s-master-1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com", "https://docker.mirrors.ustc.edu.cn", "https://fzhifedh.mirror.aliyuncs.com"],
"insecure-registries": ["hub.51iwifi.com","alpha-harbor.51iwifi.com","192.168.195.2","134.108.20.13"],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}

安装完后重启

1
2
[root@k8s-master-1 ~]# systemctl enable docker
[root@k8s-master-1 ~]# systemctl start docker

同样在各个服务器上都要保持一致

安装 Kubernetes(kubectl, kubelet, kubeadm)

添加阿里kubernetes源

1
2
3
4
5
6
7
8
9
10
[root@k8s-master-1 ~]# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF

安装

1
2
[root@k8s-master-1 ~]# yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
[root@k8s-master-1 ~]# systemctl enable kubelet

初始化 master 节点

1
[root@k8s-master-1 ~]# kubeadm config print init-defaults > kubeadm-init.yaml

该文件有两处需要修改:

advertiseAddress: 1.2.3.4修改为本机地址
imageRepository: k8s.gcr.io修改为imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers

修改完毕后文件如下:

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
38
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 0.0.0.0
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master-1
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
scheduler: {}

下载镜像

1
[root@k8s-master-1 ~]# kubeadm config images pull --config kubeadm-init.yaml

执行初始化

1
[root@k8s-master-1 ~]# kubeadm config images pull --config kubeadm-init.yaml

等待执行完毕后, 会输出如下内容:

1
2
3
4
5
6
7
...
Your Kubernetes control-plane has initialized successfully!
...
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.200.19:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:a67698bdd29af4af0d70a563c4a17d1c751faabe65d7d3661eb90783568ecda6

最后两行需要保存下来, kubeadm join ...是其它worker节点加入所需要执行的命令.

接下来配置环境, 让当前用户可以执行kubectl命令:

1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

查看节点,kubectl get node

1
2
3
[root@k8s-master-1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-1 NotReady master 3m25s v1.18.0

node节点为NotReady,因为 pod coredns 没有启动,缺少网络pod.

安装 calico 网络

官方文档地址:Instructions

下载 calico 的 k8s 文件

1
2
3
[root@k8s-master-1 ~]# wget https://docs.projectcalico.org/v3.8/manifests/calico.yaml
[root@k8s-master-1 ~]# cat kubeadm-init.yaml | grep serviceSubnet:
serviceSubnet: 10.96.0.0/12

打开 calico.yaml, 将192.168.0.0/16修改为10.96.0.0/12

需要注意的是, calico.yaml中的IP和kubeadm-init.yaml需要保持一致, 要么初始化前修改kubeadm-init.yaml, 要么初始化后修改calico.yaml.

执行kubectl apply -f calico.yaml初始化网络.

此时查看node信息, master的状态已经是Ready了.

1
2
3
[root@k8s-master-1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-1 Ready master 15m v1.18.0

安装 dashboard

部署 dashboard

官方文档:网页界面 (Dashboard)

官方部署dashboard的服务没使用nodeport,将yaml文件下载到本地,在service里添加NodePort

创建用户

官方文档地址: Creating sample user

创建一个用于登录Dashboard的用户. 创建文件dashboard-adminuser.yaml内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system

执行命令kubectl apply -f dashboard-adminuser.yaml.

登录

官方文档地址:Bearer Token

使用token进行登录,执行下面命令获取token

1
kubectl describe secrets -n kubernetes-dashboard kubernetes-dashboard-token-t4hxz  | grep token | awk 'NR==3{print $2}'

复制该Token到登录页, 点击登录即可, 效果如下:

image%

添加其它 Worker 节点

在使用 kubeadm 初始化 master 节点后会有 kubeadm join ... 这样的返回信息,详见前文。

同时,默认你已经在其它的服务器中已经安装了 docker, kubernetes.

请注意在其它的服务器只需安装kubernetes,等初始化 master 节点后,执行如下命令将 Worker 加入集群:

1
2
kubeadm join 192.168.200.19:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:a67698bdd29af4af0d70a563c4a17d1c751faabe65d7d3661eb90783568ecda6

添加完毕后, 在Master上查看节点状态:

1
2
3
4
5
6
[root@k8s-master-1 k8s-master]# kubectl get node
NAME STATUS ROLES AGE VERSION
ip-192-168-154-14 Ready <none> 14d v1.18.0
ip-192-168-154-15 Ready <none> 14d v1.18.0
ip-192-168-154-16 Ready <none> 14d v1.18.0
k8s-master-1 Ready master 19d v1.18.0

参考资源

使用kubeadm在Centos8上部署kubernetes1.18

Kubernetes(一) 跟着官方文档从零搭建K8S

前言:

在生产环境中,首先服务器磁盘满了之后,会导致一系列小问题,网站能正常访问, 但是不能登录以及一些奇奇怪怪的问题,但是不能耽误用户访问呀,所以我们的及 时清理磁盘空间出来,让MySQL能够正常写入各种数据
阅读全文 »