Rest Api 만들기 위해 정리 했던 것이다.


워드로 작성했던거 복사붙여넣기 함.



STANDARD SUECCSS

200 (“OK”)

일반적인 요청 성공을 나타내는 데 사용해야 한다.

200은 클라이언트가 요청한 어떤 액션이었뜬지 REST API가 성공적으로 수행했음을 나타내는 코드로, 클라이언트는 이 코드를 받길 원한다. 또한 더 이상의 할당된 ‘2xx’ 계열의 응답코드가 없다는 뜻이기도 하다. 204 상태 코드와는 달리 200코드는 응답 바디가 포함된다.

 

 

 

201(‘Created’)

성공적으로 리소스를 생성했을 때 사용한다.

새로운 리소스를 이용하여 컬렉션에 생성했거나 스토어에 추가했을 때 201 상태 코드로 응답한다. 컨트롤러의 행동으로 새로운 리소스가 생겨났을 경우에도 201 상태 코드로 응답한다. POST 시 거의 대부분 201 코드가 사용된다고 생각하면 된다.

 

 

 

202(“Accepted”)

비동기 처리가 성공적으로 시작되었음을 알릴 때 사용해야 한다.

202 응답은 클라이언트의 요청이 비동기적으로 처리될 것임을 나타낸다. 이 응답상태 코드는 유효한 요청이었지만, 최종적으로 처리되기 까지는 문제가 생길 수도 있다는 것을 클라이언트에게 알려준다. 보툥 202 응답은 처리 시간이 오래 걸리는 액션에 사용된다.

 

 

204(“No Content”)

응답 바디에 의도적으로 아무것도 포함하지 않을 때 사용한다.

204 상태 코드는 보통 PUT, POST, DELETE 요청에 대한 응답으로 이용하는데, REST API가 응답 메시지의 바디에 어떠한 상태 메시지나 표현을 포함해서 보내지 않을 때 사용한다. APIGET 요청에 204로 응답할 수 있는데, 요청된 리소스는 존재하나 바디에 포함시킬 어떠한 상태 표현도 가지고 있지 않다는 것을 나타낸다.

 

 

 

 

 

 

STANDARD ERROR RESPONSES

오류 응답시에는 응답 바디를 포함한다.

ERROR RESPONSE BODY

에러 시 형태

{

 "error": {

  "errors": [

   {

    "domain": "global",

    "reason": "notFound",

    "message": "Not Found"

   }

  ],

  "code": 404,

  "message": "Not Found"

 }

}

 

 

ERRORS

 

301 (“Moved Permanently”)

 리소스를 이동시켰을 때 사용한다. REST API 리소스 모델이 상당 부분 재설계되었거나 계속 사용할 새로운 URI를 클라이언트가 요청한 리소스에 할당하였다는 것을 나타낸다. REST API는 응답의 Location 헤더에 새로운 URI를 기술해야 한다.

Error Code

Description

movedPermanently

리소스를 이동시켰을 때 사용한다. REST API 리소스 모델이 상당 부분 재설계되었거나 계속 사용할 새로운 URI를 클라이언트가 요청한 리소스에 할당하였다는 것을 나타낸다. REST API는 응답의 Location 헤더에 새로운 URI를 기술해야 한다.

 

 

303 (“See Other”)

다른 URI를 참조하라고 알려줄 때 사용한다. 303응답은 처리가 끝난 컨트롤러 리소스가 잠재적으로 원하지 않는 응답 바디를 보내는 대신, 응답 리소스의 URI를 보냈음을 나타낸다. 이것은 임시 상태 메시지의 URI일 수도 있고, 이미 존재하는 영구적인 리소스의 URI일 수도 있다.

303 상태 코드는 일반적으로 REST API가 클라이언트에 상태 다운로드를 강요하지 않으면서 참조 리소스를 보내는 것을 허용한다. 대신 클라이언트는 응답 Location 헤더에 있는 값으로 GET 요청을 보낼 수 있다.

Error Code

Description

seeOther          

요청은 성공적으로 처리되었다. 응답을 얻기 위해서는 Location 헤더에 지정된 URLGET 요청을 보내라.

mediaDownloadRedirect

요청은 성공적으로 처리되었다. 응답을 얻기 위해서는 Location 헤더에 지정된 URLGET 요청을 보내라.

 

 

304 (“Not Modified”)

대역폭을 절약할 때 사용한다.

이 상태 코드는 응답 바디에 아무것도 없어야 한다는 측면에서 204 (“No Content”)와 유사하다. 주요 차이점은 204는 바디에 보낼 내용이 없을 때 사용하는 반면, 304는 리소스에 대한 상태 정보가 있긴 하지만 클라이언트에 이미 해당 상태의 최신 버전이 있다는 걸 의미할 때 사용한다.

Error Code

Description

notModified       

If-None-Match 헤더에 설정된 조건이 충족 되지 않았다.

If-None-Match 의 값과 서버의 값이 달라야 요청에 대한 데이터를 보내준다.

304 응답 발생시 클라이언트는 자신의 캐시에 있는 데이터를 그냥 사용하면 된다.

 

 

307 (“Temporary Redirect”)

클라이언트가 다른 URI로 요청을 다시 보내게 할 때 사용해야 한다. 307 응답은 REST API 가 클라이언트의 요청을 처리하지 않을 것임을 나타낸다. 클라이언트는 응답 메시지의 Location 헤더에 지정된 URI로 요청을 다시 보내야한다.

Error Code

Description

temporaryRedirect

요청을 Location 헤더에 지정된 URL로 다시 보내라.

 

 

400 (“Bad Request”)

일반적인 요청 실패에 사용해야 한다. 기본적으로 다른 4xx 응답들과 매칭되는게 없는 REST API 고유의 에러 정보를 응답 바디에 포함하여 더 자세하게 에러 정보를 표시할 수 있다.

Error Code

Description

                     

 

 

 

 

 

 

 

 

401 (“Unauthorized”)

클라이언트 인증에 문제가 있을 때 사용해야 한다.

401 오류 응답은 클라이언트가 적절한 인증 없이 보호된 리소스를 사용하려고 할 때 발생한다. 인증을 잘못하거나 아예 인증하지 못할 경우 발생한다.

Error Code

Description

unauthorized      

해당 사용자는 해당 요청에 대한 인증된 사용자가 아니다.

authError

요청에 제공된 인증 자격 증명이 유효하지 않습니다. 인증 HTTP 요청 헤더의 값을 확인하십시오.

expired

세션이 만료되었다. Authorization HTTP 요청 헤더 값을 확인하라.

lockedDomainExpired

이전에 유효한 고정 도메인이 만료 되었기 때문에 요청이 실패했다.

required

사용자는 이 API 요청을 하려면 로그인을 해야한다. 인증 HTTP 요청 헤더 값을 확인해라.

 

 

 

402 (“PAYMENT_REQUIRED”)

요금에 대한 오류 반환이다.

Error Code

Description

dailyLimitExceeded402

일일 사용 요금 한도를 초과했다.

quotaExceeded402

요청한 작업 할당량이 허용하는 것보다 더 많은 자원을 필요로한다. 즉 금액이 모자란다.

user402

요청한 작업은 인증된 사용자의 지불 방식을 필요로한다.

 

 

 

 

403 (“Forbidden”)

인증 상태에 상관없이 액세스를 금지할 때 사용해야 한다.

403 오류 응답은 클라이언트의 요청은 정상이지만, REST API가 요청에 응하지 않는 경우를 나타낸다403 응답은 인증에 문제가 있어서가 아니다. 만약 인증에 문제가 있다면 401를 사용해라. REST API에서 어플리케이션 수준의 접근 권한을 적용하고자 할 때 403을 사용한다. 예를 들어 클라이언트는 REST API 리소스의 전체가 아니라 일부에 대한 접근만 허가된 경우가 있다. 클라이언트가 허용된 범위 외의 리소스에 접근하려고 할 때 REST API403으로 응답해야 한다.

Error Code

Description

forbidden

요청이 금지되어 완료되지 못했다.

accessNotConfigured

해당 프로젝트가 이 API 호출에 접근권한이 없다.

accessNotConfigured

해당 프로젝트가 블록당했다.

accountDeleted

요청에 대한 인증 자격 증명과 관련된 사용자 계정이 삭제되었다.

accountDisabled

요청에 대한 인증 자격증명과 관련된 사용자 계정이 사용불가상태이다.

accountUnverified

요청을 하는 사용자의 이메일 혹은 id가 확인 되지 않았다. 혹은 인증이 확인되지 않았다.

concurrentLimitExceeded

동시 사용 한계 때문에 금지 되었다.

dailyLimitExceeded

API의 일일 할당량 제한에 도달했다.

dailyLimitExceeded

일일 할당량 제한에 도달 하고 있으며 이 사용자는 차단되었다.

dailyLimitExceededUnreg

인증되지 않은 API 사용을 위한 일일 한도를 초과했기 때문에 실패했다.

downloadServiceForbidden

API는 다운로드를 지원하지 않는다.

insufficientAudience

요청 이 시청자에 대해 완료 될 수 없다.

insufficientAuthorizedParty

요청은 어플리케이션에 대해 완료 할 수 없다.

insufficientPermissions

인증된 사용자이지만 이 요청을 실행 할 수 있는 권한은 없다.

limitExceeded

요청은 액세스 또는 속도 제한으로 인해 완료되지 않을 수 있다.

lockedDomainForbidden

API는 락된 도메인을 지원하지 않는다.

quotaExceeded

요청한 작업 할당량이 허용하는 것보다 더 많은 자원을 필요로 한다.

rateLimitExceeded

너무 많은 요청을 주어진 범위내에서 보냈다.

rateLimitExceededUnreg

속도 제한이 초과되었다. API 호출을 계속 할 수 있도록 조치를 취해야한다.

responseTooLarge

요청된 리소스가 반환하기에 너무 크다.

servingLimitExceeded

API 에 지정된 전체 속도 제한은 이미 도달했다.

sslRequired

해당 작업은 SSL을 써야한다.

unknownAuth

API 서버는 요청에 사용되는 인증 방식을 인식하지 못한다. Authorization HTTP 요청헤더를 확인해라.

userRateLimitExceeded

사용자 별 속도 제한에 도달했기 때문에 요청이 실패

userRateLimitExceededUnreg

사용자 별 속도 제한에 도달했고 이 클라이언트는 식별되지 않았다.

variableTermExpiredDailyExceeded

변수가 만료되었고 일일 한계량을 초과했다.

variableTermLimitExceeded

변수의 할당 제한에 도달했기 때문에 요청이 실패했다.

 

 

404 (“Not Found”)

요청 URI에 해당하는 리소스가 없을 때 사용한다.

404 오류 상태 코드는 말그대로 클라이언트가 요청한 URI에 해당하는 리소스가 존재하지 않을 때 사용한다.

Error Code

Description

notFound

요청과 관련된 리소스가 존재하지 않는다.

notFound

요청과 관련된 리소스를 찾을 수 없다.

unsupportedProtocol

요청에 사용된 프로토콜은 지원하지 않는다.

 

 

405 (“Method Not Allowed”)

HTTP 메서드가 지원되지 않을 때 사용해야 한다.

클라이언트가 허용되지 않는 HTTP 메서드를 사용하려 할 때, API405 오류 응답을 한다. 읽기 전용 리소스는 GET 메소드와 HEAD 메서드만 지원하며, 컨트롤러 리소스는 PUT 메서드와 DELETE메서드를 제외한 GET 메서드와 POST 메서드만 허용할 것이다.

405 응답에는 Allow 헤더가 포함되어야 하며, 그 값으로 리소스가 지원하는 HTTP 메서드를 다음 예와 같이 나타내야 한다.

Allow : GET, POST

 

Error Code

Description

httpMethodNotAllowed

이 리소스에 대한 HTTP 메소드는 지원하지 않는다.

 

 

406 (“Not Acceptable”)

요청된 리소스 미디어 타입을 제공하지 못 할 때 사용해야 한다.

406 오류 응답은 클라이언트의 Accept 요청 헤더에 있는 미디어 타입중 해당하는 것을 만들지 못할 때 발생한다. 예를 들어, APIjson(application/json) 데이터 포맷만 지원한다면 xml(application/xml) 포맷 데이터를 요청한 클라이언트는 406 응답을 받는다.

Error Code

Description

notAcceptable

해당 미디어 타입은 제공하지 않는다.

 

 

409 (“Conflict”)

리소스 상태에 위반되는 행위를 했을 때 사용해야 한다.

409 오류 응답은 클라이언트 요청에 의해 REST API 리소스가 불가능 또는 모순 상태가 될 수 있는 경우에 사용한다. 예를 들어 클라이언트가 비어 있지 않은 리소스를 삭제하라고 요청하면, REST API에서 이 응답 오류를 보낸다.

Error Code

Description

conflict

요청된 작업이 기존 항목과 충돌하기 때문에 API 요청을 완료 할 수 없다. 중복 항목에 대한 오류는 일반적인 상황보다 좀더 구체적으로 표현한다.

duplicate

이미 존재하는 리소스를 생성하라고 했을 때 발생한다.

 

 

 

410 (“Gone”)

존재 하지 않는 리소스에 대한 삭제 요청 시 사용해야 한다.

Error Code

Description

deleted

삭제 요청한 리소스가 이미 존재 하지 않는다.

 

 

412 (“Precondition Failed”)

조건부 연산을 지원할 때 사용한다.

412 오류 응답은 특정한 조건이 만족될 때만 요청이 수행되도록 REST API로 알려준다. 클라이언트가 요청 헤더에 하나 이상의 전제 조건(If-Match , If-None_match )을 지정할 경우 발생하며, 이러한 조건이 만족되지 않으면 412응답은 요청을 수행하는 대신에 이 상태 코드를 보낸다.

Error Code

Description

conditionNotMet

요청에 If-Match If-None-Match HTTP 헤더의 조건이 충족되지 않았다.

 

 

 

413 (“Request_entity_too_large”)

413 오류 응답은 요청의 크기가 너무 클 때 사용한다.

Error Code

Description

backendRequestTooLarge

요청이 너무 크다.

batchSizeTooLarge

요청에 너무 많은 요소가 포함되어 있다.

uploadTooLarge

요청에 포함된 데이터의 크기가 너무 커서 요청이 실패했다.

 

 

 

415 (“Unsupported Media Type”)

요청의 페이로드에 있는 미디어 타입이 처리되지 못했을 때 사용해야 한다.

415 오류 응답은 요청 헤더의 Content-Type에 기술한 클라이언트가 제공한 미디어 타입을 처리하지 못할 때 발생한다. 예를 들어 API json(application/json)으로 포맷된 데이터만 처리할 수 있을 때, 클라이언트가 xml(application/xml)로 포맷된 데이터로 요청하면 415응답을 받는다.

 

Error Code

Description

unsupportedMediaType

요청에 포함된 미디어 타입을 처리하지 못한다.

 

 

416 (“Requested Range Not Satisfiable”)

요청이 만족될 수 없는 범위를 지정할 때 사용한다.

Error Code

Description

requestedRangeNotSatisfiable

요청이 만족될 수 없는 범위를 지정할 때 사용한다.

 

 

 

417 (“Expectation Failed”)

클라이언트의 기대가 서버에 의해 만족 될 수 없을 때 사용한다.

Error Code

Description

expectationFailed

클라이언트의 기대가 서버에 의해 만족 될 수 없다.

 

 

 

428 (“Precondition Required”)

해당 요청이 전제 조건이 꼭 필요 할 때 사용한다. 이 요청이 성공하려면 If-MatchIf-None-Match 헤더가 요청에 포함되어야 한다.

Error Code

Description

preconditionRequired

해당 요청이 전제 조건이 꼭 필요 할 때 사용한다. 이 요청이 성공하려면 If-Match If-None-Match 헤더가 요청에 포함되어야 한다.

 

 

 

429 (“Too Many Requests”)

너무 많은 요청이 같은 시간에 발생 했을 경우 사용한다.

Error Code

Description

rateLimitExceeded

너무 많은 요청이 주어진 시간 범위 내에서 보냈다.

 

 

 

500 (“Internal Server Error”)

API가 잘못 작동할 때 사용해야 한다.

500 오류 응답은 일반적인 REST API오류 응답이다. 웹 프레임워크는 대부분 예외 사항을 발생시키는 요청 핸들러 코드가 실행 될 경우 자동적으로 이 응답 코드를 발생시킨다. 500 오류는 클라이언트의 잘못으로 발생한 것이 아니기 때문에 클라이언트가 이 응답을 발생시킨 것과 동일한 요청을 다시 시도하면 다른 응답을 받을 수도 있다.

Error Code

Description

internalError

요청이 내부 오류로 인해 실패했다.

 

 

 

501 (“Not Implemented”)

REST API 가 아직 구현되지 않았을 때 이 응답을 사용한다. 설계에서부터 없던 API가 아닌 지원할 것이지만 아직 구현하지 않았을 때 사용한다.

Error Code

Description

notImplemented

해당 요청에 대한 명령은 아직 구현하지 않았다.

unsupportedMethod

요청이 알려지지 않은 메소드나 명령을 실행하려 했기 때문에 실패했다.

 

 

 

503 (“Service Unavailable”)

RESTFUL 서버가 점검중이거나 장애발생시 서비스에 연결 되지 않을 때 사용한다.

Error Code

Description

backendError

백엔드 오류가 발생했다.

backendNotConnected

요청이 연결오류로 실패했다.

notReady

API 서버가 아직 준비되지 않았다.

 



Rest api 만들며 보기 편하게 정리 했던 것.

실제로 사용하는 것은 몇개 없네요. 


CODE

Description

1XX 조건부 응답

 

100 (계속)

요청자는 요청을 계속해야한다. 서버는 이 코드를 제공하여 요청의 첫 번째 부분을 받았으며 나머지를 기다리고 있음을 나타낸다.

101 (프로토콜 전화)

요청자가 서버에 프로토콜 전환을 요청했으며 서버는 이를 승인하는 중이다.

 

 

2XX 성공

 

200 (성공)

서버가 요청을 제대로 처리했다는 뜻이다. 이는 주로 서버가 요청한 페이지를 제공했다는 의미로 쓰인다.

201 (작성됨)

성공적으로 요청되었으며 서버가 새 리소스를 작성했다.

202 (허용됨)

서버가 요청을 접수했지만 아직 처리하지 않았다.

203 (신뢰할 수 없는 정보)

서버가 요청을 성공적으로 처리했지만 다른 소스에서 수신된 정보를 제공하고 있다.

204 (컨텐츠 없음)

서버가 요청을 성공적으로 처리했지만 컨텐츠를 제공하지 않는다.

205 (컨텐츠 재설정)

서버가 요청을 성공적으로 처리했지만 컨텐츠를 표시하지 않는다. 204응답과 달리 이 응답은 용청자가 문서보기를 재설정할 것을 요구한다. ( : 새 입력을 위한 양식 비우기)

206 (일부 컨텐츠)

서버가 GET 요청의 일부만 성공적으로 처리했다.

207 (다중 상태)

 

208 (이미 보고됨)

 

226 IM Used

 

 

 

3XX 리다이렉션 완료

클라이턴트 요청을 마치기 위해 추가 동작을 취해야 한다.

300 (여러 선택항목)

서버가 요청에 따라 여러 조치를 선택할 수 있다. 서버가 사용자 에이전트에 따라 수행할 작업을 선택하거나, 요청자가 선택할 수 있는 작업 목록을 제공한다.

301 (영구 이동)

요청한 페이지를 새 위치로 영구적으로 이동했다. GET 또는 HAED 요청에 대한 응답으로 이 응답을 표시하면 요청자가 자동으로 새 위치로 전달된다.

302 (임시 이동)

현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.

303 (기타 위치 보기)

요청자가 다른 위치에 별도의 GET 요청을 하여 응답을 검색할 경우 서버는 이 코드를 표시한다. HAED 요청 이외의 모든 요청을 다른 위치로 자동으로 전달한다.

304 (수정되지 않음)

마지막 요청 이후 요청한 페이지는 수정되지 않았다. 서버가 이 응답을 표시하면 페이지의 컨텐츠를 표시하지 않는다. 요청자가 마지막으로 페이지를 요청한 후 페이지가 변경되지 않으면 이 응답(if-Moified-Since HTTP 헤더라고함)을 표시 하도록 서버를 구성해야 한다.

305 (프록시 사용)

요청자는 프록시를 사용하여 요청한 페이지만 액세스할 수 있다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 하다.

307 (임시 리다이렉션)

현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.

308 (영구 리다이렉션)

 

 

 

4XX 요청 오류

 

400 (잘못된 요청)

서버가 요청의 구문을 인식하지 못했다.

401 (권한 없음)

이 요청은 인증이 필요하다. 서버는 로그인이 필요한 페이지에 대해 이 요청을 제공할 수 있다.

403 (금지됨)

서버가 요청을 거부하고 있다.

404 (찾을 수 없음)

서버가 요청한 페이지를 찾을 수 없다. 예를 들어 서버에 존재하지 않는 페이지에 대한 요청이 있을 경우 서버는 이 코드를 제공한다.

405 (허용되지 않는 방법)

요청에 지정된 방법을 사용할 수 없다.

406 (허용되지 않음)

요청한 페이지가 요청한 컨텐츠 특성으로 응답할 수 없다.

407 (프록시 인증 필요)

이 상태 코드는 401(권한 없음)과 비슷하지만 요청자가 프록시를 사용하여 인증해야한다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 한다.

408 (요청 시간초과)

서버의 요청 대기가 시간을 초과하였다.

409 (충돌)

서버가 요청을 수행하는 중에 충돌이 발생했다. 서버는 응답할 때 총돌에 대한 정보를 포함해야 한다. 서버는 PUT 요청과 충돌하는 PUT 요청에 대한 응답으로 이 코드를 요청 간 차이점 목록과 함께 표시해야 한다.

410 (사라짐)

서버는 요청한 리소스가 영구적으로 삭제되었을 때 이 응답을 표시한다. 404(찾을 수 없음) 코드와 비슷하며 이전에 있었찌만 더 이상 존재하지 않는 리소스에 대해 404 대신 사용하기도 한다. 리소스가 영구적으로 이동된 경우 301을 사용하여 리소르의 새 위치를 지정해야 한다.

411 (길이 필요)

서버는 유효한 컨텐츠 길이 헤더 입력란 없이는 요청을 수락하지 않는다.

412 (사전조건 실패)

서버가 요청자가 요청 시 부과한 사전조건을 만족하지 않는다.

413 (요청 속성이 너무 큼)

요청이 너무 커서 서버가 처리할 수 없다.

414 (요청 URI가 너무 김)

요청 URI(일반적으로 URL)가 너무 길어 서버가 처리할 수 없다.

415 (지원되지 않는 미디어 유형)

요청이 요청한 페이지에서 지원하지 않는 형식으로 되어 있다.

416 (처리할 수 없는 요청범위)

요청이 페이지에서 처리할 수 없는 범위에 해당된느 경우 서버는 이 상태 코드를 표시한다.

417 (예상 실패)

서버는 Expect 요청 헤더 입력란의 요구사항을 만족할 수없다.

418 (I’m a teapot)

 

420 (Enhance Your Calm)

 

422 (처리할 수 없는 엔티티, WebDAV)

 

423 (잠김, WebDAV)

 

424 (실패된 의존성)

 

425 (정렬되지 않은 컬렉션, 인터넷 초안)

 

426 (업그레이드 전용)

 

428 (전제조건 필요)

 

429 (너무 많은 요청)

 

431 (요청 헤더 필드가 너무 큼)

 

444 (응답 없음)

 

449 (다시 시도, 마이크로소프트)

 

450 (윈도 자녀 보호에 의해 차단됨, 마이크로소프트)

 

451 (법적인 이유로 이용 불가)

 

494 (요청 헤더가 너무 큼)

 

495 (Cert 오류)

 

496 (Cert 없음)

 

497 (HTTP to HTTPS)

 

499 (클라이언트가 요청을 닫음)

 




동영상 강좌보고 2년전에 정리했던 자료인데 노트를 이제야 발견했다...




Class Diagram

개요

- 시스템의 논리적인 구조(클래스)를 표현한다.

- 객체지향 개발에서 가장 공통적으로 많이 사용된다.

- class diagram : 시스탬 정적 설계도

- Active Class Diagram : 시스템의 프로세스도


특징

- 시스템의 요구사항에 표현된 작업에 대한 책임을 분할한다.

- 모델은 점점 증가되므로 관련된 클래스들끼리 패키지화 한다.

- 클래스를 너무 작게 쪼개거나 기능을 너무 많이 포함하면 복잡해지므로 적절히 구현해야 한다.



Class

- 객체의 속성(Attribute)와 행동(Operation)을 포함한다.

- 모든 Class는 유일한 이름을 갖는다.

- 단순명(Simple Name) : class 이름만 표현한다.

- 경로명(Path Name) : class 의 패키지명(namespace)를 포함하여 표현한다.


왼쪽이 단순명이고 오른쪽이 경로를 포함한 이름이다.


경로명의 경우 언어에 따라 표현을 달리하면 된다.

예를 들어

java : java.lang.String

c++ : std::String

c# : System.String



추상클래스의 경우 클래스명을 이텔릭체로 표기하면 된다.




속성(Attribute)

- 의미있는 명사형으로 표현

- 문법


 <<stereotype>>

visibility

name 

: 

type 

[multiplicity]

value  

 

 접근제

속성명 

 

속성타입 

배열 개수 

 

본값




행동(Operation, method)

- 의미있는 동사형 표현

- class 가 행할 수 있는 동작을 기술한다.

- 문법


 <<stereotype>>

 visibility

name 

( param1 : type [multiplictiy] = value, param2... )

returntype 

 

 접근제어

행동 

인자( 위의 속성과 비슷하다.) 

 

반환 타입 


- 추상 행동(메소드)의 경우는 이텔릭체로 표현한다.



속성, 행동 공통 사항

- static(정적) 속성(attribute)는 밑줄로 표현한다.


- 접근제어 표현법


visibility(접근제어)

+

public 

private 

protection 

package 


- stereotype : "<< contents >>" 이런식으로 표현한다. 

새로운 어휘를 표현하는 방법이다. UML의 모델요소는 한정되기 때문에 추가적인 의미, 목적, 프로그래밍 언어에 따른 UML에서 표현 못하는 요소를 추가할수 있다.





Class 표현 예1


Class 표현 예2



class 표현 예3





추가적으로 Exception을 던지는 행동(메소드)의 경우는 throw Exception과 같은 표현을 통해 던지는 예외를 표현할 수 있다.





stereotype의 경우는 위의 예처럼 UML에서 지원하지 않는 signal이나 exception 혹은 추가적인 표현을 할 때 유용하다.



Nested Class(중첩 클래스)

- 클래스내부에 선언된 또다른 클래스를 말한다.


inner class 는 outer class 내부에 존재하므로 namespace까지 표현한 경로명으로 outer.inner이다.




Active Class

- 독자적인 제어흐름을 갖고 프로그램의 실행을 주도하는 클래스이다.(예를 들어 Main Class, Thread class)

- 반대의 클래스를 Passive Class라고 한다.

- Thread를 소유하거나 주소 공간을 소유한다.

- 프로그램 실행 혹은 코드 실행시 이를 시작하거나 흐름을 제어 할 수 있다.

- 변수를 조작하거나 프로그램의 행동을 변화시킬 수 있다.



기본 클래스 형태에 왼쪽,오른쪽 양 옆에 | | 로 표현한다.




Interface(인터페이스)

- Class 또는 Component 가 외부에 제공하는 기능(행동, 메소드)만을 목록화 한 것이다.

- Interface는 구조와 구현을 갖지 않는다.( 실제 동작하지 않는다. 이런 동작을 있다는 것을 알려줄 뿐이다.)

- Interface는 속성을 갖지 않고 구현된 동작(메소드)도 갖지 않는다.

- 오직 어떤 기능을 수행할 수 있다고 하는 기능 목록만 제공한다.

- 이 기능의 실제 구현은 ㅏㅎ위클래스에서 구현해야한다.


인터페이스는 속성을 갖지 않고 구현된 행동이 없이 행동이 선언만 된 추상클래스(abstract class)이다.



위의 Test란 변수는 상수를 표현한 것이다. interface는 변수는 갖지 못하지만 상수값(변수가 아니기 때문에)은 가질수 있다.


- interface 는 원형으로 표현하되 클래스로 표현도 가능하다. 클래스로 표현시 stereotype 인 <<Interface>>를 추가하여 해당 클래스가 interface라는 것을 알려주어야 한다.


interface 표현을 원형으로 하고 이런식으로 표현도 가능하다.



 




Relation Ship

개요

- 모델 요소간의 논리적 또는 물리적인 연결을 표현한다.

- 여러 객체간 관계를 의미한다.


종류

- Dependency (의존)

- Association (연관)

   - Aggregation (집합 연관)

   - Composition (복합 연관)

-  Generalization (일반화)

- Realization (실체화)




1. Dependency Relationship (의존관계)

- 한 클래스의 변화가 이것을 사용하는 다른 클래스에 영향을 미치는 관계(역은 성립하지 않는다.)

- using(사용) 관계를 나타낸다.

- 구현시 의존 클래스를 사용하는 클래스는 이를 찹조하고 있는 인스턴스 변수를 유지하지 않는다.(의존 클래스를 잠시 사용할 뿐이다.)

- 표현은 점선에 화살표이다. --------->


적용 예시

- 한 클래스의 메소드가 다른 클래스를 인자로 받아 메소드내에서 사용

- 한 클래스의 메소드 내에서 다른 클래스를 생성하고 생성된 클래스의 메소드를 사용한다.( 메소드 내에서만 사용하고 메소드 반환시 의존 클래스 인스턴스도 함께 사라진다. -> 즉 로컬변수로만 사용 )

- 한 클래스가 의존 클래스의 객체를 반환 ( 의존 클래스를 생성 반환만 한다. 인스턴스를 유지하지 않는다.)

- 의존 클래스의 정적 메소드 사용

- 중요) 즉 의존 클래스의 인스턴스 변수를 유지하지 않는다.



예를 들어 요리사는 요리도구에 의존한다. 요리도구가 바뀌면 요리방법도 바뀐다. 또는 세금의 경우 세금법에 의존한다. 세금법이 바뀌면 세금 계산 방법도 달라진다.






2. Generalization (일반화 관계)

- 여러 클래스가 가진 공통적인 특징을 추출하여 공통적인 클래스로 일반화시키는 것을 의미한다.

- 'is a' 관계 (예를 들어 인간은 동물이다.)

- 객체 지향 언어에서의 상속관계

  = 자식은 부모의 속성과 행동을 공유한다.

  = 자식은 부모가 갖지 않는 속성과 행동을 추가할 수 있다.

  = 부모가 사용되는 곳은 어떤 자식으로든 대체 가능하다. 역은 성립하지 않는다.


## 자세한 상속관계에 대한 지식은 객체지향언어의 상속편을 보아라. 



객체지향언어에서는 animal을 부모클래스, dog, cat, human을 자식클래스라고 한다.

자식 클래스는 부모클래스의 모든 속성과 행동을 상속한다.

위의 그림을 보면

- 개, 고양이, 인간의 공통적인 속성,행동인 나이, 숨쉬다 등의 공통적인 부분으로 동물이란 클래스로 일반화했다.

- 인간의 경우 동물이란 공통직인 것에 "자동차를 운전한다."라는 행동이 추가 될 수 있다. 이를 특수화라고 한다.

- 동물의 공통적인 행동인 숨쉬다라는 행동을 개, 고양이, 인간 어떤 것으로도 대체해도 숨쉬다라는 행위를 할 수 있지만 인간의 행동중 하나인 "자동차를 운전한다"는 인간외 다른 동물로 대체 불가능하다.( 부모가 사용되는 곳은 어떤 자식으로든 대체가능, 그러나 역은 불가능)





3. Association ( 연관 관계 )

- 클래스로부터 생성된 인스턴스들 간의 관계를 표현한다.

  = 인스턴스란 클래스를 실제로 사용할 수 있는 하나의 개체로 만드는 것이다.

  = 프로그래밍 언어에서는 new 연산자를 이용하여 클래스에 메모리를 할당하고 프로그램내에서 사용할 수 있는 형태로 만드는 작업이다.

- Dependyncy와 Generalization 관계는 단순히 클래스들간의 관계를 나타낸다. 이 관계들은 인스턴스를 만들고 인스턴스에 대한 참조를 유지하지 않는다는 것이 특징이다.

- Association 관계는 Classifier 로부터 생성된 인스턴스 사이의 관계를 나타낸다. 생성된 인스턴스에 대한 참조(인스턴스 변수)를 유지한다는 것이 특징이다.

- 상대방의 인스턴스를 가리키는 attribute를 가진다.

- 참조할 수 있는 attribute는 UML 상에서 표현하지 않는다. 표현하고자 할 때는 role name을 이용한다.


방향 종류

- Bidirectional Association (양방향) : 서로간 상대의 인스턴스를 가리키는 attribute(인스턴스 변수)를 갖는다.

- Unidirectional Association (단방향) : 한쪽 클래스만이 다른 상대의 인스턴스를 가리키는 attribute(인스턴스 변수)를 갖는다.



classifier : interface, class, component와 같이 인스턴스화 될 수 있는 요소



표현방법





Association 예)


위의 예제는 학생과 교실과의 관계이다. 학생은 하나의 교실에 포함되고 교실은 한명 이상의 학생을 포함한다. 그래서 class 쪽은 1, Student쪽은 1..* 이다. 이를 Multiplicity라 한다. +student와 +class 는 서로를 가르키는 인스턴스 변수를 말한다. 이 때 +는 public 접근제어를 뜻한다. 이는 위 클래스 다이어그램에서 언급했다.


Class(교실) 클래스 내부에는 Student클래스를 참조하는 student란 인스턴스 변수가 존재하고, Student(학생) 클래스 내부에는 class 란 인스턴스 변수가 존재한다.


#multiplicity와 인스턴스 변수 이름의 위치를 잘 써야한다. 위치를 반대로 쓸때가 있다.



Multiplicity

 1

 1개 

 0..1

 0또는 1 

 *

 다수(0포함) 

 1..*

 0을 제외한 다수. 최소 하나의 관계는 있어야 한다. 

 n..m

 최소 n개 최대 m개의 관계 





Aggregation ( 집합 연관 관계 )

- association 관계 중 특별한 관계를 나타낸다.

- 전체(whole)와 부분(part)을 나타내는 모델 요소이다.

- 'has a' 관계이다.

- 전체와 부분은 서로 독립적인 관계이다. 즉 생명주기가 동일하지 않다.

- 부분(part) 인스턴스는 다른 클래스와 공유 될 수 있다.(생명 주기가 다르므로)

- 전체(whole)에 속이 빈 다이아몬드이다.

- 단방향 연관 관계이다.(whole은 part을 알지만 part는 whole을 모른다.)



차(Car)는 4개의 바퀴(Wheel)를 갖는다. 차를 폐차한다고 바퀴까지 없애지는 않는다. 바퀴는 바퀴 독립적으로 다른 차에 장착할수 있다.





Composition (복합 연관 관계)

- 전체(Whole)와 부분(Part)을 나타내는 모델요소

- 전체를 나타내는 클래스와 이를 이루고 있는 부분 클래스 관계

- Aggregation 과는 다르게 강한 연관 관계이다.

- 전체와 부분이 동시에 생성되고 동시 소멸된다. 즉 생명주기가 동일하다.

- 이 관계에서는 전체가 생성될때 전체가 부분을 생성시키는 형태이다. 부분은 독립적으로 혼자 생성되지 않는다.

- 부분(Part)는 공유되지 않는다. 왜냐면 전체와 부분이 생명주기가 같다. 공유되면 전체가 살라질 때 부분도 사라져야 하는데 공유된다면 문제가 발생하기 때문이다.

예) 자바의 경우 인스턴스 참조 갯수를 보고 갈비지 콜렉터가 인스턴스를 해제할때 공유되면 해제되지 못한다.

C++의 경우에도 공유된 인스턴스가 다른 쪽에서 해제되면 공유된 인스턴스를 사용하는 다른 곳에서 잘못된 연산을 하게된다.

- 전체(whole)에 속이 꽉찬 다이아몬드이다.

- 단방향 관계이다.



손은 손가락 5개를 갖는다. 손이 사라지면 손가락도 사라지는 것이다. 


근데 의문이 들수 있다. 손이 사라져도 손가락 따로 다른 사람 손에 이식 시킬수 있지 않나? 그리고 손이 꼭 손가락 5개를 가져야 하나? 이건 프로그램을 설계하는 사람이 어떻게 설계하느냐에 따르는 것이다. 필자는 손은 꼭 손가락 5개, 그리고 손이 사라지면 손가락도 사라진다라고 설계했기때문에 위와 같은 관계가 나온것이다.

즉 관계라는 것은 설계에 따르는 것이다.





Realization (실체화, 실현화)

- 인터페이스와 실제 구현된 클래스간의 관계

- 인터페이스 UML 표현


- 전통적으로 인터페이스 명에는 접두에 'I'가 붙거나 접미에 able이 붙는다.

- 전통적으로 JAVA ~able, C# I~





인터페이스 확장

- 인터페이스는 컴포넌스(클르새ㅡ) 간의 결합력을 느슨하게 한다.(loose coupling)

- 인터페이스는 프로그램의 수정없이 쉽게 소프트웨어를 확장 할 수 있다.



위 그림은 인터페이스 없이 User라는 클래스가 Lg, Samsung 리모콘 클래스를 직접 사용하는 것이다. 프로그램 코드도 Samsung 이냐 Lg냐에 따라 코드를 따로 작성해야 한다. 소니 리모콘 추가시에 소니 리모콘 클래스 뿐 아니라 User가 이를 조작하는 코드가 추가되어야한다.


리모콘의 공통 기능을 인터페이스화 시키면 프로그램 코드가 확연히 줄어들고 또한 Samsung, Lg가 아닌 소니, 샤오미등 다른 리모콘 클래스를 만들어야 할때도 쉽게 이를 만들수 있다.


위 그림과 같이 User 클래스는 IRemoteControl이란 인터페이스 인스턴스를 통해 Samsung, Lg 리모콘의 기능을 동일하게 사용할 수 있다. 만약 소니 리모콘을 만들어야 한다고 해도 IRemoteControl를 실체화 시킨 클래스를 그냥 만들기만 하면 되고 User 클래스의 변경없이 소니 리모콘을 사용할 수 있다.


이 부분에 대해서는 코드가 있었으면 훨씬 이해가 쉬웠을 텐데 코드는 나중에 시간이 있다면 추가하겠다..( 거의 추가 안할것 같다.;;)








Package

개요

- UML 모델 요소를 조직화 하고 계층화 한다.

- Package는 각각의 Name space를 갖는다.

  = Package만 다르면 동일한 이름의 컴포넌트(클래스)를 가질 수 있다.


package는 위와 같이 그린다.




위와 같이 Name space가 같은 두 개의 클래스를 아래와 같이 Package로 묶어서 표현할 수 있다.






클래스 다이어그램 주의점

- 일반화는 'is a' 관계만 사용한다.

- 일반화관계를 균형있게 유지한다.(세분화 주의)

- 가능하면 interaction이 교차되지 않도록 주의한다.

- 이해하기 쉬울 정도의 관계만 표현한다. (너무 자세한 관계표현은 복잡해 진다.)

- 관련된 클래스는 가까이 배치한다.







본래 의도는 코드까지 넣어서 이해도를 높일 생각이었지만.... 객체지향언어 해보신분이라면 쉽게 읽을수 있습니다. ;;



아 위의 다이어그램들은 StarUML 2 가 나왔길래 그걸로 작업했습니다.

'학습자료(~2017) > UML' 카테고리의 다른 글

[UML] Class Diagram 클래스 다이어그램  (4) 2016.04.12
1장. UML Diagram  (0) 2015.05.22
0장. UML이란?  (0) 2014.08.06
  1. 유엠엘학도 2016.04.25 11:26

    궁금한게 있는데.. abstract랑 interface의 차이와 개념이 뭔가요..

    • 단세포소년 2016.04.25 11:42 신고

      범위로 보자면 abstract 가 interface를 포함합니다.

      interface는 abstract 중 class 가 public 이고 모든 메소드가 public 으로 선언만 된 형태 그리고 내부 인스턴스 변수가 없는 것을 말합니다.
      즉 행동만 기술된 추상클래스를 말합니다.

      public abstract class Test{
      public abstract void test01(int a);
      public abstract int test02(int b);
      }

      interface Test{
      void test01(int a);
      int test02(int b);
      }

      위의 두개는 즉 동일한 것입니다.

      다시 말하면 abstract 중에서 위에서 언급한 내용으로 제한된 형태를 interface라고 합니다.

      설명이 잘 되었나 모르겠네요

  2. 유엠엘학도 2016.04.25 11:51

    아 말 그대로 interface는 오브젝트는 없고 메소드만 있는 형태인건가요..?

    그렇다면 음.. 그냥 클래스에다가 오퍼레이션만 쓴 것이랑 똑같나요? 대체해서 쓸 수 있나요?

    • 단세포소년 2016.04.25 13:18 신고

      내부 인스턴스 변수가 없고 모든 메소드가 구현없이 public 으로 선언만 되어있는 형태라면 대체가능합니다

Doxygen

참고

https://www.stack.nl/~dimitri/doxygen/manual/index.html : doxygen 메뉴얼

http://www.slideshare.net/arload/doxygen-33932243 : doxygen 사용법

 

테스트 환경

- ubuntu14.04 lts

- php

 

 

 

 

 

테스트 코드



Test.php, Etc.php, subFolder/Etc.php 만들었다. 코드는 없다.

 

 

 

 

 

 

 

 

 

Doxygen 이란?

doxygen 코드상의 주석을 통해 문서를 만들어내는 프로그램이다. doxygen 맞는 주석을 사용하면 따로 문서를 만들 필요 없이 주석만으로 문서를 만들 있기 때문에 문서 관리를 따로 필요가 없고 코드만 보고도 이해하기가 쉬워진다.

 

아래와 같이 html 문서를 만들 있다.



 


 


 

 



 


 

 

 

 

기본 주석법

doxygen 인식하는 주석법은

/**
*
주석
*
*
*/

이런 식으로 /** 주석 시작시 * 두번 줘야 한다.

방법 말고도 주석 법은 있다.

 

아래의 사이트를 보면 주석 방법에 대해 나와 있다.

https://www.stack.nl/~dimitri/doxygen/manual/docblocks.html#specialblock

 

 

 

클래스에 대한 주석

@brief

간략한 설명

@details

자세한 설명

@author

저작권자

@date

날짜

@version

버전

 

 

/**

 *

 * @brief 테스트를 위한 클래스이다.

 * @details 내부에서 아무짓도 안한다.

 * @author oncellboy

 * @date 1234-12-12

 * @version 0.0.1

 *

 */

class Test{

}


 


 

출력 문석



 

 

 

 

메소드에 대한 주석

@brief

간략한 설명

@details

자세한 설명

@param

파라미터

@return

반환

@throws

발생 예외

 

/**

 *

 *        @brief 메서드 간략 설명

 *        @details 메서드 자세한 설명

 *        @param string a 파라미터 번

 *        @param string b

 *        이거는 테스트 파라미터

 *

 *        @return mixed|boolean

 *  성공시 숫자, 실패시 false 반환

 *        

 *        @throws ValidException 나쁜짓하면 예외발생        

 *

 */

public function add($a,$b)

{

$sum = $a + $b;

 

 

return $sum;

}


 


 

출력 문서



 

 

 

 

기타 주석

주석

설명

작성

출력

@todo

todo

todo 리스트를 따로 관리도 해준다.

@todo 다음주까지 해야할 업무



 

todo 리스트 관리



@todo 작성된 해당 클래스와 메소드를 알수 있다.

@bug

bug

bug 리스트를 따로 관리도 해준다.

@bug 반환이 언제나 false이다. 해결해야함




bug 리스트 관리



@bug 작성된 클래스와 메소드를 알수 있다.

@see

참고나 이것 저것 보여 줘야 하는것

@see 그냥 이것저것 보여줘야하는 것



 

_____|______

      |

 First Header  | Second Header

 ------------- | -------------

 Content Cell  | Content Cell

 Content Cell  | Content Cell



 

@li

리스트

@li list 1

@li list 2



 

[내용](링크주소)

링크

클릭시 링크를 연다.

[내 블로그](http://onecellboy.tistory.com)



@code

@endcode

코드 표현

 @code{.py}

 #!/usr/bin/python

 print "Hello World! 뜸금없는 파이썬 코드"

@endcode



 

@ref class

@ref namespace.class

참조

클래스 이름이나 네임스페이스가 포함되어 있는 경우 namespace.class 써준다.

참조 링크를 클릭시 해당 클래스의 문서 페이지로 이동한다.

@ref Etc

@ret subFolder.Etc



 

subFloder.Etc 클릭시 해당 클래스의 문서 페이지로 이동한다.



 

@n

주석 내에서 new line(개행) 이다.

@see 개행할 것 @n 이다.

 

 

 

작성 전체

<?php

 

 

require_once './Etc.php';

 

 

 

 

/**

 *

 * @brief 테스트를 위한 클래스이다.

 * @details 내부에서 아무짓도 안한다.

 * @author oncellboy

 * @date 1234-12-12

 * @version 0.0.1

 *

 */

class Test{

 

public $test; 

 

 

 

public function __construct()

{

 

}

 

 

 

public function show()

{

 

$etc = new Etc();

 

$str = $etc->getText();

 

print_r($str);

}

 

 

/**

 *

 *        @brief 메서드 간략 설명

 *        @details 메서드 자세한 설명

 *        @param string a 파라미터 번

 *        @param string b

 *        이거는 테스트 파라미터

 *

 *        @return mixed|boolean

 *  성공시 숫자, 실패시 false 반환

 *        

 *        @throws ValidException 나쁜짓하면 예외발생        

 *

 *

 *

 *  @todo 다음주까지 해야할 업무

 * 

 *  @bug 반환이 언제나 false이다. 해결해야함

 *

 *

 *  @see 그냥 이것저것

 *  보여줘야하는 것

 *

 *        

 *        First Header  | Second Header

 *        ------------- | -------------

 *        Content Cell  | Content Cell

 *        Content Cell  | Content Cell

 *

 *  @li list 1

 *  @li list 2

 *

 *  [내 블로그](http://onecellboy.tistory.com)

 *

 *        @code{.py}

 *  #!/usr/bin/python

 *        print "Hello World! 뜸금없는 파이썬 코드"

 *  @endcode

 *

 *  이 클래스를 사용합니다. @ref Etc @n

 *  이 네임스페이스의 이 클래스를 사용합니다. @ret subFolder.Etc

 *

 */

public function add($a,$b)

{

$sum = $a + $b;

 

 

return $sum;

}

}

 

 

출력 문서 전체



 



 



 

 

 

 

 


Doxygen 설치

$ sudo apt-get install doxygen doxygen-gui

 

 

Doxygen gui 실행

$ doxywizard

 

 

 

Doxygen GUI 설정

 



 

select : 소스의 위치를 지정

Pjorect name : 프로젝트 이름

Project viersion or id : 프로젝트 버전

Scan recursively : 소스 위치의 모든 하위 폴더까지 스캔(지정하지 않으면 하위폴더에 대한 문서는 생성 안함)

 

 



 

All Entities : 모든 엔트리

Include cross-referenced source code in the output : 함수마다 사용한 함수로의 링크를 생성

 

Select programming language to optimize the results for : 언어 지정

 



 

with navigation panel : 문서 왼쪽에 탐색 트리를 보여줌

 

 



 

Dot graphs to generate : 소스간의 관계를 GraphViz 표현해줌

 

 



 

OUTPUT_LANGUAGE : 출력 문서 언어

 

 



 

ALWAYS_DETAILDE_SEC : 항상 상세 정보를 보여줌

INLINE_INHERITED_MEMB : 소멸자와 상속자를 제외한 상속된 모든 멤버를 보여줌

 

 



 

EXTRACT_ALL : 소스코드의 모든 요소가 문서화 대상이

EXTRACT_PRIVATE : 클래스 내의 모든 private 멤버가 문서화 대상이

EXTRACT_STATIC : 클래스 내의 모든 static 멤버가 문서화 대상이



 

INLIVE_SOURCES : 함수 설명시 함수 코드를 보여줌

 

 



 

CLASS_DIAGRAMS : 클래스의 상속구조 다이어그램을 그림

UML_LOOK : 다이어그램을 UML 형식으로 그림

 



 

 

DOT_PATH : dot 프로그램(Graphviz) 위치를 지정

 

Graphviz 설치법  sudo apt-get install graphviz

설치 위치 확인 : which dot

 

 

 

 

 

문서 만들기



 

Run doxygen 클릭

 

Show HTML output으로 문서 확인

 



JKS 포맷의 인증서는 java 계열 인증설정시 많이 사용한다.




예를 들어 아래와 같이 파일이 있다고 하자.

 - 메인 인증서 : test.com.crt

 - 개인키 : test.com.key

 - 체인인증서 : chain1.crt , chain2.crt

 - 루트인증서 : trustcaroot.crt




1. pem 형식으로 파일 압축하기

crt 및 개인키로 인증서를 적용하기 위해 pem 형식으로 변환

( 개인키 -> 메인인증서 -> 체인인증서 -> 루트인증서 순서이다.)

$ cat test.com.key test.com.crt chain1.crt chain2.crt trustcaroot.crt > test.com.pem



2. openssl 을 이용하여 pem -> pkcs12 포맷으로 변환

( test.com.pem 을 test.com.p12 로 변환 )

$ openssl pkcs12 -export -out test.com.p12 -in test.com.pem

변환 시 패드워드는 임의로 지정한다.



3. keytool 을 이용하여 pkcs12 -> jks 포맷으로 변환

( test.com.p12 을 test.com.jks 로 변환 )

$ keytool -importkeystore -srckeystore test.com.p12 -srcstoretype pkcs12 -destkeystore test.com.jks -deststoretype jks

패스워드는 위의 openssl 사용 시 사용했던 패스워드를 사용한다.



4. 변환된 인증서 확인

$ keytool -list -keystore test.com.jks


Enter keystore password:

 

Keystore type: JKS

Keystore provider: SUN

 

Your keystore contains 1 entry

 

1, Jan 18, 2016, PrivateKeyEntry,

Certificate fingerprint (SHA1): B4:8D:C1:78:55:56:28:87:BA:39:EB:52:44:38:C1:11:5C:2B:43:93


공인된 인증서는 대행업체나 인증업체에서 발급받는다.



인증 파일 목록

 - 메인 인증서

 - 개인키

 - 체인인증서

 - 루트인증서


예를 들어 

 - 메인 인증서 : test.com.crt

 - 개인키 : test.com.key

 - 체인인증서 : chain1.crt , chain2.crt

 - 루트인증서 : trustcaroot.crt

있다고 하자.





1. MOD-SSL 활성 시키기

아파치 ssl 모듈을 활성화 시켜야한다

$ sudo a2enmod ssl

$ sudo service apache2 restart



2. 체인인증서 하나로 합치기

체인인증서가 2개이상일 경우이고 자신이 사용하는 web server 설정에 체인인증서를 여러개 설정하지 못하는 경우에는 여러개의 체인인증서를 하나로 합쳐야 한다.


$ sudo cat chain1.crt chain2.crt > chain.pem






3. SSL 설정

기본 ssl 사이트 설정은 apache2 기준으로 /etc/apache2/sites-available/default-ssl.conf 에 존재한다.


인증서들은 /etc/apache2/ssl 에 위치 한다고 가정한다.

체인인증서는 하나로 합친 chain.crt 를 사용한다.


$ sudo vi /etc/apache2/sites-available/default-ssl.conf


<IfModule mod_ssl.c>

        <VirtualHost _default_:443>

                ServerAdmin webmaster@localhost

 

                DocumentRoot /var/www/html

<생략.....>


        SSLEngine on

       SSLCertificateFile    /etc/apache2/ssl/test.com.crt

       SSLCertificateKeyFile /etc/apache2/ssl/test.com.key

       SSLCertificateChainFile /etc/apache2/ssl/chain.pem

       SSLCACertificateFile /etc/apache2/ssl/trustcaroot.crt

<생략.....>



4. ssl 설정 사이트 활성화 시키기

위에서 설정한 default-ssl.conf 설정을 활성화 시키자.

$ sudo a2ensite default-ssl.conf

$ sudo service apache2 reload




5. 확인

브라우저를 통해 test.com 에 접속해본다. 

몽고디비 3.2가 특정 시간이 지난후 연결이 해제되는 문제가 발생했다. 몽고디비를 인증모드로 설정해서 그런것인지 테스트는 안해보았고 급해서 3.0 으로 다시 다운그레이드를 진행했다.



mongodb 3.0 apt repository 등록

$ echo "deb http://repo.mongodb.org/apt/ubuntu precise/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list


$ sudo apt-get update

$ sudo apt-get install --force-yes sudo apt-get install -y mongodb-org=3.0.0 mongodb-org-server=3.0.0 mongodb-org-shell=3.0.0 mongodb-org-mongos=3.0.0 mongodb-org-tools=3.0.0


// 다운그레이드시에는 --force-yes 옵션을 붙여야한다.





# echo {package-name} | sudo dpkg --set-selections 


예를 들어 mongodb를 업그레이드 시키고 싶지 않다면


# echo "mongodb-org hold" | sudo dpkg --set-selections
# echo "mongodb-org-server hold" | sudo dpkg --set-selections
# echo "mongodb-org-shell hold" | sudo dpkg --set-selections
# echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
# echo "mongodb-org-tools hold" | sudo dpkg --set-selections




참고 : https://www.virtualbox.org/manual/ch04.html



4.2.2.1. Installing the Linux Guest Additions

The VirtualBox Guest Additions for Linux are provided on the same virtual CD-ROM file as the Guest Additions for Windows described above. They also come with an installation program guiding you through the setup process, although, due to the significant differences between Linux distributions, installation may be slightly more complex.

Installation generally involves the following steps:

  1. Before installing the Guest Additions, you will have to prepare your guest system for building external kernel modules. This works similarly as described inSection 2.3.2, “The VirtualBox kernel module”, except that this step must now be performed in your Linux guest instead of on a Linux host system, as described there.

    Again, as with Linux hosts, we recommend using DKMS if it is available for the guest system. If it is not installed, use this command for Ubuntu/Debian systems:

    sudo apt-get install dkms

    or for Fedora systems:

    yum install dkms

    Be sure to install DKMS before installing the Linux Guest Additions. If DKMS is not available or not installed, the guest kernel modules will need to be recreated manually whenever the guest kernel is updated using the command

    /etc/init.d/vboxadd setup

    as root.

  2. Insert the VBoxGuestAdditions.iso CD file into your Linux guest's virtual CD-ROM drive, exactly the same way as described for a Windows guest in Section 4.2.1.1, “Installation”.

  3. Change to the directory where your CD-ROM drive is mounted and execute as root:

    sh ./VBoxLinuxAdditions.run

For your convenience, we provide the following step-by-step instructions for freshly installed copies of recent versions of the most popular Linux distributions. After these preparational steps, you can execute the VirtualBox Guest Additions installer as described above.

4.2.2.1.1. Ubuntu

  1. In order to fully update your guest system, open a terminal and run

    apt-get update

    as root followed by

    apt-get upgrade
  2. Install DKMS using

    apt-get install dkms
  3. Reboot your guest system in order to activate the updates and then proceed as described above.







정리  하면 

#sudo apt-get update
#sudo apt-get upgrade
#sudo apt-get install dkms
#sudo apt-get install gcc
#sudo apt-get install build-essential linux-headers-`uname -r`
#sudo /etc/init.d/vboxadd setup

// guest Addition 마운트하고 마운트 폴더내에서 
#sudo ./VBoxLinuxAdditions.run

이렇게 했는데도 Could not find the X.org or XFree86 Windows System이 뜬다면 아래와 같이 해라. (Guestadditions 는 X.Org libraries를 필요로한다.)
#sudo apt-get install xserver-xorg xserver-xorg-core
#sudo ./VBoxLinuxAdditions.run


이래도 안되면 그냥 ssh 연결해서 하자..ㅜㅜ

생각해보니까 ubuntu Server를 설치한 내가 왜 굳이 guest additions 를 설치하려고 했을까.. 




UML Diagram 이란?

구성요소들의 그래픽 표현이다.



UML Diagram 종류

 - Class Diagram(클래스 다이어그램)

 - Object Diagram(객체 다이어그램)

 - Use Case Diagram(쓰임새 다이어그램)

 - Sequence Diagram(순서 다이어그램)

 - Collaboration Diagram(협력 다이어그램)

 - State Diagram(상태 다이어그램)

 - Activity Diagram(활동 다이어그램)

 - Component Diagram(컴포넌트 다이어그램)

 - Deployment Diagram(배치 다이어그램)

시스템을 여러 관점에서 표현할 수 있다.    


'학습자료(~2017) > UML' 카테고리의 다른 글

[UML] Class Diagram 클래스 다이어그램  (4) 2016.04.12
1장. UML Diagram  (0) 2015.05.22
0장. UML이란?  (0) 2014.08.06

UML이란?

Unified Modeling Language의 약자이다. 하나의 시스템을 표현하기 위한 표준적인 방법을 제공하기 위해서 만들어 졌다.

 

 

UML 개요

  • OMG 표준기구로부터 인정받은 표준화된 그래픽언어이다.
  • 개발자들의 의사소통을 원활하게 하며 기업간의 시스템 통합을 가능하게 한다.
  • 개발 시스템과 관련된 사람에게 비전을 공유하고, 의견을 얻을 수 있도록 한다.
    • 개발자, 운영자, 사용자, 엔지니어등와 시스템의 의도를 쉽게 전달할 수 있다.
  • UML은 기호와 도식을 이용한다.
  • 프로그램언어가 아닌 기호와 도식을 이용하여 표현하는 방법을 정의한다.

 

 

UML 작성 목적

객체 지향 시스템을 가시화, 명세화, 문서화한다.

 

 

 

UML의 요소

  • Thing
    • Structual Thing
    • Behavioral Thing
    • Grouping Thing
    • Annotation Thing
  • Relationships
    • Dependency Relationship
    • Generalization Relationship
    • Association Relationship
      • Aggregation Relationship
      • Composition Relationship
    • Realization Relationship
  • Diagrams
    • Class Diagram
    • Object Diagram
    • Use Case Diagram
    • Sequence Diagram
    • Collaboration Diagram
    • State Diagram
    • Activity Diagram
    • Component Diagram
    • Deployment Diagram

 

Thing

정의

추상적인 개념으로 UML을 이용한 모델링의 기본요소

 

종류

Structural Thing(구조 사물)

  - UML 모델의 명사형(예. 클래스, 노드, 서버, 사용자...)

  - 모델의 정적인 부분이며 개념적이거나 물리적인 요소

Behavioral Thing(행동 사물)

  - UML 모델의 동사형

  - 모델의 동적인 부분이며 시간과 공간에 따른 행위 요소를 표현

Grouping Thing(그룹 사물)

  - 모델을 그룹화하여 요소 표현(패키지, 라이브러리, 네임스페이스..)

Annotation Thing(주석 사물)

  - UML 모델 요소를 설명하거나 메모하거나 명확히 하는 표현방법(주석, 메모..) 

 

 

Structural Thing 종류

 = Class(클래스)

  - 속성과 동작으로 구성된 객체를 표현(변수와 메소드, 객체지향 언어의 Class 와 동일)

 

왼쪽은 클래스명, 속성, 행동(메소드)를 표현한 것

오른쪽은 클래스명만으로 간략히 표현한것

 

 

= Interface(인터페이스)

  - 클래스 또는 컴포넌트의 행동(동작, 메소드)만을 명세화한 Operation의 집합이다.{자바의 인터페이스와 동일 개념 속성(인스턴스 변수) 없이 행동(메소드)선언만 존재하는 추상클래스라고 생각하면 쉽다. 행동의 구체적 명시없이 선언된 클래스}

 

 

왼쪽은 클래스 표현법의 클래스명에 <<Interface>> 란 단어를 붙여 Interface를 표현할 것이다.(행동을 명시하고 싶을때 사용한다.)

오른쪽은 Interface 명만 표현한 것이다.

 

 

= Use Case (쓰임새)

  - 시스템이 수행해야 하는 기능을 기술

 

 

 

= Component (컴포넌트)

  - 객체 지향에서의 모듈화 된 자원

    예) 문서, 소스 코드, 파일, 라이브러리 등

 

 

 


= Node (노드)

  - 실행시에 존재하는 실제 물리적 요소

    예) 서버, 프린터, 복사기, 키보드 등

 

 

 

 

 

 

Behavioral Thing 종류

 

= Interaction (상호작용)

  - 행위를 의미하여 특정 문백에 속한 객체들간의 Messages 들로 구성

 

 

 

= State Machine (상태 머신)

  - 객체의 시간에 따른 상태를 표현

 

 

 

                                              예)  

 

 

 

 

 

Grouping Thing 종류

 = Package 패키지

  - 요소를 그룹으로 묶는 방법(폴더 모양), 프레임워크, 서브시스템 표현

 

 

 

 

Annotation Thing 종류

 = Note (노트)

  - 주석(comment) 로 모델요소를 명확하게 설명하기 위한 방법

  - 주로 제약조건, 메모, 설명을 표현한다.

 

 

 

 

 

 

 

 

Relationships

정의

  - 구성 요소들간의 연관성을 표현

  - 주로 클래스들간의 관계 표현시 사용된다.

 

종류

  - Dependency Relationship(의존 관계)

  - Generalization Relationship(일반화 관계)

  - Association Relationship(연관 관계)

     - Aggregation Relationship(집합 관계)

     - Composition Relationship(구성 관계)

  - Realization Relationship(실체화, 실현 관계)

 

 

Dependeny Relationship

정의

 - 한 클래스가 다른 클래스를 사용하는 사용관계

 (프로그래밍에서는 인스턴스 변수없이 어떤 클래스의 정적 메소드를 사용할 경우나, 메소드내에서만 생성되었다 사라지거나 하는 경우. 예를 들어 Math 클래스 사용시 인스턴스를 생성하지 않고 Math 클래스의 정적 메소드(Math.sin()) 을 사용하는 경우이다. )

 

특징

 - 하나의 클래스의 변화가 다른 클래스에 영향을 주는 관계

 - UML 표기법은 점선으로 된 화살표로 표현

 - A 가 B를 의존할때

 

                                       

예) 세금 , 세금법

 

 

 

Generalization Relationship

정의

 - 일반화(generalization), 특수화(명세 specialization) 관계

 - 객체 지향에서의 상속 관계

  예) 인간, 원숭이의 일반화(Generalization)는 포유류이다. 포유류 중 특수화(specialization)는 인간이다.

- 실선에 화살표로 표현

 

화살표 방향이 일반화관계이고 반대가 특수화 관계이다.

 

 

 

 

 

Association Relationship (연관 관계)

정의

 - 클래스로부터 생성된 객체간의 일반적 협력관계

 - 연관 관계는 실선혹은 양방향화살선으로 표현한다.

 

한 반에는 여러 학생이 속한다. 한 학생은 하나의 반에만 속할 수 있다. * 은 0 혹은 그이상을 표현한다.

 

그냥 실선이나 양화살표가 있는 선이나 같은 표현이다.

 

 

세부 종류(Association 관계는 세부적으로 2가지로 나눈다.)

 - Aggregation Relationship(집합연관)

 - Composition Relationship(복합연관)

* association, aggregation 은 개념적차이지 실제 코드상의 차이는 거의없다. composition 은 실제 코드상에 차이가 있다.

 

 

= Aggregation Relationship(집합 관계)

정의

 - 두 클래스간의 전체-부분관계(Whole-part)

 - 각 클래스가 독립적인 생명 주기를 갖는다.

   예) 자동차의 경우 자동차가 사라진다고 바퀴, 엔진이 사라지는 것은 아니다. 자동차와 바퀴, 엔진의 생명주기는 다르다. 역으로 바퀴가 사라진다고 자동차도 사라지는 것은 아니다.

 - 하나의 클래스가 여러개의 컴포넌트 클래스로 구성

 

 

추가설명 : Aggregation Relationship 은 속이 빈 다이아몬드로 표현한다.

 

이렇게 이해하면 좋다. A가 B를 포함한다.

A ◇───> B 









= Composition Relationship

정의

 - 두 클래스간의 부분-전체관계(Part-Whole)

 - 부분의 생명주기가 전체의 영향을 받는다.

 - 하나의 클래스가 여러개의 컴포넌트 클래스로 구성

 - 다른 말로 강한 집합관계

추가적으로

 - part를 가진 whole 인스턴스가 part 인스턴스의 전체 수명을 책임진다.

 - part에 해당하는 인스턴트는 공유 될수 없다.

 - whole 인스턴스가 part 인스턴스를 생성

 - whole 인스턴스가 소멸되면 part 인스턴스도 함계 소멸

 - whole 인스턴스가 복사되면 part 인스턴스도 복사됨


구현시

 - Deep Copy 를 구현해야함 (공유되지 않기 위해서)

 - whole 클래스 생성시 part도 같이 생성되어야 함

 - 외부에서 part를 생성하지 못하게 해야하고 또한 part에 대한 Setter가 없어야 한다.



- whole ◆───> part

 - aggreagtion 과 다르게 ◇ 에 속이 채워져 있다.(채워져 있으니 없어져도 같이 없어진다고 생각하면 편할 듯)

 - A 는 B로 구성되어 있다. A◆───> B



- 손과 손가락으로 예를 들었다. 손이 생겨야 손가락도 생긴다. 손가락만 따로 생성되지 않는다. 또한 손이 사라지면 손가락도 사라진다. 물론 현실 세계에서 손만 사라지고 손가락은 남아서 남한테 붙일수 있지만 Aggregation 이나 Composition은 개념적으로 설계자가 어떻게 설계하느냐에 따라 달라지는거다. 설계자는 손과 손가락을 하나의 세트로 생각했으므로 Composition을 사용한것이고 손이 사라지면 손가락도 사라진다고 설계자는 설계했다.



= Realization Relationship

정의

 - 인터페이스와 실제 구현된 클래스간의 관계

 - generaization Relationship과 비슷하다 다르다. generalization은 존재하는 객체(속성,행동)에 대한 추가구현(오버라이딩)이고 Realization 은 존재하는 행동에 대한 구현이다.

 - 예를 들어 부모와 자식관계에서 부모는 키, 몸무게 등의 속성과 걸음, 달리기, 점프등의 행동이 이미 존재한다. 이것을 그대로 상속 받거나 변조 구현 한것이 자식이다. 이처럼 존재하는 것에서 더 추가/제거/변경을 통해 생성된 관계가 generalization 관계이다.

 - Realization은 행동만 정의 되어있는(구현되지 않았다. 행동 목록만 존재) 객체(interface)를 구현한 것이다. 예를 들어 '달리다', '점프하다', '눕다' 란 행동목록이 존재한다면 이것이 interface이다. 키, 몸무게 등의 속성은 없다. 행동 또한 어떻게 달릴지 어떻게 뛰지 구현되어 있지 않다. 다만 행동 목록만 나열되어 있다. 이것을 구현 할 때 Realization Relationship 이다. 

달리다, 점프하다, 눕다란 행동은 인간 뿐만 아니라 강아지, 사자, 호랑이로 구현 될 수 있다.

 - interface 는 행동만 정의(나열, 구현되지 않았다.)된 객체이다.

 - 다시 정리하면 generalization 은 객체(속성,행동)을 이어받아 속성/행동을 추가/제거/수정한 구현을 말하고 Realization은 행동(기능) 목록만을 나열된 interface의 행동(기능)을 구현한 것이다.

 - 자바나 c# 등 객체지향 언어의 일반 클래스와 추상클래스, interface에 대한 개념이 있다면 쉽게 이해할 수 있다. 





'학습자료(~2017) > UML' 카테고리의 다른 글

[UML] Class Diagram 클래스 다이어그램  (4) 2016.04.12
1장. UML Diagram  (0) 2015.05.22
0장. UML이란?  (0) 2014.08.06


참고 : 

http://guguru.tistory.com/category/%5B%EA%B8%B0%EC%88%A0%EA%B2%80%ED%86%A0%20%26%20%EC%95%84%EC%9D%B4%ED%85%9C%5D

http://superlinuxer.com/DRBD

http://www.nidc.kr/customer/content.asp?board=tec&uid=967&board_group=2&params=skey=subject%5Epage=

http://www.drbd.org/docs/about/





DRBD 란?



DRBD는 블럭 디바이스를 HA(High Availabilty, 고가용성) 구성을 위한 Network Raid-1(mirroring) 유틸이다.

서비스 중단에 따른 Service Downtime 을 최소화하기 위해 사용된다.

DRBD 는 Raid-1 처럼 mirroring 만 하는 유틸이므로 linux heartbeat 와 같은 HA유틸과 같이 사용하는 것을 추천한다.



DRBD는 실제 사용하는 블럭 디바이스의 I/O 명령을 대신 받아서 처리한다.  실제 블럭 디바이스에 데이터를 쓰고 해당 데이터를 네트워크를 통해 mirroring 되는 장치로 보낸다.

예를 들어 /dev/sda 란 실제 블럭 디바이스가 있고 이를 중간에서 대신 처리하는 drbd 디바이스인 /dev/drbd0 가 있다면 모든 연산은 /dev/drbd0 로 보내면 이 연산을 /dev/sda 로 drbd가 대신 처리하고 network를 통해 다른 노드의 mirroring 되는 장비로 보낸다.


DRBD 상태는 primary 와 secondary 가 있으며 primary 에서만 연산이 가능하다. secondary는 primary를 계속 mirroring 한다.









DRBD 설치




설치 환경



OS : Ubuntu 14.014 LTS

DRBD : DRBD 8.4.4

 

primary ip : 192.168.3.11

primary hostname : drbd-1

primary device : /dev/sdb  # 실제 mirroring 할 디바이스


secondary ip : 192.168.3.12

secondary hostname : drbd-2

secondary device : /dev/sdc  # 실제 mirroring 할 디바이스







1. /etc/hosts(primary , secondary 둘다 설정)

drbd 설정시 hostname 을 통해 노드를 구분함으로 이를 /etc/hosts파일에 등록해야한다.


$ vi /etc/hosts

192.168.3.11    drbd-1

192.168.3.12    drbd-2




2. 패키지 설치 및 kernel module 로드(primary , secondary 둘다 설정)

$ sudo apt-get install drbd8-utils

$ sudo modprobe drbd


module 로드 확인

$ lsmod | grep drbd




3. DRBD 설정(primary , secondary 둘다 설정)

설정 파일은 /etc/drbd.d/ 에 넣으면 된다. 이전 버전의 경우는 /etc/drbd.conf 이다.

현재는 /etc/drbd.conf 에서 /etc/drbd.d/ 하위의 설정파일을 불러 오는 방법을 쓴다.


$ cat /etc/drbd.conf

# You can find an example in  /usr/share/doc/drbd.../drbd.conf.example

include "drbd.d/global_common.conf";

include "drbd.d/*.res";



# drbd 설정 파일 만들기

$ sudo vi /etc/drbd.d/{name}.res

resource "{resource_name}"

{

protocol {A | B | C};

disk {on-io-error detach;}

               syncer {

                        }


                 on {primary-hostname} {

                     device /dev/{drbd_logical_name};

                     disk /dev/{raw_device_name};

                     address {ip}:{port};

                     meta-disk internal;

                             }


                on {secondary-hostname} {

                     device /dev/{drbd_logical_name};

                     disk /dev/{raw_device_name};

                     address {ip}:{port};

                     meta-disk internal;

                             }

}


{}  인 곳에 내용을 넣어주면 된다.
- resource : 임의의 리소스 이름을 넣으면 된다.
- protocol : 동기화 방식인데, A는 비동기 방식으로 속도는 빠르나 데이터 손실의 위험이 있다. B는 메모리 까지만 동기화 방식으로 속도가 A보다는 느리지만 꽤빠른편이고 데이터 손실 위험은 A보다 적다. C는 동기 방식으로 primary 에서의 연산이 secondary에서도 완료되어야 작업이 완료되는 방식으로 속도는 제일 느리나 데이터 신뢰성을 높다. 데이터의 안정성은 C가 제일 좋다.
- on : 노드를 구분한다. hostname을 써주면 된다.
- device : drbd 논리 디바이스 이름이다. 해당 이름은 임의로 주면 drbd 동작시 해당 이름의 논리 디바이스를 만든다. 전통적으로는 drbd0, drbd1 이런 식으로 이름짓는다.
- disk : 실제 디바이스 이름을 넣는다. 
- address : ip와 port를 넣는다.
- meta-disk : drbd 가 동작하기 위한 메타데이터 저장 공간이며 디바이스를 따로 지정할 수 도 있지만 internal로 지정하면 disk 항복에 지정된 실제 디바이스의 공간중 128MB를 이용하여 메타 데이터용으로 쓴다.


                                                                                                                                                                          


예) $ sudo vi /etc/drbd.d/drbd_test.res


resource "test01"

{

protocol C;

disk {on-io-error detach;}

               syncer {

                        }


                 on drbd-1 {

                     device /dev/drbd0;

                     disk /dev/sdb;

                     address 192.168.3.11:7791;

                     meta-disk internal;

                             }


                 on drbd-2 {

                     device /dev/drbd0;

                     disk /dev/sdc;

                     address 192.168.3.12:7791;

                     meta-disk internal;

                                }

}


위 설정을 보면 drbd-1의 /dev/sdb 와 drbd-2의 /dev/sdc 간 mirroring 을 한다는 것이다.







4. DRBD 실행(primary , secondary 둘다 )

drbd-1$ sudo service drbd start

drbd-2$ sudo service drbd start





5. METADATA 생성(primary , secondary 둘다 )

* 주의 : Metadata 생성전 DRBD 볼륨으로 사용할 공간은 파일시스템이 생성되어 있지 않아야한다.

미리 파일시스템이 생성된 상태라면 아래와 같은 에러가 발생할 경우

Command 'drbdmeta 1 v08 /dev/xxx internalcreate-md' terminated with exit code 40


dd를 이용하여 MBR 영역을 없애주어야한다.

$ dd if=/dev/zero of=/dev/sdb bs=1M count=128



# Metadata 생성 명령

$ sudo drbdadm create-md all


위 명령을 수행하면 device 에 지정했던(/dev/drbd0) 디바이스가 생성된다.




6. DRBD primary 만들기(primary 에서 명령)

DRBD 가 처음실행되면 secondary/secondary로 동작한다. 이를 primary/secondary로 만들어 mirroring이 진행될 수 있게 해야한다.


primary 로 사용할 drbd-1 호스트에서 아래의 명령을 호출한다.


$ sudo drbdadm primary {resource_name}


# 위의 예제 설정에서는 resource_name 이 test01이었다.

예) $ sudo drbdadm primary test01











DRBD 모니터링



정상 동작하는지 확인해보자.


모니터링 명령으로는

$ cat /proc/drbd

$ sudo drbdadm role {resource_name}

$ sudo service drbd status

가 있다.


$ cat /proc/drbd

version: 8.4.3 (api:1/proto:86-101)

srcversion: 88927CDF07AEA4F7F2580B2 

 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----

    ns:50 nr:117650 dw:117695 dr:3746 al:2 bm:9 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


$ sudo drbdadm role {resource_name}

예)

$ sudo drbdadm role test01

Primary/Secondary



$ sudo service drbd status

drbd driver loaded OK; device status:

version: 8.4.3 (api:1/proto:86-101)

srcversion: 88927CDF07AEA4F7F2580B2 

m:res  cs         ro                 ds                 p  mounted   fstype

0:r0   Connected  Primary/Secondary  UpToDate/UpToDate  C  /tmp/mnt  ext3 










DRBD 운영




1. 파일 시스템으로 포맷하고 mount 하기

primary 노드에서 디바이스를 ext3 로 포맷팅하고 mount

* 주의 : /dev/sdb 를 포맷팅하는 것이 아니라 이를 대신 처리해주는 drbd 논리 디바이스인 /dev/drbd0에 수행해야한다.


$ sudo mkfs.ext3 /dev/drbd0

$ sudo mount /dev/drbd0 /mnt


* 주의 : secondary 노드의 블록 디바이스는 mirroring 만 되는 것이다. mount 되지 않는다. secondary 노드의 블록 디바이스를 mount 하기 위해서는 primary를 secondary 로 만들고 secondary 를 primary 로 만들어야한다.





2. mirroring 확인

primary 노드에서 마운트 진행하였고 여기에 파일을 하나 만든다.

drbd-1$ sudo touch /mnt/test


secondary 에 mirroring 되는지 확인하기 위해 secondary를 primary로 만들 것이다.

primary 노드는 하나밖에 지정못하므로 primary 를 우선 secondary 로 만들어야한다. secondary 로 만들기 전에 우선 umount 해야한다.


# primary를 secondary 만들기

drbd-1$ sudo umount /mnt

drbd-1$ sudo drbdadm secondary test01 #test01은 resource_name이다.


# secondary를 primary 만들기

drbd-2$ sudo drbdadm primary test01


# secondary 노드 였던 drbd-2에서 마운트하여 확인하기

drbd-2$ sudo mount /dev/drbd0 /mnt

drbd-2$ ls -al /mnt



확인해보면 drbd-1에서 생성했던 test 란 파일이 보일 것이다.









3. secondary를 primary 만들기

secondary를 primary 로 만드는 경우는 primary 노드가 죽었을 때 이다.

primary 노드가 죽었다면 secondary를 primary 로 만들어 서비스를 지속시켜야한다.


secondary 노드에서 아래의 명령을 통해 확인하면 primary 노드의 연결이 끊긴것을 확인할 수 있다.


drbd-2$ cat /proc/drbd

version: 8.4.3 (api:1/proto:86-101)

srcversion: 88927CDF07AEA4F7F2580B2 

 0: cs:WFConnection ro:Secondary/Unknown ds:UpToDate/DUnknown C r-----

    ns:0 nr:43 dw:43 dr:1456 al:0 bm:2 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0



drbd-2$ sudo service drbd status

drbd driver loaded OK; device status:

version: 8.4.3 (api:1/proto:86-101)

srcversion: 88927CDF07AEA4F7F2580B2 

m:res  cs            ro                 ds                 p  mounted  fstype

0:r0   WFConnection  Secondary/Unknown  UpToDate/DUnknown  C



secondary 를 primary 로 만든다.


drbd-2 $ sudo drbdadm primary {resource_name}


예) resource_name 이 test01일때

drbd-2 $ sudo drbdadm primary test01




secondary 를 primary로 만들었는지 확인

drbd-2$ cat /proc/drbd

version: 8.4.3 (api:1/proto:86-101)

srcversion: 88927CDF07AEA4F7F2580B2 

 0: cs:WFConnection ro:Primary/Unknown ds:UpToDate/DUnknown C r-----

    ns:0 nr:43 dw:43 dr:2912 al:0 bm:2 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


drbd-2$ sudo service drbd status

drbd driver loaded OK; device status:

version: 8.4.3 (api:1/proto:86-101)

srcversion: 88927CDF07AEA4F7F2580B2 

m:res  cs            ro               ds                 p  mounted  fstype

0:r0   WFConnection  Primary/Unknown  UpToDate/DUnknown  C








4. secondary 노드를 교체

 위의 상황처럼 primary 가 죽거나 secondary 가 죽거나 하여 mirroring 할 경로를 바꾸어야할 때


예를 들어 secondary 였던 drbd-2 의 장애로 drbd-3 에 mirroring 을 해야할 경우이다.



우선 primary 의 설정파일을 drbd-3로 바꾼다.

drbd-1 $ sudo vi /etc/drbd.d/{name}.res


예)

drbd-1 $ sudo vi /etc/drbd.d/test.res


resource "test01"

{

protocol C;

disk {on-io-error detach;}

               syncer {

                        }


                 on drbd-1 {

                     device /dev/drbd0;

                     disk /dev/sdb;

                     address 192.168.3.11:7791;

                     meta-disk internal;

                             }


                 on drbd-3 {

                     device /dev/drbd0;

                     disk /dev/sdb;

                     address 192.168.3.13:7791;

                     meta-disk internal;

                                }

}


그리고 secondary 로 사용할 drbd-3 에도 동일하게 설정하고 drbd를 실행시킨다. 실행시키면 primary 의 연결을 대기한다.


drbd-3 $ sudo service drbd start



그리고 drbd-1 에서 drbd-3 로 연결하는 명령을 수행한다.


drbd-1 $ sudo drbdadm connect test01   # test01은 .res 파일 내의 resource_name 이다.


  1. 대학생 2019.09.03 16:16

    pacemaker의 resource부분에 drbd를 넣고싶은데 혹시 방법을 아시는지 궁금합니다.
    답변 부탁드립니다.

    • 단세포소년 2019.09.06 12:08 신고

      답글이 늦었습니다.

      죄송하게도 제가 pacemaker 에 대한 지식이 없어서 답변을 드리기 힘들겠네요.

  2. ㅇㅇ 2019.12.19 17:31

    만약 /dev/drbd0 을 /d 라는 파일에 마운트를 시켯다면 /d라는 파일에 들어가는 데이터만 drbd가 처리를 하는건가요?

    • 단세포소년 2019.12.27 12:00 신고

      답변이 늦었네요.

      예 그렇습니다.

      더 정확히는 파일단위가 아니라 블럭단위입니다.

1. 하위 디렉토리 파일 내용 치환


$ find ./ -type f | xargs sed -i 's/from/to/g'

현재 디렉토리 내의 모든 파일들의 내용중 from 을 to로 바꾼다.



2. 하위 디렉토리 파일 이름 변경


find ./ -name "*from*"  | sed -e 'p' -e "s/from/to/g" |xargs -n 2 mv

현재 디렉토리 내의 모든 파일, 디렉토리의 이름중 from이 포함된 파일, 디렉토리의 이름의 from을 to로 바꾼다.

예) test_from_test -> test_to_test




은근 필요할 때가 많더라. 

오랜만에 글 올렸는데 짧다..

  1. ㅇㅇㅇ 2020.02.12 17:43

    첫문장에 type 앞에 - 가 빠졌네요

    하여튼 내용 너무 좋았습니다. 감사합니다.

/etc/fstab 에 네트워크 드라이브/저장소를 자동 mount 하게 설정하는 경우 시스템 재시작시 마운트를 하지 못하여 대기를 하는 경우가 있다.

이 문제는 시스템이 네트워크를 설정하고 연결하기 전에 /etc/fstab 의 mount 를 시도하기 때문이다.


예를 들어

/etc/fstab

  192.168.1.1:/usr/local    /mnt    nfs    defaults     0    0

위와 같은 경우 192.168.1.1:/usr/local 에 대한 mount 가  네트워크 연결보다 먼저 일어나기 때문에 시스템 시작시 자동 마운트 되지 않는다. 심한 경우는 해당 경로를 마운트하기 위해 무한대기한다.



이와 같이 네트워크를 통한 저장소를 /etc/fstab 에 등록할때에는 mount 옵션에 _netdev 를 추가해주어야한다.

 192.168.1.1:/usr/local    /mnt    nfs    defaults,_netdev     0    0

_netdev 옵션은 네트워크에 연결후 마운트하라는 옵션이다. 이렇게 해야 시스템 시작시 문제 없이 해당 네트워크 경로로 자동 마운트 된다.




% 기록 위주라 보니 글에 정성은 미포함이다...

  1. ㅇㅇ 2018.01.04 02:35

    감사합니다~

apt-get 에서 repository 를 cdrom 으로 잡는 방법


네트워크를 못쓰는 상황이나 급하게 패키지를 설치해야 하는 경우가 존재한다.

나의 경우는 네트워크를 못쓰는 상황이었다. 


이때 방법이 설치 cd 를 이용하는 방법이다. 설치 cd 에는 기본적인 패키지들은 존재한다.



만약 cd 의 디바이스가 /dev/sr0 라고 한다면



$ sudo mount -o loop /dev/sr0 /media/cdrom


# 왜 /media/cdrom 이냐면 /etc/apt/apt.conf.d/00CDMountPoint  설정에 그렇게 잡혀 있다. 왠만하면 이 경로 쓰자.

Acquire::cdrom {

  mount "/media/cdrom";

};

Dir::Media::MountPath "/media/cdrom";



/media/cdrom 경로를 repository 로 등록하면 된다.



$ sudo apt-cdrom add -d /media/cdrom -m


그런후 /etc/apt/sources.list 를 확인하면


deb cdrom:[Ubuntu-Server..~~~~~~~~~~~] raring main restricted

라고 적혀있을 것이다.



$ sudo apt-get update

후에 패키지 설치하면 된다.


끝.


급하게 쓴 글이라.. 


추가적인 부분은 google 에게 물어라.



폴더내 모든 문서의 특정 문자열 치환


find ./ -type f |xargs sed -i 's/{바꿀문자열}/{새로운문자열}/g'


만약 특정 폴더에 파일이 많고 파일의 내용중 TEST 를 test 로 바꾼다면


find ./ -type f |xargs sed -i 's/TEST/test/g'






폴더내 파일중 특정 이름의 파일을 바꿀 경우


$ find ./ -name "*{바꿀문자열}*"  | sed -e 'p' -e "s/{바꿀문자열}/{새로운문자열}/g" |xargs -n 2 mv



만약 특정 폴더에 'TEST' 문자열이 들어가는 폴더나 파일의 이름을 'TEST' 대신 'test' 로 바꾼다면

예) TEST_aa   -> test_aa


$ find ./ -name "*TEST*"  | sed -e 'p' -e "s/TEST/test/g" |xargs -n 2 mv



만약 특정 폴더에 'TEST' 문자열이 들어가는 폴더만 이름을 'TEST' 대신 'test' 로 바꾼다면


$ find ./ -name "*{TEST}*" -type d  | sed -e 'p' -e "s/TEST/test/g" |xargs -n 2 mv

  1. a91558972@gmail.com 2022.05.02 21:43

    감사해요... 한 줄기 빛과 같습니다 일일이 이름 바꿀생각만 하면 .. 으 ... ㅜㅜ 감사합니다



git 에서 소스를 export 하기 위해서는 archive 란 명령을 사용한다.


$ git archive HEAD | tar -x -C {TARGEET_ROOT}


{TARGEET_ROOT} : 여기에는 소스를 export 하기 위한 빈 디렉터리의 경로를 지정하면 된다.


HEAD 는 현재 자신이 선택한 branch 이다. 다른 명령 내리지 않았다면 master branch 일 것이다.





git 에서 소스를 archive 로 추출할 때 한가지 문제가 존재한다. git 소스내의 submodule 같은 경우 추출이 안된다.


이때는 아래와 같이 수행한다.


$ git submodule init

$ git submodule update


$ git submodule foreach 'git archive HEAD | tar -x -C {TARGET_ROOT}/$path'


 {TARGET_ROOT} : 위에서 archive 명령을 이용해 추출한 경로와 동일하다. 



1. 인증서 생성


sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt



2. apache 설정


아파치 설정 부분에 아래의 굻은 글씨를 추가하면 https 접속으로 바뀐다. https 기본 포트는 443 이다.


vi /etc/apache2/sites-available/https.conf


<VirtualHost *:443>

        ServerAdmin webmaster@localhost



       SSLEngine on

       SSLCertificateFile /etc/apache2/ssl/apache.crt

       SSLCertificateKeyFile /etc/apache2/ssl/apache.key



        DocumentRoot /var/www

        <Directory />

                Options FollowSymLinks

                AllowOverride None

        </Directory>

        <Directory /var/www/>

                Options Indexes FollowSymLinks MultiViews

                AllowOverride None

                Order allow,deny

                allow from all

        </Directory>


        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

        <Directory "/usr/lib/cgi-bin">

                AllowOverride None

                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

                Order allow,deny

                Allow from all

        </Directory>


        ErrorLog ${APACHE_LOG_DIR}/error.log


        # Possible values include: debug, info, notice, warn, error, crit,

        # alert, emerg.

        LogLevel warn


        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>








443 포트에 관한 설정은 /etc/apache2/sites-available/default-ssl  이미 기본적으로 있다. 443포트에 대해 위처럼 따로 설정을 한다면

 

sudo a2dissite default-ssl 


명령을 통해 default-ssl 설정을 사용중지 시켜야한다.





3. ssl 모듈 활성



sudo a2enmod ssl


sudo service apache2 restart







4. https.conf 활성



sudo a2ensite https.conf







5. 참고 사항



기본적으로 apache 설치시 /etc/apache2/sites-available/default-ssl 란 파일에 443 포트에 대한 https 설정이 있다.


sudo a2enmod ssl 

sudo service apache2 restart


명령을 통해 ssl 모듈을 활성화 시키고



sudo a2ensite default-ssl 


명령을 통해 설정을 활성화만 시키면 https 접속이 가능하다.





아래는 /etc/apache2/sites-available/default-ssl  내용이다.


<IfModule mod_ssl.c>

<VirtualHost _default_:443>

        ServerAdmin webmaster@localhost


        DocumentRoot /var/www

        <Directory />

                Options FollowSymLinks

                AllowOverride None

        </Directory>

        <Directory /var/www/>

                Options Indexes FollowSymLinks MultiViews

                AllowOverride None

                Order allow,deny

                allow from all

        </Directory>


        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

        <Directory "/usr/lib/cgi-bin">

                AllowOverride None

                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

                Order allow,deny

                Allow from all

        </Directory>


        ErrorLog ${APACHE_LOG_DIR}/error.log


        # Possible values include: debug, info, notice, warn, error, crit,

        # alert, emerg.

        LogLevel warn


        CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined


        #   SSL Engine Switch:

        #   Enable/Disable SSL for this virtual host.

        SSLEngine on


        #   A self-signed (snakeoil) certificate can be created by installing

        #   the ssl-cert package. See

        #   /usr/share/doc/apache2.2-common/README.Debian.gz for more info.

        #   If both key and certificate are stored in the same file, only the

        #   SSLCertificateFile directive is needed.

        SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem

        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key


        #   Server Certificate Chain:

        #   Point SSLCertificateChainFile at a file containing the

        #   concatenation of PEM encoded CA certificates which form the

        #   certificate chain for the server certificate. Alternatively

        #   the referenced file can be the same as SSLCertificateFile

        #   when the CA certificates are directly appended to the server

        #   certificate for convinience.

        #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt


        #   Certificate Authority (CA):

    #   Set the CA certificate verification path where to find CA

        #   certificates for client authentication or alternatively one

        #   huge file containing all of them (file must be PEM encoded)

        #   Note: Inside SSLCACertificatePath you need hash symlinks

        #         to point to the certificate files. Use the provided

        #         Makefile to update the hash symlinks after changes.

        #SSLCACertificatePath /etc/ssl/certs/

        #SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt


        #   Certificate Revocation Lists (CRL):

        #   Set the CA revocation path where to find CA CRLs for client

        #   authentication or alternatively one huge file containing all

        #   of them (file must be PEM encoded)

        #   Note: Inside SSLCARevocationPath you need hash symlinks

        #         to point to the certificate files. Use the provided

        #         Makefile to update the hash symlinks after changes.

        #SSLCARevocationPath /etc/apache2/ssl.crl/

        #SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl


        #   Client Authentication (Type):

        #   Client certificate verification type and depth.  Types are

        #   none, optional, require and optional_no_ca.  Depth is a

        #   number which specifies how deeply to verify the certificate

        #   issuer chain before deciding the certificate is not valid.

        #SSLVerifyClient require

        #SSLVerifyDepth  10


        #   Access Control:

        #   With SSLRequire you can do per-directory access control based

        #   on arbitrary complex boolean expressions containing server

        #   variable checks and other lookup directives.  The syntax is a

        #   mixture between C and Perl.  See the mod_ssl documentation

        #   for more details.

        #<Location />

        #SSLRequire (    %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \

        #            and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \

        #            and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \

        #            and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \

        #            and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20       ) \

        #           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/

        #</Location>


        #   SSL Engine Options:

        #   Set various options for the SSL engine.

        #   o FakeBasicAuth:

        #     Translate the client X.509 into a Basic Authorisation.  This means that

        #     the standard Auth/DBMAuth methods can be used for access control.  The

        #     user name is the `one line' version of the client's X.509 certificate.

        #     Note that no password is obtained from the user. Every entry in the user

        #     file needs this password: `xxj31ZMTZzkVA'.

        #   o ExportCertData:

        #     This exports two additional environment variables: SSL_CLIENT_CERT and

        #     SSL_SERVER_CERT. These contain the PEM-encoded certificates of the

        #     server (always existing) and the client (only existing when client


#     authentication is used). This can be used to import the certificates

        #     into CGI scripts.

        #   o StdEnvVars:

        #     This exports the standard SSL/TLS related `SSL_*' environment variables.

        #     Per default this exportation is switched off for performance reasons,

        #     because the extraction step is an expensive operation and is usually

        #     useless for serving static content. So one usually enables the

        #     exportation for CGI and SSI requests only.

        #   o StrictRequire:

        #     This denies access when "SSLRequireSSL" or "SSLRequire" applied even

        #     under a "Satisfy any" situation, i.e. when it applies access is denied

        #     and no other module can change it.

        #   o OptRenegotiate:

        #     This enables optimized SSL connection renegotiation handling when SSL

        #     directives are used in per-directory context.

        #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire

        <FilesMatch "\.(cgi|shtml|phtml|php)$">

                SSLOptions +StdEnvVars

        </FilesMatch>

        <Directory /usr/lib/cgi-bin>

                SSLOptions +StdEnvVars

        </Directory>


        #   SSL Protocol Adjustments:

        #   The safe and default but still SSL/TLS standard compliant shutdown

        #   approach is that mod_ssl sends the close notify alert but doesn't wait for

        #   the close notify alert from client. When you need a different shutdown

        #   approach you can use one of the following variables:

        #   o ssl-unclean-shutdown:

        #     This forces an unclean shutdown when the connection is closed, i.e. no

        #     SSL close notify alert is send or allowed to received.  This violates

        #     the SSL/TLS standard but is needed for some brain-dead browsers. Use

        #     this when you receive I/O errors because of the standard approach where

        #     mod_ssl sends the close notify alert.

        #   o ssl-accurate-shutdown:

        #     This forces an accurate shutdown when the connection is closed, i.e. a

        #     SSL close notify alert is send and mod_ssl waits for the close notify

        #     alert of the client. This is 100% SSL/TLS standard compliant, but in

        #     practice often causes hanging connections with brain-dead browsers. Use

        #     this only for browsers where you know that their SSL implementation

        #     works correctly.

        #   Notice: Most problems of broken clients are also related to the HTTP

        #   keep-alive facility, so you usually additionally want to disable

        #   keep-alive for those clients, too. Use variable "nokeepalive" for this.

        #   Similarly, one has to force some clients to use HTTP/1.0 to workaround

        #   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and

        #   "force-response-1.0" for this.

        BrowserMatch "MSIE [2-6]" \

                nokeepalive ssl-unclean-shutdown \

                downgrade-1.0 force-response-1.0

        # MSIE 7 and newer should be able to use keepalive

        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown


</VirtualHost>




하드웨어
























만약 현재 우분투 12.04를 사용하고 있고 새로운 버전인 13.10이 나왔다고 했을 때 아래의 명령을 통해 쉽게 릴리즈 버전으로 업그레이드 할 수 있다.

$ do-release-upgrade 

http://tmdgus.tistory.com/116


http://www.troot.co.kr/tc/2671


http://stackoverflow.com/questions/16360689/invalid-parameters-error-when-trying-to-insert-module-that-accesses-exported-s  - insert module 시 Invaild parameters 오류 발생시, 모듈 컴파일시 undefined 오류 발생시 해결법




1. 특정 모듈 컴파일시 필요한것


1. 커널 소스 헤더와 의존되는 모듈이 있다면 해당 모듈의 심볼 테이블이다. 

심볼 테이블의 이름은 Module.symvers 이다.

심볼 테이블은 모듈을 컴파일하면 해당 디렉토리에 생성되며 함수의 위치 정보를 가지고 있다.


2. 커널 소스 혹은 커널 헤더

sudo apt-get install linux-source 나 sudo apt-get install linux-headers-x.x.x 을 통해 받을수 있다. 대체로 위치는 /usr/src 에 존재한다.




2. 특정 모듈 컴파일시 Makefile


obj-m = {modulename}.o

{modulename}-y = {file}.o

PWD = $(shell pwd)

ccflags-y += {추가할 헤더경로}

KBUILD_EXTRA_SYMBOLS = {참조할 심볼 테이블}

all:  
         make -C {헤더나 소스 최상위 경로} M=$(PWD) modules  

clean:  
        make -C {헤더나 소스 최상위 경로} M=$(PWD) clean


예들 들어 

1. test.ko 란 모듈을 제작하려고 하고 해당 모듈은 소스파일 /test/foo.c , /test/bar.c 로 이루어져 있다고 하자. 

그리고 /test/include/foo.h , /test/include/bar.h 헤더가 존재한다고 하자.  그리고 libtest.ko 의 함수를 test.ko 에서 사용한다고 하자.


2. libtest.ko 란 모듈은 소스파일 /libtest/libtest.c 로 이루어져 있다고 하자. 헤더는 따로 없다.


그리고 /usr/src/linux-headers-3.10 에 헤더파일들이 존재한다고 하자.

* 커널 헤더는 sudo apt-get install linux-headers 명령을 통해 받을수 있다. 혹은 그냥 커널 소스 자체를 받아도 된다.



이때 test.ko 에 대한 Makefile 은 /test/ 안에 생성해야한다.

obj-m += test.o

test-y := foo.o bar.o

PWD = $(shell pwd)

ccflags-y += -I/test/include

KBUILD_EXTRA_SYMBOLS += /libtest/Module.symvers

all:

         make -C /usr/src/linux-headers-3.10/ M=${PWD} modules

clean:

         make -C /usr/src/linux-headers-3.10/ M=${PWD} clean



libtest.ko 에 대한 Makefile은 /libtest/ 안에 생성한다.

obj-m += libtest.o

PWD = $(shell pwd)

all:

         make -C /usr/src/linux-headers-3.10/ M=${PWD} modules

clean:

        make -C /usr/src/linux-headers-3.10/ M=${PWD} clean



컴파일은 해당 디렉토리에 가서 make all 하면된다.

test.ko 는 libtest.ko의 함수를 사용하기 때문에 libtest.ko 의 심볼 테이블이 필요하다. 그러므로 libtest.ko 를 우선 컴파일 해야한다.

libtest.ko 를 컴파일하면 해당 디렉토리에 Module.symvers 심볼 테이블 파일이 생성된다.

그후 test.ko 를 컴파일하면 이상없이 컴파일 될것이다.



3. Makefile 설명


1. obj-m : 생성할 모듈 이름이다. 예를 들어 test.ko 를 생성하고 싶다면 test.o 를 인자로 주면된다.(test.ko 가 아니다.)

 obj-m += test.o


2. {module_name}-y : 해당 모듈을 구성하는 소스리스트를 적어주면된다. 주의할 것은 .o 이지 .c 가 아니다. 예를들어 test.ko 를 구성하는 소스가 foo.c, bar.c 라면

 test-y := foo.o bar.o


3. PWD = $(shell pwd) : 그냥 현재 경로이다.


4. ccflags-y : 이것은 컴파일시 gcc 에 포함할 옵션이다. 예를들어 참조하는 헤더의 위치가 /home/include 라면 이 경로는 gcc가 암시적으로 참조하지 않는다. 따라서 옵션을 주어 해당경로에서도 헤더를 찾으라고 해야한다. 헤더가 위치한 경로를 주는 옵션은 대문자 I 이다.

 ccflags-y += -I/home/include



5. KBUILD_EXTRA_SYMBOLS : 참조할 심볼 테이블 파일의 경로이다. 심볼 테이블 파일의 이름은 Module.symvers 이다. 예를 들어 참조하는 심볼 테이블의 경로가 /libtest/Module.symvers 라면

 KBUILD_EXTRA_SYMBOLS += /libtest/Module.symvers


6. all , clean : 여기의 make -C 옵션 값은 커널 헤더 최상위 경로거나 커널 소스 최상위 경로이면 된다.

셋중 하나면 된다. 중요한 것은 현재 커널 버젼 uname -r 과 동일해야한다는 것이다.

 make -C /usr/src/linux-headers-$(shell uname -r)/ M=$(PWD)  modules

혹은

 make -C /usr/src/linux-$(shell uname -r)/ M=$(PWD)  modules

혹은 

 make -C /lib/modules/$(shell uname -r)/build M=$(PWD)  modules

기본 linux/xxxx.h 헤더는 /usr/src/linux-$(shell uname -r)/include 에서 찾는다.




4. 예시



아래와 같이 많이 쓴다.

CONFIG_TEST = m

obj-$(CONFIG_TEST) += test.o


test-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \

export.o caps.o snap.o 


PWD = $(shell pwd)

BASE_DIR =  $(shell dirname $(PWD))

#ccflags-y += -I/home/user/include

#KBUILD_EXTRA_SYMBOLS += /home/user/lib/Module.symvers


all:

make -C /usr/src//linux-headers-$(shell uname -r)/ M=$(PWD) ccflags-y+=-I$(BASE_DIR)/include KBUILD_EXTRA_SYMBOLS+=$(BASE_DIR)/net/Module.symvers  modules


clean:

make -C /usr/src/linux-headers-$(shell uname -r)/ M=$(PWD) clean

대충 이런식으로 많이 쓴다.

ccflags-y 나 KBUILD_EXTRA_SYMBOLS 변수 같은 경우

cflags-y += -I${BASE_DIR}/include 이런식으로 쓰면 오류가 나더라.

그래서  make cflags-y += -I${BASE_DIR}/include 이런식으로 make 명령에 직접 옵션으로 붙인다.




5. 모듈 추가


추가는 쉽다.

해당 모듈이 존재하는 디렉토리에서 

sudo insmod test.ko 라고 치면 된다. 여기서 중요한 점은 test.ko 가 libtest.ko 의 함수를 쓴다면 우선 libtest.ko 모듈을 로드한 후에 test.ko 를 로드해야한다.


insmod 는 해당 모듈이 존재하는 곳에서 로드하는 방법이고 modprobe를 사용하기 위해서는

/lib/modules/`uname -r`/kernel/ 밑에 적절한 디렉토리를 선택하거나 디렉토리를 생성하고 .ko 파일을 복사하면 된다.

복사한 후에는 modprobe 로 추가하기 전에 depmod -a 명령을 우선 수행해서 복사한 .ko 파일을 인식시켜야한다.


$ sudo depmod -a

$ sudo modprobe {module}.ko



아 그리고 test.ko 가 libtest.ko 의 함수를 사용할 때 즉 test.ko 가 libtest.ko 를 의존할때는 libtest.ko 를 우선 로드후에 test.ko를 로드해야한다.





6. 모듈 정보 보기


modinfo {모듈경로}


예를 들어

$ modinfo /lib/modules/3.11.8/kernel/fs/xfs/xfs.ko

filename:       /lib/modules/3.11.8/kernel/fs/xfs/xfs.ko
license:        GPL
description:    SGI XFS with ACLs, security attributes, realtime, large block/inode numbers, no debug enabled
author:         Silicon Graphics, Inc.
alias:          fs-xfs
srcversion:     F107BA901126B3EA796F27D
depends:        libcrc32c
intree:         Y
vermagic:       3.11.8 SMP mod_unload modversions 



7. 오류


만약 컴파일 중에 undefined 에러나, 모듈을 insmod 중에 Invalid parameters 에러가 발생한다면 현재 모듈이 다른 모듈의 함수를 사용했을 경우다. 이때는 사용하려는 해당 모듈이 컴파일 되기전에 함수에 대한 심볼 테이블이 필요하다.

만약 foo.ko 가 bar.ko 의 함수를 사용한다면 우선 bar.ko 를 컴파일 한다. 컴파일하면 해당 폴더에 Module.symvers 란 파일이 생성된다. 이 파일을 foo.ko 가 컴파일될 폴더에 복사한후 foo.ko를 컴파일하면 에러 없이 컴파일되고 에러 없이 insmod 될 것이다.
혹은 makefile 에 KBUILD_EXTRA_SYMBOLS += {Module.symvers} 를 추가한다.




글이 참.. 설명 능력좀 키워야하나..



  1. 전자둥이 2021.03.17 12:59 신고

    많은 도움이 되었습니다. 감사합니다

참고 : 

http://www.thegeekstuff.com/2013/06/compile-linux-kernel/

http://mintnlatte.tistory.com/314

http://bbanghee.wordpress.com/2010/08/05/make%EC%9D%98-j-%EC%98%B5%EC%85%98%EC%9D%80-%EC%8B%A4%EC%A0%9C%EB%A1%9C-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%98%EB%8A%94%EA%B0%80/ - make j 옵션 설명



1. 우분투 - 커널 deb 패키지 만들어 설치하기


커널을 그냥 컴파일하여 설치하는 방식이 아닌 패키지를 만들어 설치하는 방법으로 커널 패키지를 생성시키면 여러대의 우분투의 커널을 업그레이드하고 싶을 때 따로따로 컴파일 필요없이 패키지를 만들어 쉽게 설치할 수 있다.

하지만 이 방법은 컴파일에 꽤 오랜시간이 걸린다.



1.1 필요 패키지 설치

$ sudo apt-get install build-essential libncurses5-dev bin86 kernel-package




1.2 커널 소스 다운로드

$ sudo apt-get install linux-source  # 현재 설치된 버전의 커널 소스를 다운받는다.

혹은


https://www.kernel.org/ 사이트에서 원하는 커널 버전을 다운로드한다.

예를 들어

$ sudo wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.tar.xz 

받은 커널 파일은 압출을 푼다.

$ sudo tar linux-3.10.tar.xz


커널 소스는 /usr/src 에 위치시키는 것이 좋다.



1.3 컴파일 설정 파일 가져오기

모든 설정을 하기는 힘들다. 따라서 이미 설치된 커널의 설정파일을 가져다가 쓴다.

/boot 폴더에 config 로 시작하는 파일이 커널 설정 파일이며 이를 커널 소스 디렉토리에 넣는다.

$ sudo cp /boot/config-`uname -r` /usr/src/linux-3.x.x/.config


커널 소스 디렉토리에서 아래의 명령을 수행하고 load 를 선택하고 .config 를 선택하여 설정파일을 로드한다.

$ sudo make menuconfig

혹은


$ sudo make oldconfig 

oldconfig 는 현재 설치된 커널 버전의 설정 파일을 자동으로 가져온다. 위의 sudo cp 명령을 자동으로 해준다고 생각하면된다.



1.4 컴파일 설정 바꾸기

$ sudo make menuconfig 

혹은 

$ sudo vi .config

를 통해 설치할 모듈을 선택한다.

(따로 포함시킬 모듈이 없다면  설정은 굳이 바꾸지 않아도 된다.)




1.5 커널을 컴파일하고 패키지화 한다.

$ sudo make-kpkg clean

$ sudo make-kpkg --initrd kernel_image kernel_headers kernel_source modules_image


make-kpkg 시 target 리스트는 $ sudo make-kpkg --target 명령을 수행하면 리스트가 출력된다.




1.6 커널 패키지 설치

커널이 정상적으로 컴파일 되면 linux-xxxxx.deb , linux-headers-xxxxx.deb 가 생성되고 이 패키지를 설치하면 커널이 업그레이드된다.

$ sudo dpkg -i *.deb

$ sudo reboot






2. 일반적인 커널 컴파일




1.1 커널 소스 다운로드

$ sudo apt-get install linux-source  # 현재 설치된 버전의 커널 소스를 다운받는다.

혹은


https://www.kernel.org/ 사이트에서 원하는 커널 버전을 다운로드한다.

예를 들어

$ sudo wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.tar.xz 

받은 커널 파일은 압출을 푼다.

$ sudo tar linux-3.10.tar.xz


커널 소스는 /usr/src 에 위치시키는 것이 좋다.




1.2 컴파일 설정 파일 가져오기

모든 설정을 하기는 힘들다. 따라서 이미 설치된 커널의 설정파일을 가져다가 쓴다.

/boot 폴더에 config 로 시작하는 파일이 커널 설정 파일이며 이를 커널 소스 디렉토리에 넣는다.

$ sudo cp /boot/config-`uname -r` /usr/src/linux-3.x.x/.config


커널 소스 디렉토리에서 아래의 명령을 수행하고 load 를 선택하고 .config 를 선택하여 설정파일을 로드한다.

$ sudo make menuconfig

혹은


$ sudo make oldconfig 

oldconfig 는 현재 설치된 커널 버전의 설정 파일을 자동으로 가져온다. 위의 sudo cp 명령을 자동으로 해준다고 생각하면된다.



1.3 컴파일 설정 바꾸기

$ sudo make menuconfig 

혹은 

$ sudo vi .config

를 통해 설치할 모듈을 선택한다.

(따로 포함시킬 모듈이 없다면  설정은 굳이 바꾸지 않아도 된다.)



1.4 커널 컴파일 하기

$ sudo make  
#컴파일 속도를 향상시키기 위해서 sudo make -j8 옵션을 주면 된다. -j 옵션은 주어진 개수만큼 동시에 빌드를 수행한다.
자세한 정보는 위 참조를 확인하라.

$ sudo make modules

$ sudo make modules_install

$ sudo make install 

sudo make install 시 vmlinuz-x.x.x , System.map-x.x.x , initrd.img-x.x.x , config-x.x.x 파일이 /boot 에 복사되면 grub.cfg 파일이 자동으로 갱신된다. 따라서 grub.cfg 를 수동으로 수정하지 않아도 된다.

$ sudo reboot







3. 우분투 커널을 패키지로 쉽게 설치하기


# ubuntu kernel 을 패키지로 설치하는 방법도 있다.

http://kernel.ubuntu.com/~kernel-ppa/mainline/  여기가서 원하는 커널 버전을 받는다.

linux-header-..._all.deb

linux-headers-..._i386(amd64).deb

linux-image-..._i386(amd64).deb

32bit면 i386, 64bit면 amd 64 받으면 된다. 위의 3개의 패키지를 다 받아야 한다.




$ sudo dpkg -i linux-header-..._all.deb

$ sudo dpkg -i linux-headers-..._amd64.deb

$ sudo dpkg -i linux-image-..._amd64.dev



3개의 패키지를 다 설치한다. 귀찮으면 sudo dpkg -i linux* 

설치후 재부팅한다.

$ sudo reboot 



재부팅후 kernel 버전 확인 한다.

$ uname -a



시리얼 포트는 스위치 설정을 위해 사용해보았다.


우선 스위치와 컴퓨터에 시리얼 포트를 연결하고 장치관리자를 확인해보자.


포트(COM & LPT)에 보면 COM3에 시리얼 포트가 연결된것이 보인다.


그럼 해당 포트를 우클릭하고 속성부분을 클릭하고 포트설정탭에서 포트를 설정해라.


Baud rate : 9600

data bits : 8

stop bit : 1

parity none

flow control xon/xoff 

로 설정하자. 설정은 하나의 예이다. 필요에 의해서 바꾸어도 된다. 


위와 같이 설정했다면 putty와 같은 클라이언트를 이용하여 연결하면된다.

예를 들어 putty 의 경우 아래와 같이 설정하고 연결하면 된다.



연결 설정부분을 포트설정했던것과 동일하게 하면 연결될 것이다.


중요 : 설정을 하고 시리얼 연결시 아무것도 안뜰수 있다. 그때는 당황하지말고 엔터한번 눌러주면 된다. 


  1. 세봉아 2015.12.11 16:30 신고

    연결 후
    아무것도 뜨지 않는데,
    엔터 눌러도 똑같습니다.

    어떻하나요?

    • 단세포소년 2015.12.16 09:46 신고

      자세히는 모르겠으나 설정 문제일 것 같네요.

      장비의 시리얼 포트 설정 메뉴얼을 보시는게 좋을 것 같습니다.

 

만약 daum 의 ubuntu 저장소를 추가하고 싶다면

echo deb http://ftp.daum.net/ubuntu/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/daum.list

 

명령을 내려라.

 

현재 내 우분투 버전에서는 아래와 같이 입력된다.

 

deb http://ftp.daum.net/ubuntu/ raring main

 

내 우분투의 버전이 raring 이기 때문이다. lsb_release -sc 는 내 리눅스의 패키지 버전을 나타내준다.

 

위 방법은 저장소를 추가하는 방법이다. apt-get install 로 설치시 daum 사이트로 연결될지는 장담못한다.

 

 

 

저장소를 아예 바꾸고 싶다면 vi 로 /etc/apt/sources.list 를 열고

 

:%s/kr.archive.ubuntu.com/ftp.daum.net/g 명령을 통해 저장소위치를 치환해버려라.

 

혹은 sed -i 's/kr.archive.ubuntu.com/ftp.daum.net/g' /etc/apt/sources.list

sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches"

혹은 

sudo sync; echo 3 | sudo tee /proc/sys/vm/drop_caches


메모리 캐시는 테스트 하기 전에 캐싱되지 않은 실제적인 테스트 결과를 얻기위해 사용한다.

참고 :

http://sd.wareonearth.com/~phil/jumbo.html

http://windy.luru.net/565


10 기가비트 네트워크 카드, 10 기가 지원 스위치(가격이 좀 비싸다.) 가 있는 상황에서 

10 기가비트 네트워크 환경에서 제속도를 내기 위해서는 아래의 3가지 사항이 중요하다.


1. switch jumbo frame 설정
   switch의 jumbo frame(packet)을 지원하는 switch 라면 설정을 enable 시키고 만약 사이즈도 지정해야 한다면
   9014 Bytes 로 지정해라.

2. Network Interface Card MTU 설정
   nic 의 MTU 값은 기본 1500 이다. 이 값을 9000 으로 바꾸어라. 테스트 결과 1500일 경우 10Gigabit 의 절반정도의 효율만 보엿다.
   리눅스의 경우 ifconfig eth mtu 9000 입력하면 일시적으로 바뀐다.

3. 위의 2가지 사항 말고도 실제적인 속도 향상을 위해서는 장비의 메모리와 cpu 사양이 높아야한다.
   특히 패킷을 받는 장비의 경우 메모리가 낮을 경우 네트워크의 최대 속도를 장비가 따라가지 못할 수 있다.




리눅스에서 네트워크 속도 테스트의 경우 

netcat , iperf 로 확인하였다. 자세한 사용법은 구글링 하시길..

iperf 는 이론상의 네트워크 대역폭에 근접하게 뜨고 netcat 는 장비의 메모리나 cpu 등등 환경에 의한 실제적인 네트워크 대역폭이 나온다. 필자의 경우 netcat으로 테스트하고 속도가 이론상보다 낮게 나왔을때 메모리나 cpu, 네트워크 설정 등을 확인하였다.


netcat 간단 사용법

server : nc -v -v -l -n 2222 > /dev/zero
client : time dd if=/dev/zero bs=1M count={1000 or 10000} |  nc -v -v -n {server-ip} 2222


iperf 간단 사용법

server : iperf -s
client : iperf -c {server-ip}





NTP 는 시간을 동기화 하기 위해 쓰이는 프로그램이다.

기본 설정값은 공공의 time server (예를 들어 0.ubuntu.pool.ntp.org ..) 에서 시간을 받아 동기화 한다.


외부 네트워크와 단절된 보안을 요구하는 네트워크 환경에서 time server 를 두고 내부에 모든 서버가 time server의 시간으로 동기화 하는 방법을 사용할 수 있다. 이때 내부 네트워크에서만 동작되는 time server 를 local time server 라고 부른다.

설정은 아주 간단하다.



예제 정의


예를 들어 외부 네트워크와 연결이 단절된 사설 네트워크 내에서 한대의 time server가 동작하고 10대의 클라이언트가 있다고 가정하자.

Time server address : 192.168.0.1

client address : 192.168.1.1~10



NTP 설치


Ubuntu 기준으로

$ sudo apt-get install ntp


NTP 설정에 따라 서버로 동작할지 클라이언트로 동작할지 둘다로 동작할지 결정된다.



Time Server 설정


/etc/ntp.conf 설정


#server 0.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server 1.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server 2.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server 3.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server ntp.ubuntu.com # 외부 네트워크와 단절되어 있으므로 주석 처리

server 127.127.1.0  # 로컬 타임 서버로 동작하기 위한 설정 꼭 127.127.1.0 입력

restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap # client 접근 허용





Client 설정


/etc/ntp.conf 설정


#server 0.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server 1.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server 2.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server 3.ubuntu.pool.ntp.org # 외부 네트워크와 단절되어 있으므로 주석 처리

#server ntp.ubuntu.com # 외부 네트워크와 단절되어 있으므로 주석 처리

server 192.168.0.1  # 로컬 타임 서버의 주소를 입력




정리


타임 서버로 동작 시킬 장비 ntp 설정에는 server 127.127.1.0 을 추가하고 restrict 를 통해 클라이언트의 접근을 허용한다.

클라이언트로 동작 시킬 장비 ntp 설정에는 server {타임서버-주소} 를 추가하여 로컬 타임서버에게 시간을 받아 동기화 할 수 있도록 한다.

보안 문제상 만약 로컬 타임 서버만 외부 네트워크와 연결되어 있다면 server 0.ubuntu.pool.ntp.org 와 같이 공공의 타임 서버에 대한 설정값에 주석을 하지않고 공공의 타임 서버와 시간을 동기화 하고 자신의 시간을 로컬내의 클라이언트와 동기화하는 방법 또한 사용할 수 있다.




http://docs.python.org/2/tutorial/ - 공식 사이트

http://www.learnpython.org/ - 파이썬 기초 강좌(웹에서 코드 직접 실행가능)

http://www.tutorialspoint.com/python/

http://learnpythonthehardway.org/book/


EBOOK 무료(원서)

http://it-ebooks.info/go.php?id=171-1377522735-4c235745ad127629362836d41b35f6f4 - Python Pocket Reference, 4th Edition PDF

http://it-ebooks.info/go.php?id=172-1377522792-d61571b22c3628e6dba17be4ad6afef8 - Python for Unix and Linux System Administration

http://it-ebooks.info/go.php?id=1162-1377522796-b098cc69dcf375a95cba20fe55a80595 - Beginning Python

http://it-ebooks.info/go.php?id=1275-1377522799-7502b6180fbacaa54764dbe7f7d618c4 - Programming in Python 3, 2nd Edition

http://it-ebooks.info/go.php?id=373-1377522812-fd177694e5b764da0dbee80aa3b4a325 - Head First Python

http://it-ebooks.info/go.php?id=1506-1377522830-bed9611fca951ec094d52ce1213af441 - The Python Standard Library by Example

http://heather.cs.ucdavis.edu/~matloff/Python/PLN/FastLanePython.pdf - Fast Lane to Python

'학습자료(~2017) > Python' 카테고리의 다른 글

[Python] 공부하기 좋은 사이트  (0) 2013.08.26

http://sourceforge.net/projects/iperf/ - iperf 소스 배포


두 장비(연결)사이의 네트워크 속도를 측정하는 유틸로 네트워크 설정(bonding, switch)을 제대로 했는지 확인하는 수단으로 좋다. 

하나의 장비를 서버, 하나의 장비를 클라이언트로 실행하여 두 연결 사이의 속도를 측정하는 방법을 사용한다.

사용법 또한 매우 간단하다.

이것 찾게된 이유는 switch 10G 환경에서 장비 bonding 시 실제로 속도가 예상치만큼 나오는지 설정이 잘 되었는지 확인해보고 싶었다.


설치


$ sudo apt-get install iperf



실행


서버


$ iperf -s

------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 192.168.3.23 port 5001 connected with 192.168.3.20 port 38194
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0-10.1 sec   113 MBytes  94.1 Mbits/sec




클라이언트


$ iperf -c {server-ip}

TCP window size: 22.9 KByte (default)

------------------------------------------------------------
[  3] local 192.168.3.20 port 38194 connected with 192.168.3.23 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   113 MBytes  94.7 Mbits/sec



기타 옵션


-s 서버 모드

-c <server ip or domain> 클라이언트 모드

-u UDP 사용 (기본 TCP)

-p port (기본포트는 5001)

-w TCP Window 크기(socket buffer 사이즈)(ex -w 10M, -w 10K)

-t 측정시간(초)


sudo 를 사용하는 환경에서 원격지에 파일 보내기



파일을 보낼때 우리는 흔히 scp 를 이용한다. 이때 sudo 환경이라면 아래와 같이 실행할 것이다.

 $ sudo scp {sourcefile} {hostname}:/targetfile

위의 명령어의 경우 ubuntu와 같이 {hostname}의 장비가 root 를 사용하지 못하고 sudo 를 통해 권한을 이양받아 실행하는 환경이고 targetfile root 소유라면 이 명령어는 실패한다. (물론 targetfile 에 쓰기권한이 있다면 scp 써도 문제 없다.)

sudo scp {sourcefile} root:{hostname}:/targetfile 이렇게 실행하면 안되냐는 말이 있을것이다. ubuntu 의 경우 정책상 root의 비밀번호가 없다. 즉 root로 로그인이 불가능하다.(물론 sudo passwd 명령어도 root 패스워드 만들어주면 되지만 sudo를 쓰는 이유가 훼손된다.)


이때는 아래와 같이 하자.

 $ ssh {hostname} "echo '`cat {sourcefile}`' | sudo tee {targetfile}"


tee 명령어를 사용한 이유는 리다이렉션은 쉘내장명령어라 sudo의 영향을 받지 않기 때문이다.

위의 명령어도 하나의 문제가 발생한다. ssh 를 통해 단일 명령어 실행시 sudo 와 같이 입력이 발생하는 경우 no tty ~~~~ 에러가 발생한다. 

이때는 패스워드 없이 sudo 사용하기 라고 구글링하거나 http://onecellboy.tistory.com/292 이 링크를 참고해라. sudo 실행시 패스워드를 묻지 않게 하는 방법이다.


간단하게 예를 들어 sourcefile의 내용이 "hello linux" 라면
ssh {hostname} "echo '`cat {sourcefile}`' | sudo tee {targetfile}" 는
ssh {hostname} "echo 'hello linux' | sudo tee {targetfile}" 로 바뀌어 명령이 호출된다.


내가 위의 내용들을 정리해본 이유는 ubuntu 에서 미리 시스템 설정파일을 만들고 원격지에 /etc/network/interface와 같이 시스템설정 파일을 대체하려고 했는데 시스템설장 파일이 root 소유라 scp 로는 되지 않아서이다.


참고로 ssh {hostname} "echo '`cat {sourcefile}`' | sudo tee {targetfile}" 명령어는 백쿼트(backquote) 와 명령어 중첩, 리다이렉션 대신 tee를 활용한 명령이다.

구글링으로 "backquote shell script", "쉘 백쿼트" , "명령어 중첩", "tee" 를 검색하여 위 명령어를 확실히 이해하는 것도 좋다.





방법이 하나 더 있다.

그냥 원격지 장비의 /tmp 에 파일을 scp 한후 mv 명령으로 옮기는 것이다. (/tmp 디렉토리는 누구나 쓸수 있다.)

 $ scp {sourcefile} {hostname}:/tmp/

 $ ssh {hostname} "sudo mv /tmp/{sourcefile} {targetfilepath}" 


예를 들어

내 장비의 testfile 을 원격지(1.1.1.1) 장비의 /etc/target 으로 보내고 싶다.

scp testfile 1.1.1.1:/tmp

ssh 1.1.1.1 "sudo mv /tmp/testfile /etc/target"  이런식으로 하면된다.


+ Recent posts