Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

Worker node cluster join

Dockerkubernetes 구성 요소를 설치한 뒤 이전 포스트에서 cluster 초기화 시 생성된 스크립트를 실행하면 worker node로써 설정이 된다.

kubeadm join 192.168.4.78:6443 --token abcdefg.8rpr4mfmetbabcde --discovery-token-ca-cert-hash sha256:3a12345caaef12334567890cd3953d1234c3904ab70a8b949f32d6df12345

[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

worker 노드에서도 kubernetes config 관련 명령을 수행해주면 kubectl 명령을 이용할 수 있다.

kubectl get nodes

NAME       STATUS     ROLES                  AGE    VERSION
centos7    NotReady   control-plane,master   104s   v1.23.5
centos71   NotReady   <none>                 36s    v1.23.5

master node 설정 후 확인한 것과 같이 STAUS는 NotReady 상태로 표시된다. 이는 kubernetes 네트워크 관련 배포가 필요한 것으로 이후 관련 인스턴스를 배포하면 Ready 상태로 표시된다.

 

cluster 생성 후 24시간 경과 시

kubeadm init 수행 시 생성된 join 스크립트의 token은 24시간의 만료 시간을 가진다. 즉 24시간이 지나면 생성된 join script, 정확히 말하자면 token이 만료되어 사용이 불가능하다.

따라서 24시간 이후에는 갱신된 token을 확인하고 새 token을 이용한 join 스크립트를 사용해야 한다.

  • token 확인: TTL(Time To Live) 값을 보면 22h시간 사용가능함을 알 수 있다.
kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
abcdef.2zha2oqwp12abcd1   22h         2022-04-08T00:46:45Z   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   system:bootstrappers:kubeadm:default-node-token
  • 해당 token에 해당하는 sha256 값 확인
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
871c73bfcb0d0421f029faa7ba07201abf4f00abcdefghijklmnopqrstuvwxyz
  • 확인된 token, 과 sha256 값을 이용하여 join 명령을 수행한다.
kubeadm join 192.168.4.78:6443 --token abcdef.2zha2oqwp12abcd1 --discovery-token-ca-cert-hash sha256:871c73bfcb0d0421f029faa7ba07201abf4f00abcdefghijklmnopqrstuvwxyz

 

 

 

Kubernetes #1. 사전작업 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

쿠버네티스 공식 홈페이지의 가이드를 따르면 쉽게 설치할 수 있다.
하지만 경우에 따라 외부 연결이 불가능한 폐쇄망 등에 설치해야 하는 경우를 가정하여 설치하는 방법을 설명한다. (물론 이 방법도 쿠버네티스 공식 홈페이지에 잘 설명되어있다.)

기본적으로 쿠버네티스 클러스터는 노드간 통신에 별도의 네트워크를 사용한다.
(별도의 물리적 변경이 아닌 가상 환경) 이를 위해 브릿지 관련 설정을 변경한다.

이 포스트의 작업은 쿠버네티스 클러스터에 포함하는 모든 노드에서 수행해야 한다.

브릿지 네트워크 관련 설정 변경

[haedong@haedongg.net:~]$ sudo cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
[haedong@haedongg.net:~]$ sudo cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[haedong@haedongg.net:~]$ sudo sysctl --system
[haedong@haedongg.net:~]$ sudo sysctl -p 
net.ipv4.tcp_keepalive_time = 160
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_syncookies = 1
vm.min_free_kbytes = 524288
...중략
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1
...생략

SELINUX 해제

[haedong@haedongg.net:~]$ vi /etc/selinux/config
...중략...
# 기본값은 SELINUX=enforced disabled로 수정한다.
SELINUX=disabled 
...생략

 

swap 메모리 해제

swap 여부 확인

[haedong@haedongg.net:~]$ free -g
              total        used        free      shared  buff/cache   available
Mem:             62           3           0           0          57          57
Swap:            99           0          99

swap 해제

[haedong@haedongg.net:~]$ swapoff -a

해제 확인

[haedong@haedongg.net:~]$ free -g
              total        used        free      shared  buff/cache   available
Mem:             62           3           0           0          57          57
Swap:             0           0           0

fstab 수정 ( swap 파티션이 마운트되지 않도록 설정)

[haedong@haedongg.net:~]$ sudo vi /etc/fstab
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=111f15c1-7697-4597-1234-b7f231009876 /boot                   xfs     defaults        0 0
#/dev/mapper/centos-home /home                   xfs     defaults        0 0
# 아래 줄을 주석처리 한다.
#/dev/mapper/centos-swap swap                    swap    defaults        0 0

 

hostname 과 hosts 파일 수정

쿠버네티스는 기본적으로 kubeadm init 시 hostname을 참조한다. 별도의 DNS를 사용하지 않는다면 /etc/hosts 파일에 호스트 명과 IP 정보를 적어준다.

[haedong@haedongg.net:~]$ vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# 현재 서버의 정보가 없을 경우 다음 줄 추가 
192.168.192.168 haedongg.net

DD 명령을 이용한 부팅 가능 미디어 생성

linux 상에서 Windows 또는 Linux 설치를 위한 부팅 가능 USB 미디어를 생성하는 방법이다.
Windows에서는 Rufus 등을 이용하여 미디어를 생성하지만 Linux의 경우 Disk Dump 명령을 이용 하여 미디어를 생성할 수 있다.

dd는 파일을 변환하고 복사하는 것이 주 목적인 유닉스 및 유닉스 계열 운영 체제용 명령 줄 유틸리티이다.
유닉스에서 하드웨어와 특수 장치 파일용 장치 드라이버는 파일 시스템에서 마치 일반 파일처럼 나타난다.
dd는 기능이 개별 드라이버에서 구현되어 있는 경우 이러한 파일들을 읽거나 기록하는 것이 가능하다.
그러므로 dd는 하드 드라이브의 부팅 섹터를 백업하는 등의 일과 고정된 크기의 랜덤 데이터를 취득하기 위해 사용할 수 있다.
dd 프로그램은 복사 시 데이터에 변환을 수행할 수도 있는데, 여기에는 바이트 순서 스와핑, ASCII↔EBCDIC 텍스트 인코딩 변환을 포함할 수 있다. 1위키백과에서 발췌

일반적 사용방법은 다음과 같다

dd if="source file 또는 data 또는 device" of="target file 또는 device" bs="block size" count="block count"

부팅용 USB 를 만드는 경우는 다음과 같이 입력하면 된다.

[haedong@haedong:~]$ sudo dd if=linux-install-media.iso of=/dev/sdx bs=8M oflag=direct status=progress
595591168 bytes (596 MB) copied, 131.502109 s, 4.5 MB/s
71+1 records in
71+1 records out
602931200 bytes (603 MB) copied, 132.264 s, 4.6 MB/s

DNS 서버 구축

네임 서버(Name server)는 디렉터리 서비스 프로토콜을 실행하는 프로그램이나 서버를 통칭한다. 일반적으로, 인터넷에서 Domain Name Service (도메인 이름) 를 제공하는 서버를 말한다.1위키백과 에서 발췌

생각보다 단순한 서비스이다.
전제 조건은
1. 세상의 모든 네트워크에 연결된 장비는 숫자로 된 IP주소232bit: IPv4, 255.255.255.255 형식, 128bit: IPv6, FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 로 식별된다.
즉, www.haedongg.net 같은 주소를 가지는 장비는 없다는 얘기다.
2. 하지만 이 숫자로 된 주소는 인간이 기억하기 쉽지 않다.
3. 그래서 www.haedongg.net : 000.0000.000.000 같은 주소 연결이 필요하다.
는 것이다.

동작 원리는 다음과 같다.
– DNS 서버라는 녀석이 존재한다.
– 도메인 이름과 IP주소를 연결할 수 있는 정보를 가지고 있다.
(www.haedongg.net = 000.000.000.000 같은 정보)
– 사용자가 사용하는 PC에 DNS서버 정보를 미리 입력 해둔다.
– 웹 브라우저 등에서 www.haedongg.net을 입력한다.
– 사용자 컴퓨터는 hosts 라는 파일 안에 www.haedongg.net 이라는 정보가 있는지 확인한다.
– 없다면 미리 등록해둔 DNS 서버에 가서 www.haedongg.net 의 IP주소를 물어본다.
– DNS서버는 www.haedongg.net에 해당하는 주소 000.000.000.000를 반환한다.
– 000.000.000.000으로 이동한다.

위 역할을 하는 서버 DNS를 많은 ISP업체 등에서 제공하고 있다.
1.1.1.1 : cloudflare
8.8.8.8 : google
168.126.63.1 : KT
210.220.163.82 : SK boradband
164.124.101.2 : LG U+
등이 있다.

DNS 서비스 설치

haedong@haedong:/home/:]$ sudo yum install bind
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.kakao.com
Resolving Dependencies
--> Running transaction check
---> Package bind.x86_64 32:9.11.4-26.P2.el7_9.5 will be installed
...중략...
---> Package setools-libs.x86_64 0:3.3.8-4.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=====================================================================================================================
 Package                             Arch               Version                            Repository           Size
=====================================================================================================================
Installing:
 bind                                x86_64             32:9.11.4-26.P2.el7_9.5            updates             2.3 M
Installing for dependencies:
 GeoIP                               x86_64             1.5.0-14.el7                       base                1.5 M
Transaction Summary
=====================================================================================================================
Install  1 Package (+13 Dependent packages)
Total download size: 6.9 M
Installed size: 18 M
Is this ok [y/d/N]: y
Downloading packages:
(1/14): bind-libs-lite-9.11.4-26.P2.el7_9.5.x86_64.rpm                                        | 1.1 MB  00:00:00
...중략...
(14/14): setools-libs-3.3.8-4.el7.x86_64.rpm                                                  | 620 kB  00:00:00
---------------------------------------------------------------------------------------------------------------------
Total                                                                                9.2 MB/s | 6.9 MB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : 32:bind-license-9.11.4-26.P2.el7_9.5.noarch                                                      1/14
...중략...
  Verifying  : setools-libs-3.3.8-4.el7.x86_64                                                                 14/14

Installed:
  bind.x86_64 32:9.11.4-26.P2.el7_9.5

Dependency Installed:
  GeoIP.x86_64 0:1.5.0-14.el7                       audit-libs-python.x86_64 0:2.8.5-4.el7                  
  bind-libs-lite.x86_64 32:9.11.4-26.P2.el7_9.5     bind-license.noarch 32:9.11.4-26.P2.el7_9.5            
  bind-libs.x86_64 32:9.11.4-26.P2.el7_9.5          libcgroup.x86_64 0:0.41-21.el7                         
  policycoreutils-python.x86_64 0:2.5-34.el7        python-IPy.noarch 0:0.75-6.el7                         
  setools-libs.x86_64 0:3.3.8-4.el7

Complete!

서비스 설정

haedong@haedong:/home:]$ sudo  vi /etc/named.conf
// named.conf
options {
//서비스 요청을 받을 IP를 지정한다. IPv4 any로 변경한다.
        listen-on port 53 {any; };
//서비스 요청을 받을 IP를 지정한다. IPv6. any로 변경한다.
        listen-on-v6 port 53 { any; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
// 서비스 요청을 허용해야 한다. 
        allow-query     { any; };
        recursion yes;
        dnssec-enable yes;
        dnssec-validation yes;
        bindkeys-file "/etc/named.root.key";
        managed-keys-directory "/var/named/dynamic";
        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
        type hint;
        file "named.ca";
};

// 서비스 할 도메인 정보를 기재하는 파일이다. 
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

도메인 추가

haedong@haedong:/home:]$ sudo vi /etc/named.rfc1912.zones
// named.rfc1912.zones:
zone "localhost.localdomain" IN {
        type master;
        file "named.localhost";
        allow-update { none; };
};
zone "localhost" IN {
        type master;
        file "named.localhost";
        allow-update { none; };
};
zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" IN {
        type master;
        file "named.loopback";
        allow-update { none; };
};
zone "1.0.0.127.in-addr.arpa" IN {
        type master;
        file "named.loopback";
        allow-update { none; };
};
zone "0.in-addr.arpa" IN {
        type master;
        file "named.empty";
        allow-update { none; };
};

// 변환 해 줄 주소. 
// xxx.haedong.skk의 주소 정보. 즉, a.haedongg.skk haedong.haedongg.skk 등의 주소를 사용가능케 한다.
zone "haedong.skk" IN{
        type master;
// zone 파일 지정
        file "haedong.skk.zone";
        allow-update {none;};
        allow-transfer {none;};
};

zone 파일 설정

haedong@haedong:/home:]$ sudo vi /var/named/haedong.skk.zone
$TTL 1D
@       IN SOA  @ haedong.skk. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
        NS      @
        A       127.0.0.1
        AAAA    ::1
// haedong.haedong.skk 를 질의하면 172.17.0.11 을 반환한다.
haedong  IN      A       172.17.0.11
// hello.haedong.skk 를 질의하면 192.168.0.1을 반환한다.
hello    IN      A       192.168.0.1
// bye.haedong.skk 를 질의하면 www.haedongg.net을 반환한다. 
bye      IN      CNAME   www.haedongg.net

※ 위의 // 주석은 적용되지 않는다. //로 시작하는 줄은 모두 삭제한다.

vi /etc/named.rfc1912.zones 파일에 zone 정보를 기재하고 기재된 주소에 해당하는 zone 파일을 생성하고 정보를 위 양식대로 넣어주면 된다.
(호스팅 서비스 업체에서 제공하는 DNS나 등은 GUI등을 통해 설정 할 수 있다.)
생성한 zone 파일은 named 그룹이 소유권을 가지도록 설정해야 한다.

haedong@haedong:/home:]$ sudo chown -R :named /var/named/haedong.skk.zone

서비스 구동 및 확인

haedong@haedong:/home:]$ sudo service named restart
Redirecting to /bin/systemctl restart named.service
haedong@haedong:/home:]$ ps -ef | grep named
named    158850      1  0 15:17 ?        00:00:00 /usr/sbin/named -u named -c /etc/named.conf
root     158901 150715  0 15:18 pts/3    00:00:00 grep --color=auto named
haedong@haedong:/home:]$   nslookup haedong.haedong.skk
Server:         10.240.29.37
Address:        10.240.29.37#53

Name:   haedong.haedong.skk
Address: 172.17.0.11

named 는 UDP 53 포트로 서비스한다.
방화벽(firewalld / iptables)등에서 UDP53번 포트를 허용하지 않으면 서비스 되지 않는다.

Linux(CentOS7) 가상 네트워크 인터페이스 추가

NAT 구성 등을 위한 가상 인터페이스를 추가하는 방법을 설명알아보자.

인터페이스 정보 확인

[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.192.252  netmask 255.255.255.0  broadcast 192.168.192.255
        inet6 fe80::6d05:37d3:fb10:5b25  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:67:a4:a6  txqueuelen 1000  (Ethernet)
        RX packets 411  bytes 36267 (35.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 329  bytes 31013 (30.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 96  bytes 8376 (8.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 96  bytes 8376 (8.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

가상 인터페이스 생성
물리 인터페이스를 공유할 인터페이스 생성
ens33의 물리 NIC를 사용할 경우 ens33:0으로 생성한다.

[root@localhost ~]# cp /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/sysconfig/network-scripts/ifcfg-ens33:0              
[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33:0
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
# 인터페이스 명과 장치명이 겹치지 않도록 수정한다.
NAME=ens33:0
DEVICE=ens33:0
ONBOOT=yes

# 사용하고 싶은 IP로 변경한다.
IPADDR=192.168.192.253
PERFIX=24
GATEWAY=192.168.192.254

확인

[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.192.252  netmask 255.255.255.0  broadcast 192.168.192.255
        inet6 fe80::6d05:37d3:fb10:5b25  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:67:a4:a6  txqueuelen 1000  (Ethernet)
        RX packets 1046  bytes 93843 (91.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 703  bytes 78865 (77.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.192.253  netmask 255.255.255.0  broadcast 192.168.192.255
        ether 00:0c:29:67:a4:a6  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 104  bytes 9080 (8.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 104  bytes 9080 (8.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

인터페이스 정보를 확인하고 연결이 되는지 확인한다.

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\haedong> ssh haedong@192.168.192.253
The authenticity of host '192.168.192.253 (192.168.192.253)' can't be established.
ECDSA key fingerprint is SHA256:en-----------------------0s3gUedMt8.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

SSH 설정

개요

시큐어 셸(Secure SHellSSH)은 네트워크 상의 다른 컴퓨터에 로그인하거나 원격 시스템에서 명령을 실행하고 다른 시스템으로 파일을 복사할 수 있도록 해 주는 응용 프로그램 또는 그 프로토콜을 가리킨다. 기존의 rshrlogin텔넷 등을 대체하기 위해 설계되었으며, 강력한 인증 방법 및 안전하지 못한 네트워크에서 안전하게 통신을 할 수 있는 기능을 제공한다. 기본적으로는 22번 포트를 사용한다.

SSH는 암호화 기법을 사용하기 때문에, 통신이 노출된다고 하더라도 이해할 수 없는 암호화된 문자로 보인다.

SSL 그리고 HTTPS 의 암호화 통신방식을 이용한 쉘이다.
비대칭키 암호화 알고리즘으로 대칭키를 암호화 하여 주고받은 뒤 대칭키로 암호화 된 메시지를 주고 받는 프로토골이다.

대부분의 리눅스 시스템에 기본으로 포함되어있고, 설치된다.
ssh 서버에 접속하기 위한 클라이언트는 대부분의 linux 배포본에는 기본적으로 포함되어있고, Windows Powershell에도 포함되어있다.




사용법

linux shell / powershell 모두
ssh 계정명@hostname_또는_IP 명령으로 다른 호스트에 연결할 수 있다.
대개의 경우 Windows 에서는 putty 라는 공개 툴을 많이 사용한다.

[haedong@openstack2:~]$ssh
usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-E log_file] [-e escape_char]
           [-F configfile] [-I pkcs11] [-i identity_file]
           [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]
           [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]
           [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
           [user@]hostname [command]
 # 일반적인 연결방법
 # ssh account@server_HOSTNAME_or_server_IP
[haedong@openstack2:~]$ssh haedong@192.168.113.172
haedong@192.168.113.172's password:
Last login: Thu Dec 17 13:26:54 2020 from 192.168.4.199
[haedong@openstack2:~]$
 # 저장된 ssh key를 사용하는 경우
 # ssh account@server_HOSTNAME_or_server_IP -i KEY_FILE_NAME
[haedong@openstack2:~]$ssh root@192.168.113.171 -i ~/.ssh/id_rsa
Last login: Wed Dec 16 09:31:02 2020 from openstack3
[root@openstack1:~]#
 # 접속 로그 확인을 원할 경우
[haedong@openstack2:~]$ssh root@192.168.113.171 -i ~/.ssh/id_rsa -v
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 58: Applying options for *
debug1: Connecting to 192.168.113.171 [192.168.113.171] port 22.
debug1: Connection established.
debug1: key_load_public: No such file or directory
debug1: identity file /home/haedong/.ssh/id_rsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/haedong/.ssh/id_rsa-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.4
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.4
debug1: match: OpenSSH_7.4 pat OpenSSH* compat 0x04000000
debug1: Authenticating to 192.168.113.171:22 as 'root'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ecdsa-sha2-nistp256
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit                               > compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit                               > compression: none
debug1: kex: curve25519-sha256 need=64 dh_need=64
debug1: kex: curve25519-sha256 need=64 dh_need=64
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:mLoKmt/MNoY/Il1LahMDflXKfT/c                               KSpI80vbl2m5EFM
debug1: Host '192.168.113.171' is known and matches the ECDSA host key.
debug1: Found key in /etc/ssh/ssh_known_hosts:4
debug1: rekey after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey after 134217728 blocks
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<rsa-sha2-256,rsa-sha2-512>
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mi                               c,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure.  Minor code may provide more information
No Kerberos credentials available (default cache: KEYRING:persistent:1000)

debug1: Unspecified GSS failure.  Minor code may provide more information
No Kerberos credentials available (default cache: KEYRING:persistent:1000)

debug1: Next authentication method: publickey
debug1: Trying private key: /home/haedong/.ssh/id_rsa
debug1: Authentication succeeded (publickey).
Authenticated to 192.168.113.171 ([192.168.113.171]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LANG = ko_KR.UTF-8
Last login: Thu Dec 17 13:38:57 2020 from openstack2
[root@openstack1:~]#



sshd (SSH daemon : a.k.a ssh server) 설정

기본적으로 ssh 데몬의 설정파일은 /etc/ssh/sshd_config
ssh 클라이언트 설정 파일은 /etc/ssh/ssh_config
파일이다. 보통은 windows클라이언트에서 linux 서버로 접속을 하는 경우가 많다보니 ssh_config 파일을 수정하는경우는 많지 않(은것 같)다.

자주 사용하거나, 중요한 옵션만 기억하자.

 # ssh 서버 설정을 위한 값. 주석처리가 되어있는 경우 기본값으로 설정된다.
#Port 22
#ListenAddress 0.0.0.0


 # root로 로그인을 허용할 것인지 설정. no로 설정하고 sudo을 이용하는 것을 권장한다.
#PermitRootLogin yes
PermitRootLogin no

 # 로그인을 시도하는 계정/.ssh/authorized_keys 파일을 의미한다.
 # 허용할 공개키를 저장하는 파일을 가리킨다.
AuthorizedKeysFile      .ssh/authorized_keys

 # 빈 패스워드 로그인을 허용할 것인지 설정한다. 당연히 no로 설정하는 것이 '옳다'
PermitEmptyPasswords no

 # password를 이용한 로그인을 허용할 것인지 설정한다.
PasswordAuthentication yes

 # GSSAPI 사용 여부
 # 간혹 폐쇄망에서 접속 지연(ID 입력 후 지연)이 발생하년 경우 no로 변경
# GSSAPI options
GSSAPIAuthentication no
GSSAPICleanupCredentials no

 # 역시 폐쇄망 혹은 DNS 연결이 안되는 환경에서 접속 지연이 발생화면 no로 변경
UseDNS no

서비스 구동 / 재시작 / 종료

 # 서비스 구동
 # service sshd start
[haedong@openstack2:~]$ sudo systemctl start sshd.service

 # 서비스 재시작
 # service sshd restart
[haedong@openstack2:~]$ sudo systemctl restart sshd.service

 # 서비스 구동
 # service sshd stop
[haedong@openstack2:~]$ sudo systemctl stop sshd.service

사실 service sshd stop 또는 systemctl stop sshd.service 명령은 평생 내릴 일 없는 명령일지도 모른다.

ssh 키 쌍을 이용한 로그인 설정

SSL 그리고 HTTPS 포스트에서 설명한 공개키를 미리 서버에 저장해 두고 인증하는 방식이다.
이해를 위해 개념적인 절차를 기재해보면(실제 절차와는 차이가 있음)
1. 사용자가 비대칭 키 쌍 K1(공개키), K2(비밀키)를 생성.
2. 서버에 K1 을 저장
3. 사용자가 서버에 접속 시도
4. 서버는 대칭키 KS 생성
5. K1로 KS를 암호화하여 KK 생성
6. KK를 사용자에게 전달
7. 사용자는 KK를 K2를 복호화하여 KS 획득
8. KS를 KS로 암호화하여 SS 생성
9. 서버로 SS 전송
10. 서버는 KS로 SS를 복호화 하여 KS 획득.
11. 서버가 가지고 있는 KS와 사용자가 전송한 KS가 같은지 비교
가 되겠다.

보통은 보안상의 이유로 ssh key를 이용한 로그인을 강제하지만 반대로 편리한 것도 있다. 모든 서버의 키를 하나로 통일하고 passphrase를 비워두면 패스워드 입력 없이 모든 서버에 접속이 가능해 진다.(당연히 보안상 지양해야 하는 행위다)

서버에서 키를 생성하고 등록하는 과정은 다음과 같다.

 # 키를 등록할 서버에 로그인
[haedong@openstack3:~]$ssh-keygen
Generating public/private rsa key pair.
 # 키쌍이 저장될 경로 기본값은 /home/계정명/.ssh/
Enter file in which to save the key (/home/haedong/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): 비워두거나 최소5자 이상의 암호구
Enter same passphrase again: 비워두거나 최소5자 이상의 암호구
Your identification has been saved in /home/haedong/.ssh/id_rsa.
Your public key has been saved in /home/haedong/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+rZt72JUHSrIuqEeI07ey/5MQm1pYmFxFmBukuegj8s haedong@openstack3
The key's randomart image is:
+---[RSA 2048]----+
|    +.+.         |
|   + +        .  |
|  + *  . .   o . |
| . B o .o . o .  |
|.   = =.S  o     |
| o o +o.  .      |
|. + +.oo .       |
|.= +.*....+      |
|.Eoo*oo.o+.+o    |
+----[SHA256]-----+
[haedong@openstack3:~/.ssh]$ls -lah /home/haedong/.ssh/
합계 12K
drwx------. 2 haedong haedong   57 12월 17 14:33 .
drwx------. 3 haedong haedong   95 12월 16 09:30 ..
-rw-------. 1 haedong haedong 1.8K 12월 17 14:33 id_rsa
-rw-r--r--. 1 haedong haedong  400 12월 17 14:33 id_rsa.pub
-rw-r--r--. 1 haedong haedong  188 12월 16 09:30 known_hosts
[haedong@openstack3:~/.ssh]$ls -lah /home/haedong/
합계 16K
drwx------. 3 haedong haedong  95 12월 16 09:30 .
drwxr-xr-x. 3 root    root     21 12월 14 14:27 ..
-rw-------. 1 haedong haedong  31 12월 16 10:36 .bash_history
-rw-r--r--. 1 haedong haedong  18  4월  1  2020 .bash_logout
-rw-r--r--. 1 haedong haedong 193  4월  1  2020 .bash_profile
-rw-r--r--. 1 haedong haedong 231  4월  1  2020 .bashrc
drwx------. 2 haedong haedong  57 12월 17 14:33 .ssh
# 파일 권한ㅇ르 주목하자.
 # 공개키 등록
 # 다른 곳에서 만든 키를 넣어도 된다.
 # sshd_config 파일에 설정한 파일명과 일치해야 한다.
[haedong@openstack3:~/.ssh] cp ~/.ssh/id_rsa.pub    ~/.ssh/authorized_keys

 # 또는
[haedong@openstack3:~/.ssh] cat ~/.ssh/id_rsa.pub    >>  ~/.ssh/authorized_keys
 # >를 하나만 넣게 되면 authorized_key 파일의 내용을 모두 지운다음 id_rsa.pub의 내용이 들어가게 된다.
 # >>는 읽으려는 파일의 내용을 대상 파일의 맨 끝에 붙여넣는다.
 # .ssh 디렉토리는 700 
 # .ssh 디렉토리 아래 파일들은 600 권한이어야 한다.
 # 당연한 이야기지만 소유자는 해당 키를 사용할 계정이어야 한다.
[haedong@openstack3:~/.ssh]$chmod 600 ~/.ssh/*
[haedong@openstack3:~/.ssh]$ll ~/.ssh/
합계 16
-rw-------. 1 haedong haedong  400 12월 17 14:41 authorized_keys
-rw-------. 1 haedong haedong 1766 12월 17 14:33 id_rsa
-rw-------. 1 haedong haedong  400 12월 17 14:33 id_rsa.pub
-rw-------. 1 haedong haedong  188 12월 16 09:30 known_hosts

id_rsa 파일을 클라이언트에 저장한다.
다운로드 해도 되고, 내용을 복사한뒤 일반 텍스트 파일 형식으로 저장해도 된다.
앞서 설명한 것처럼 ” ssh account@hostname -i id_rsa ” 와 같이 키 파일을 지정해주면 된다.

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,C820352F5512D184F9C6887101DBE9F2

TFynB3AwsiFRoPUxJRg3Y9vv34lOsimQB3yNEyKMP2jvt5XbJFNT6Qw9BAD1xIkl
MfL27ADniRM73OgB+4E6OxzMgDXRE88Gor6CifWUZcASMPPOn55HrontgNE+fv7F
RL1TZ285IX73N/GDifAu9rchc3mIOL2i9D8t/TWUVMNjV+jL+jmSrWI70YlMArPE
I8qVUWc39SFn7NmQYuyo/7LBMNLdSBSMr4WpavM7WbbZAAcRZIYgT51gLWmgGEJv
LrCOcjdzHbSekxIp/8kejKj3ZbJZo6cwGsTKgT9RfLvamU38f21XeBp1bxXazuGF
jiqE9zZ4on69/nNzDRw9BKxuSbiO2rD4hwfSZyH0yJO0TUFaNPr2ejQ8uvbhVIxN
WNQ8+TNX84sm2Mjs8USN8UkAq9uzCLCBeKXJVbmrQAyGvIaU4Y8p9hXjwDgg4oKv
ohiW1VtoqMEigpgpRo2xF6Ft3E6O6yuuh48QauFVNwen2FPGLmRrx2ZkD5htBjjM
mgaZv/E2wP21EmEf6/3tmMOyR4mVxnn1Am4O6zMnOjCtA4OZxv2a2jWBSIZl7/SB
8Zu6yDaHycv0SLKBMtwm3cTXYwpD4StDgX7XBUv0tpyfYh/okT/YRVCx+HP723L+
FLSuwMs9bnvYvLqRbF2GBPJSUQSG1REyoxL//gSqBTdiUSYb2275vAVxYg72Oh28
MgH4tAGhTlk6rxp5ZMflFF0GeMQAoTqjfcs1n+LjFztLZY/L/nZfk6jQEZIbDyEA
IYrZ9zL4XQhsILI0RjCpYei//8rMtf3+w2QiyOFyIcKH0PDRDJegQyFUs5CWiOIX
0j+5ZOMr1igNHbotCR8JhGsPnm2XWx0rs5+nY/Y198Re9waebE7zCKHRjC2jbRnK
mM14mngyIVsaKkKlJz1OMkN1rEnHd6Hu0t52JRTDxI+DWed+ZbUsxpUsmPq9Y68l
jH7R7b5g0emb0sqcyMvjYOEbWD9hk7VBFuKL5CnLGraW4Ag+FcZSGg0DM5nL+Iwr
OHKslt6xFMHVRr7aSJxslw9zGGUb2LG0lBEp+SKLquCFevcv2rQp0Vzprb5UAzum
pVE/TYKXXVjeQA+rQlqefDY43HjJxWA+Oai8dLUNVMt/LuSge5D9mmwK3Nkkj98d
eVDZp1AKBw1vjom1w0LS4J9kKk8FJmUPjb/nb1nbkGYMc+QGQZGvOVYOmfb3bjbI
8M8EUHTs6Sg3WVPEALWZU99yqvemeVx1/A/gf3cqP/kuEYphFN7zRchMV9lXNs7m
pE1DtAYLcAEaLK5MZDgQ6Oo9jCVLlleiYXj3kBCijJ2zK0iXh08PsiggAoaYvlgk
l21oXTS1tPl1Cpe3QaIb98LMdTPZk+Qkbq4N+9YPQbRwBgiDF2ApXJQhSTdKmVES
B9E3mYCf5OqtiYw/V9xOKA7RB/RR2vCGxXAa1pem5ntzqPLYhBLaUZ2CShOOUPFh
/oL1exNCATeOgpSLypx0ZoHqU+TJLI9IhD15HlA6IAcZmyBp+jVMayTNYjvAmWgT
br8tBxaGuTyIVO00auUJQeud84Lq85pS0mGQMM7fORHsk9B4PuZT2zjkIpiGay30
-----END RSA PRIVATE KEY-----

putty 클라이언트를 사용하는 경우

puttygen 을 실행한 다음 아래 절차를 따라 키 포맷을 변경하고 putty에서 로드하면 된다.