k8s搭建(超详细,保姆级教程)

Posted ヾ一封信

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s搭建(超详细,保姆级教程)相关的知识,希望对你有一定的参考价值。

1、简介

这里就不赘述,想要了解的朋友直接去这里深入了解什么是K8S

2、环境要求

  • 2台以上机器,操作系统 CentOS7.7-64位系统
  • 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
  • 集群中所有机器之间网络互通
  • 可以访问外网,需要拉取镜像 禁止swap分区

3、部署准备(我这里是使用虚拟机,可以买云服务器)

4、开始部署

4.1、安装docker

我准备了2台机器172.168.200.130(master)、172.168.200.131(node1),也测试了2台是内网互通。

[root@localhost ~]# ping 172.168.200.130  #node1 ping master节点
PING 172.168.200.130 (172.168.200.130) 56(84) bytes of data.
64 bytes from 172.168.200.130: icmp_seq=1 ttl=64 time=0.243 ms
64 bytes from 172.168.200.130: icmp_seq=2 ttl=64 time=0.142 ms
64 bytes from 172.168.200.130: icmp_seq=3 ttl=64 time=0.192 ms
64 bytes from 172.168.200.130: icmp_seq=4 ttl=64 time=0.224 ms

[root@localhost ~]# ping 172.168.200.131 #master ping node1节点
PING 172.168.200.131 (172.168.200.131) 56(84) bytes of data.
64 bytes from 172.168.200.131: icmp_seq=1 ttl=64 time=0.021 ms
64 bytes from 172.168.200.131: icmp_seq=2 ttl=64 time=0.110 ms
64 bytes from 172.168.200.131: icmp_seq=3 ttl=64 time=0.035 ms
64 bytes from 172.168.200.131: icmp_seq=4 ttl=64 time=0.042 ms

所有机器都必须安装docker环境。


 #查看系统是否已安装docker
rpm -qa|grep docker

#卸载旧版本docker
sudo yum remove docker*  

 #安装yum工具
sudo yum install -y yum-utils  device-mapper-persistent-data  lvm2

#配置docker的yum下载地址
sudo yum-config-manager \\
--add-repo \\
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 

#生成缓存
sudo yum makecache 

#查看docker版本
yum list docker-ce --showduplicates | sort -r 


选择19.3.9版本安装

 #安装docker的指定版本
sudo yum install -y docker-ce-19.03.9-3.el7 docker-ce-cli-19.03.9-3.el7 containerd.io

#配置开机启动且立即启动docker容器
systemctl enable docker --now 

#创建docker配置
sudo mkdir -p /etc/docker 

 #配置docker的镜像加速
sudo tee /etc/docker/daemon.json <<-EOF

  "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": 
    "max-size": "100m"
  ,
  "storage-driver": "overlay2"

EOF

#加载配置
sudo systemctl daemon-reload 
#重启docker
sudo systemctl restart docker 

##查看docker版本,看是否安装成功
[root@localhost ~]# docker version
Client: Docker Engine - Community
 Version:           19.03.9
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        9d988398e7
 Built:             Fri May 15 00:25:27 2020
 OS/Arch:           linux/amd64
 Experimental:      false
......

4.2、安装Kubernetes

所有机器配置自己的hostname(不能是localhost)172.168.200.130机器我配置为master,172.168.200.131为node1。

hostnamectl set-hostname master #在172.168.200.130执行
hostnamectl set-hostname node1 #在172.168.200.131执行

所有机器必须关闭swap分区,不为0则说明没有关闭;禁用selinux;允许 iptables 检查桥接流量(k8s官网)。

[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1980         174        1474           9         331        1655
Swap:          3071           0        3071

##关闭swap分区
swapoff -a  
sed -ri 's/.*swap.*/#&/' /etc/fstab 

## 把SELinux 设置为 permissive 模式(相当于禁用)
sudo setenforce 0 
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config 

## 允许 iptables 检查桥接流量 
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

4.3、安装kubelet、kubeadm、kubectl

所有机器配置k8s的yum源地址及安装并启动kubelet。

#配置k8s的yum源地址
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
   http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

#安装 kubelet,kubeadm,kubectl
sudo yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9

#启动kubelet
sudo systemctl enable --now kubelet

#所有机器配置master域名
echo "172.168.200.130  master" >> /etc/hosts

4.4、初始化master主节点

我这里是把172.168.200.130作为master,–apiserver-advertise-address值为master的IP、–control-plane-endpoint值为master的域名、–image-repository 值为镜像仓库、–kubernetes-version指定k8s的版本、–service-cidr指定service的网段、–pod-network-cidr指定pod的网段。更多初始化参数详情点击这里

kubeadm init \\
--apiserver-advertise-address=172.168.200.130 \\
--control-plane-endpoint=master \\
--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \\
--kubernetes-version v1.20.9 \\
--service-cidr=10.96.0.0/16 \\
--pod-network-cidr=192.168.0.0/16 

初始话完毕后,需要记录如下信息,后续会使用到。

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join master:6443 --token rk6er7.7pmgpxdkq12t45r7 \\
    --discovery-token-ca-cert-hash sha256:7045e72a64def658c8ce1ebebdc6e149326c0c7fa4815b387a8edfc7e2123f97 \\
    --control-plane 

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join master:6443 --token rk6er7.7pmgpxdkq12t45r7 \\
    --discovery-token-ca-cert-hash sha256:7045e72a64def658c8ce1ebebdc6e149326c0c7fa4815b387a8edfc7e2123f97 

执行上述记录的信息,然后查看master的运行情况,发现有2个名为 coredns-*还未运行成功,这里就需要安装网络插件。

## 在master节点执行
 mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

4.5、安装网络插件

前置准备,我这里不适用防火墙来控制转发,而是使用ipvs(k8s版本必须是1.18以上(含))。

##所有机器开启ipvs,先检查是否有ipvs 所需模块,只要报command not found就是没有。
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4

## 引入ipvs所需模块
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4

##更改kube-proxy的模式为ipvs
[root@master ~]# kubectl edit configMap kube-proxy -n kube-system
 ipvs:
  ......
    kind: KubeProxyConfiguration
    metricsBindAddress: ""
    mode: "ipvs" #设置为ipvs,不设置默认使用iptables
    
##重启所有的kube-proxy
[root@master ~]# kubectl get pod -A | grep kube-proxy | awk 'system("kubectl delete pod "$2" -n kube-system")'
pod "kube-proxy-689h8" deleted

##查看k8s主节点运行情况
[root@master ~]# kubectl get pod -A
NAMESPACE     NAME                             READY   STATUS    RESTARTS   AGE
kube-system   coredns-5897cd56c4-56mmj         0/1     Pending   0          8m38s
kube-system   coredns-5897cd56c4-mgfmh         0/1     Pending   0          8m38s
kube-system   etcd-master                      1/1     Running   0          8m51s
kube-system   kube-apiserver-master            1/1     Running   0          8m51s
kube-system   kube-controller-manager-master   1/1     Running   0          8m51s
kube-system   kube-proxy-l6946                 1/1     Running   0          8m38s
kube-system   kube-scheduler-master            1/1     Running   0          8m51s

##查看proxy是否以ipvs模式运行,发现已经换成了IPv4
[root@master ~]# kubectl logs kube-proxy-l6946 -n kube-system
......
I0623 09:03:38.347008       1 server_others.go:258] Using ipvs Proxier.


安装网络插件。我这里使用的是calico。这一步必须在所有work节点加入之前操作。

##下载calico的配置文件(最新)
curl https://docs.projectcalico.org/manifests/calico.yaml -O >> calico.yaml

##引入calico文件,发现报错。其实是版本问题,重新下载v3.20即可
[root@master ~]# kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
......
error: unable to recognize "calico.yaml": no matches for kind "PodDisruptionBudget" in version "policy/v1"

##重新下载calico插件,报错就解决了。
[root@master ~]# curl https://docs.projectcalico.org/v3.20/manifests/calico.yaml -O  >> calico.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  198k  100  198k    0     0   229k      0 --:--:-- --:--:-- --:--:--  229k
[root@master ~]# 
[root@master ~]# kubectl apply -f calico.yaml  #卸载则使用kubectl delete -f calico.yaml 
configmap/calico-config unchanged
......
[root@master ~]# 

##再次查看master节点的运行情况,发现之前的coredns-*也已经运行起来了,到此master节点配置完毕。
[root@master ~]# kubectl get pod -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-6d9cdcd744-49vrr   1/1     Running   0          12m
kube-system   calico-node-8gpm2                          1/1     Running   0          13m
kube-system   coredns-5897cd56c4-56mmj                   1/1     Running   0          28m
kube-system   coredns-5897cd56c4-mgfmh                   1/1     Running   0          28m
kube-system   etcd-master                                1/1     Running   0          28m
kube-system   kube-apiserver-master                      1/1     Running   0          28m
kube-system   kube-controller-manager-master             1/1     Running   0          28m
kube-system   kube-proxy-l6946                           1/1     Running   0          119s
kube-system   kube-scheduler-master                      1/1     Running   0          28m

4.6、node工作节点加入master节点

还记得4.4步骤,初始化master节点后的信息吗?work加入master节点的命令如下,需要切换到非master节点的机器上执行。

##发现无法加入,这是因为我们开了防火墙,所以关闭即可(生产不能关闭,需要放行对应端口)
[root@node1 ~]# kubeadm join master:6443 --token rk6er7.7pmgpxdkq12t45r7     --discovery-token-ca-cert-hash sha256:7045e72a64def658c8ce1ebebdc6e149326c0c7fa4815b387a8edfc7e2123f97
[preflight] Running pre-flight checks
	[WARNING Hostname]: hostname "node1" could not be reached
	[WARNING Hostname]: hostname "node1": lookup node1 on 114.114.114.114:53: no such host

## 查看防火墙运行状态
[root@master ~]# service firewalld status
Redirecting to /bin/systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2022-06-23 15:16:19 CST; 1h 32min ago
     Docs: man:firewalld(1)
 Main PID: 591 (firewalld)
    Tasks: 2
   Memory: 284.0K
   CGroup: /system.slice/firewalld.service
           └─591 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
           
##所有机器停止且永久关闭防火墙(生产不能关闭,这里只是用作学习)
[root@master ~]# sudo service firewalld stop && systemctl disable firewalld
Redirecting to /bin/systemctl stop firewalld.service

## 再次执行加入命令,发现报错(这里是k8s与docker的驱动不同的问题),我们docker设置的是systemd
[root@node1 ~]# kubeadm join master:6443 --token rk6er7.7pmgpxdkq12t45r7     --discovery-token-ca-cert-hash sha256:7045e72a64def658c8ce1ebebdc6e149326c0c7fa4815b387a8edfc7e2123f97
......
[kubelet-check] It seems like the kubelet is not running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.

## 查看k8s的驱动,发现与我们配置的docker不一致
[root@master ~]# cat /var/lib/kubelet/config.yaml |grep group
cgroupDriver: cgroupfs

##修改k8s的驱动
[root@master ~]# kubectl edit cm kubelet-config-1.20 -n kube-system

##重新执行节点重新加入,这样基本算成功了,
[root@node1 ~]# kubeadm join master:6443 --token 35h05t.96u192eube0wy9vk     --discovery-token-ca-cert-hash sha256:6173250bbe1e64ff86ba0502cddff67de573ce75c2fb0054afcb64d8769c1a0b
......
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

主节点查看work节点运行情况,发现node1节点没有准备好,处理node1异常情况如下:

[root@master ~]# kubectl get nodes
NAME     STATUS     ROLES                  AGE    VERSION
master   Ready      control-plane,master   46m    v1.20.9
node1    NotReady   <none>                 5m5s   v1.20.9

##查看pod的运行情况,发现有一个calico的pod节点运行失败
[root@master ~]# kubectl get pod -A 
NAMESPACE     NAME                                       READY   STATUS                  RESTARTS   AGE
kube-system   calico-kube-controllers-6d9cdcd744-h4tzc   1/1     Running                 0          43m
kube-system   calico-node-hmzdn                          0/1     Init:ImagePullBackOff   0          6m10s
kube-system   calico-node-ntrcr                          1/1     Running                 0          43m
kube-system   coredns-5897cd56c4-s84wj                   1/1     Running                 0          47m
kube-system   coredns-5897cd56c4-t7tx7                   1/1     Running                 0          47m
kube-system   etcd-master                                1/1     Running                 0          47m
kube-system   kube-apiserver-master                      1/1     Running                 0          47m
kube-system   kube-controller-manager-master             1/1     Running                 0          47m
kube-system   kube-proxy-hgh7j                           1/1     Running                 0          44m
kube-system   kube-proxy-v2mqr                           1/1     Running                 0          6m10s
kube-system   kube-scheduler-master                      1/1     Running                 0          47m

##查看构建情况,发现是node1节点的cni镜像下载失败,
[root@master ~]# kubectl describe pod calico-node-hmzdn -n kube-system
......
  Warning  Failed     2m4s                   kubelet            Failed to pull image "docker.io/calico/cni:v3.20.5": rpc error: code = Unknown desc = Get https://registry-1.docker.io/v2/calico/cni/manifests/sha256:8fb230289086a9962799e055c93bc51c74d16158ba09ab23c619af509419f90d: read tcp 172.168.200.131:45062->34.237.244.67:443: read: connection reset by peer
  Normal   BackOff    80s (x7 over 5m58s)    kubelet            Back-off pulling image "docker.io/calico/cni:v3.20.5"
  Warning  Failed     80s (x7 over 5m58s)    kubelet            Error: ImagePullBackOff
  
##在node1查看cni:v3.20.5镜像已经下载,那么重新到master节点把calico-node-hmzdn删掉重启即可
[root@node1 ~]# docker images|grep cni
calico/cni                                                    v3.20.5             73dc08b04b58        2 months ago        138MB
[root@node1 ~]# 

## 删除旧的pod,k8s会自动创建新的pod,等一会发现正常运行。
[root@master ~]# kubectl delete pod calico-node-hmzdn -n kube-system
pod "calico-node-hmzdn" deleted
[root@master ~]# kubectl get pod -A 
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-6d9cdcd744-h4tzc   1/1     Running   0          46m
kube-system   calico-node-ntrcr                          1/1     Running   0          46m
kube-system   calico-node-qbpf5                          1/1     Running   0          6s
kube-system   coredns-5897cd56c4-s84wj                   1/1     Running   0          50m
kube-system   coredns-5897cd56c4-t7tx7                   1/1     Running   0          50m
kube-system   etcd-master                                1/1     Running   0          50m
kube-system   kube-apiserver-master                      1/1     Running   0          50m
kube-system   kube-controller-manager-master             1/1     Running   0          50m
kube-system   kube-proxy-hgh7j                           1/1     Running   0          48m
kube-system   kube-proxy-v2mqr                           1/1     Running   0          9m19s
kube-system   kube-scheduler-master                      1/1     Running   0          50m

## 在执行kubectl get nodes,发现node1节点已经成功加入主节点。
[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   53m   v1.20.9
node1    Ready    <none>                 12m   v1.20.9

4.7 当master init有误时

这里是对master重置,不需要重置的略过。

强制重置k8s节点
[root@master ~]# kubeadm reset -f

移除相关数据
[root@master ~]#  rm -rf /etc/cni /etc/kubernetes /var/lib/dockershim /var/lib/etcd /var/lib/kubelet /var/run/kubernetes ~/.kube/*

k8s这些镜像没有的从这里拿吧。
链接:https://pan.baidu.com/s/1LFDY4gEMvOKinyhq08cClQ?pwd=0rqy
提取码:0rqy

[root@master ~]# kubeadm config images list --kubernetes-version v1.20.9
kube-apiserver:v1.20.9
kube-controller-manager:v1.20.9
kube-scheduler:v1.20.9
kube-proxy:v1.20.9
pause:3.2
etcd:3.4.13-0
coredns:1.7.0

后续实战可以看这篇文章【K8S实战】-超详细教程(一)

:有开启防火墙的小伙伴需要放行一些端口,具体放行哪些端口详情点这里

资料参考:

保姆级教程 CSS 知识点梳理大全,超详细!!!

保姆级教程 CSS 知识点梳理大全,超详细!!!

✴️大家好,我是王同学,好久不见,趁着假期王同学把CSS 知识点梳理了一遍
✴️如果对你有帮助就给我点个赞吧,这样我们就互不相欠了
✴️星光不负赶路人,所有的幸运都来自于坚持不懈的努力,大家一起加油吧

一、前端三层

二、CSS的书写位置

(一)、内嵌式

  • 内嵌式,顾名思义,内嵌在.html文件中
  • <head></head>标签中,书写 <style></style>标签对,里面书写CSS语句。


(二)、外链式

  • 可以将CSS单独存为.css文件,然后用link标签引入它

  • 外链式的优点:多个HTML文件,可以共用一个CSS样式表文件



(三)、 导入式

导入式是最不常见的样式表导入方法,使用导入式引入文件,不会等待CSS文件加载完毕,而是会立即渲染HTML结构

(四)、行内式

行内式: 样式可以直接通过style属性写在标签上,行内式牺牲了样式表的批量设置样式的能力,只能给一个标签设置样式,所以不常用。

三、CSS选择器

首先我们来介绍传统的CSS2.1 选择器

(一)、标签选择器

标签选择器:又称元素选择器,类型选择器,它直接使用元素的标签名当做选择器,将选择页面上所有的标签

标签选择器将选择页面上所有该种标签,无论这个标签所处位置的深浅


标签选择器的覆盖面非常大,所以通常用于标签的初始化

(二)、id选择器

  • 标签可以有id属性,它是这个标签的唯一标识
  • id的命名只能由字母、数字、下划线、短横线构成,且不能以数字开头,字母区分大小写,但习惯上一般为小写字母
  • 同一个页面上不能有相同的id标签
  • CSS选择器可以使用#井号选择指定的id标签

(三)、类选择器

  • class属性表示类名
  • 类名的命名规范和id的命名规范相同
  • 我们使用点.前缀来指定class的标签
  • class类名十分灵活,多个标签可以为相同的类名
  • 同一个标签可以同时属于多个类,类名用空格隔开





在开发中我们也用到过原子类,这里简单的介绍一下

(四)、原子类

  • 在做网页前、可以将所有的常用字号、文字颜色、行高、外边距、内边距等都设置为单独的类。

  • 在HTML标签就可以“则需选择”它的类名,这样可以非常快速的添加一些常见的样式

<style>
        .fs18 {
            font-size: 18px;
        }
        
        .fs20 {
            font-size: 20px;
        }
        
        .fs22 {
            font-size: 22px;
        }
        
        .fs24 {
            font-size: 24px;
        }
        
        .fs26 {
            font-size: 26px;
        }
        
        .color-blue {
            color: blue;
        }
        
        .color-red {
            color: red;
        }
        
        .color-orange {
            color: orange;
        }
        
        .color-pink {
            color: pink;
        }
        
        .color-purple {
            color: purple;
        }
    </style>
</head>

<body>
    <p class="fs18 color-blue">好好学习 天天向上</p>
    <p class="fs20 color-red">好好学习 天天向上</p>
    <p class="fs22 color-orange">好好学习 天天向上</p>
    <p class="fs24 color-pink">好好学习 天天向上</p>
    <p class="fs26 color-purple">好好学习 天天向上</p>

</body>

(五)、复合选择器

后代选择器


交集选择器

并集选择器

并集选择器也叫做分组选择器,逗号表示分组

(六)、伪类选择器

伪类是添加到选择器的描述性词语,指定要选择的元素的特殊状态,超级链接拥有4个特殊的状态

a 标签的伪类书写,要按照“爱恨准则”的顺序,否则会有伪类不生效的问题

    <style>
        a:link {
              color: rgb(255, 0, 242);
        }
        
        a:visited {
            color: red;
        }
        
        a:hover {
            color: pink;
        }
        
        a:active {
            font-size: 40px;
            color: green;
        }
    </style>
</head>

<body>
    <p>
        <a href="http://www.baidu.com"> 百度</a>
    </p>
    <p>
        <a href=" http://www.jd.com"> 京东</a>
    </p>
    <p>
        <a href="http://www.taobao.com"> 淘宝</a>
    </p>
    <p>
        <a href="http://www.jd.com"> 慕课</a>
    </p>
</body>

(七)、元素关系选择器

(七)、子选择器

当使用 >符号分隔两个元素时,它只会匹配那些作为第一个元素的直接后代元素,即两个标签为父子关系


(八)、相邻兄弟选择器

  • 相邻兄弟选择器(+)介于两个选择器之间,当第二个元素紧跟着第一个元素之后,并且两个元素都是属于同一个父元素的子元素,则第二个元素将被选中。
  • 说白了,a+b就是选择紧跟在a后面的一个b

(九)、通用兄弟选择器(~)

通用兄弟选择器(~),a~b选择a元素之后所有同层级b元素

(十)、序号选择器

(十一)、:first-child

first-child表示选择第一个子元素,比如下面的例子就是表示选择.box盒子中的第一个p

(十二)、:last-child

:last-child表示选择最后一个子元素,比如下面的例子

(十二)、: nth-child()

: nth-child()可以选择任意序号的子元素

:nth-child()可以写成 an+b的形式,表示从b开始每个a选一个





 <style>
        .box p:first-child {
            color: red;
        }
        
        .box p:last-child {
            color: aqua;
        }
        
        .box p:nth-child(3) {
            color: orange;
        }
        
        .box p:nth-child(2n) {
            color: pink;
        }
        
        .box1 p:nth-child(2n+1) {
            color: red;
        }
    </style>
</head>

<body>
    <div class="box">
        <p>1</p>
        <p>2</p>
        <p>3</p>
        <p>4</p>
        <p>5</p>
        <p>6</p>
        <p>7</p>
        <p>8</p>
        <p>9</p>
    </div>
    <div class="box1">
        <p>1</p>
        <p>2</p>
        <p>3</p>
        <p>4</p>
        <p>5</p>
        <p>6</p>
        <p>7</p>
        <p>8</p>
        <p>9</p>
    </div>

(十三)、序号选择器的兼容性

(十四)、属性选择器


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 
        [alt]  有这个属性
        [alt ="背景故宫"] 精准匹配
        [alt ^="abc"] 开头位置匹配
        [alt $="abc"]  结尾位置匹配
        [alt *="abc"]  任意位置匹配
        [alt |="abc"]    abc-开头
        [alt ~="abc"]  abc为空格分开的独立部分
        
        */
        
        img {
            width: 300px;
        }
        
        img[alt^="北京"] {
            border: 5px solid purple;
        }
        
        img[alt$="夜景"] {
            border: 5px solid rgb(236, 184, 12);
        }
        
        img[alt*="美"] {
            border: 5px solid rgb(52, 5, 138);
        }
        
        img[alt |="参赛作品"] {
            border: 5px solid rgb(224, 228, 9);
        }
        
        img[alt~="手机拍摄"] {
            border: 5px solid pink;
        }
    </style>
</head>

<body>
    <img src="images/bj/0.jpg" alt="北京故宫">
    <img src="images/bj/1.jpg" alt="北京鸟巢">
    <img src="images/bj/2.jpg" alt="北京十七孔桥">


    <img src="images/wx/0.jpg" alt="参赛作品-无锡体育场">
    <img src="images/wx/1.jpg" alt="手机拍摄 无锡太湖">
    <img src="images/wx/2.jpg" alt="无锡美景">
    <img src="images/wx/3.jpg" alt="无锡夜景">

</body>

</html>

(十五)、CSS3新增伪类











(十六)、伪元素

CSS3新增了伪元素特性,顾名思义,表示虚拟动态创建的元素
伪元素用双冒号表示,IE8可以兼容单冒号

::before

::after


(十七)、::selection


(十八)、::first-letter和::first-line


三、层叠性和选择器权重的计算

  • CSS全名叫做“层叠样式表”,层叠性是他很重要的性质
  • 层叠性:多个选择器可以同时作用于同一个标签,效果叠加

    如果多个选择器的定义有冲突呢?CSS有严密的处理规则



复杂选择器的计算

复杂选择器可以通过(ID的个数,class的个数,标签的个数)的形式,计算权重



四、文本与字体属性

(一)、常用的文本字体属性

  • color属性可以设置文本内容的前景色

  • color属性主要用于英语单词、十六进制、rgba()、rgb() 等表示方法

  • 用英语单词表示法,比如:color:red;仅仅用于学习时临时设置一下颜色,工作时不用这样的形式,因为追求精确。

(二)、十六进制表示法

十六进制表示法是所有设计软件中常用的颜色表示方法,设计师给我们的设计上面标注的图标颜色,通常为十六进制

(三)、rgb() 表示法

(四)、rgba()表示法

颜色可以使用rgba() 表示法,最后一个参数表示透明度,介于0-1之间,0表示纯透明,1表示纯实心

(五)、font-size属性

font-size属性用来设置字号,单位为px 后面还会说到em和rem

网页文字正文字号通常是16px浏览器最小支持10px

(六)、font-weight属性

  • font-weight属性设置字体的粗细程度,通常就用normal和bold两个值

(七)、font-style属性

作用:设置文字的倾斜

(八)、text-decoration属性

text-decoration属性用于设置文本的修饰外观的(下划线,删除线)

(九)、font-family属性

  • font-family属性用于设置字体的属性
  • 字体可以是列表的形式,一般英语字体放到前面,后面的字体是前面的字体的后备字体
  • 字体名称中有空格,必须要用引号来包裹
font-family:" 微软雅黑";
font-family: serif,"Times New Roman","微软雅黑";

中文字体也可以称呼他们的名字

字体通常必须是用户计算机中已经安装好的字体,所以一般来说设置为微软雅黑和宋体的较多,设置成其他字体的较少

问题一:如何设置为用户电脑中没有的字体呢?那就必须自己定义新的字体,这就需要我们有字体文件,当用户加载网页的时候,会同时下载这些字体

定义字体,当我们拥有以下字体文件之后,就可以使用@font-face定义字体


(十)、阿里巴巴普惠体

阿里巴巴提供了一套免费商用授权的普惠字体,网址 https://www.iconfont.cn/webfont#!/webfont/index

使用阿里巴巴普惠字体也省去了下载的麻烦

使用步骤:

下载字体—使用font-face声明字体—定义使用 webfont 的样式—为文字加上对应的样式

第一步:下载字体

第二步:使用font-face声明字体(注意:在引用的时候要注意引用的路径哦)

第三步:定义使用 webfont 的样式

第四步:为文字加上对应的样式

(十一)、text-indent属性



(十二)、 line-height行高

  • line-height属性的单位可以是px为单位的数值
line-height:30px;
  • line-height属性的单位可以是 没有单位是数值,表示字号的倍数,这是最推荐的写法
line-height:1.5;
  • line-height属性也可以是百分数,表示字号的倍数
line-height:150%;


(十三)、单行文本垂直居中

行高等于盒子的高度,设置单行文本垂直居中对齐

设置text-align:center,即可实现文本水平居中


(十四)、font合写属性


(十五)、继承性

  • 文本相关的属性普遍具有继承性,只需要给祖先标签设置,即可在后代所有的标签中生效。
  • 因为文字相关的属性都有继承性,所以通常会设置body标签的字号、颜色、行高等、这样就能当做整个网页的默认样式了。

(十五)、继承性的就近原则

在继承的情况下,选择器权重计算失效,就近原则

五、盒子模型

(一)、什么是盒子模型

所有的HTML标签都可以看成矩形盒子,由width,height,padding、border构成,称为盒子模型



(二)、width属性

  • width属性表示盒子内容的宽度

  • width属性的单位通常是px,移动端开发也会涉及到百分数、rem等单位

  • 当块级元素(div 、h系列、li等)没有设置width属性时,它将自动撑满,但这并不意味着width可以继承

(三)、height属性